Archive for 九月, 2013

先收集:

http://www.cnblogs.com/panfeng412/archive/2011/10/28/realtime-computing-of-big-data.html

总论

Visual Guide to NoSQL Systems

CAP理论CAP理论淘宝工程师的实际理解

ACID理论

Systemic Requirements

【分布式系统工程实现】系统可扩展性演化  淘宝分布式想法,由于bigtable/PNUTS/Dynamo等虽然扩展性、容灾和数据容量都很优秀,但前期投入成本过大,所以他们考虑采用折中方案。“比如我们可以将动态更新操作存放到单机内存中,静态数据存放到多台机器的磁盘中,定期将静态数据和动态数据合并,读取操作同时读取静态数据和动态数据部分,由于动态数据存放在内存中,这样的系统设计对于大多数应用性能不成问题,且极大地减低了系统整体复杂性。更为重要的是,只要我们理解了分布式系统可扩展性设计的关键点,提前制定好系统发展路线图,经过一段时间积累后一定能够设计和开发出可扩展的分布式系统。”

mongodb

document based db,存储类json格式的数据。动态数据结构,支持较为丰富的类sql查询,支持多种索引,读写性能相对较高。支持大数据量的分布式存储,其HA是由分片、replication保证的,而非单机本地的持久化。

官网。从手册上可以看到:

  • 不需要提前建DB、表,当插入json对象时,mongod自动建立对应的Db和collection。
  • 它支持顺序读取、较为复杂的查找,但不支持join。
  • 为了提高查询速度,可以在任意一个或多个filed上建立索引,且有多种索引类型可选;不同的索引类型,对写性能、查找性能有不同的影响。
  • mongodb内置支持sharded query,对于含有shard key的查询,route server mongos进程会将请求多播给匹配该shard key的data servers,并merge查询结果;而不含shard key的查询,会导致广播,对于大集群,可能会有性能问题。
  • mongodb也可被配置为replica的即primary和secondary,并且能通过mongodb client的配置指定读primary、primary优先、secondary、secondary优先、nearest几种模式,不过需要注意的是,读secondary库可能有延时,从而仅能实现最终一致性。以PHP driver为例,是通过application driver与primary and/or secondaries server交互而决定谁是primary、谁是secondary的。
  • 对于写操作,也有不同等级的设置,由若到强有Errors Ignored(忽略所有错误,包括网络、写操作,立刻返回)、Unacknowledged(捕获网络错误,忽略其他所有错误)、Acknowledged(捕获错误,保证写入mongodb内存区域)、Journaled(捕获错误,保证写入持久化日志)、Replica Acknowledged(捕获错误,保证replica同步完成)。sharded cluster的写操作,仍然由 mongos route server来分发;replica模式下,主从间通过oplog同步,当批量写入大批数据时,可能导致主从不同步,这时可适当指定Replica Acknowledged,使secondary可以 catch up with primary。
  • 写性能受到索引、document growth、磁盘写、写日志性能的影响。其中update写操作,如果引起document growth,可能耗时较久;而类似$inc之类的操作,由于是in-place操作,一般较快;为了尽可能减少growth,数据结构的设计尤关重要。
  • 超过16MB的大文件,可利用gridFS

问题:

1. shard cluster增加data server的成本?

2. shard cluster中,是否存在单点问题?

3. shard cluster对于顺序读取全表数据的影响?

4. replica模式下,影响主从同步的因素是?一般延时多大?

5. 索引数据结构,存储数据结构如何?

6. $isolated和两阶段提交怎样应用于mongodb的多collection/多行更改, 未能完全理解

7. replica架构时,故障时的选举过程,会不会导致震荡?由client driver来决定主从,会不会有性能问题?有没有别的解决方案?

MongoDB最佳实践  在部署mongodb方面的建议。

盛大研究院对mongodb的调研和简单比较

mongodb速查卡:总结了常用的命令和配置,很好。

应用场景:

cassandra

最终一致性的kv存储。Apache Cassandra是一套开源分布式NoSQL数据库系统。它最初由Facebook开发,用于储存收件箱等简单格式数据,集Google BigTable的数据模型与Amazon Dynamo的完全分布式的架构于一身。Facebook于2008将 Cassandra 开源,此后,由于Cassandra良好的可扩放性,被DiggTwitter等知名Web 2.0网站所采纳,成为了一种流行的分布式结构化数据存储方案。

是基于google bigtable data model的,是Column-oriented存储。

Cassandra的系统架构与Dynamo一脉相承,是基于O(1)DHT的完全P2P架构,与传统的基于分片的数据库集群相比,Cassandra可以几乎无缝地加入或删除节点,非常适于对于节点规模变化比较快的应用场景。(P2P即无中心节点,可能会有数据一致性问题,且由于数据是hash的,顺序扫描的性能可能不高。)

Cassandra的数据会写入多个节点,来保证数据的可靠性,在一致性、可用性和网络分区耐受能力(CAP)的折衷问题上,Cassandra比较灵活,用户在读取时可以指定要求所有副本一致(高一致性)、读到一个副本即可(高可用性)或是通过选举来确认多数副本一致即可(折衷)。这样,Cassandra可以适用于有节点、网络失效,以及多数据中心的场景。

redis

基于内存的kv存储。感觉还是在“小”数据量的高性能读写应用上。提供持久化,也可以从mysql的binlog等同步数据。

应用场景:Redis作者谈Redis应用场景

应用实例:twitter的timelineinstragram的feed/session等服务(redis作为集群式cache,估计是利用其log持久化到disk,并导入DB),github(感觉业务比较简单,redis应该还是用于cache热点数据)、stackoverflow(大量redis的应用)、flickr实时消息推送系统(使用redis作为队列)、digg计数器

Berkerly DB

MemcacheDB

hdfs

hive

Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供完整的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。但不支持单行的增删改。读时模式,即写时不建立索引,其延迟是分钟级。

http://wiki.babel.baidu.com/twiki/bin/view/Com/Test/Hive%E5%85%A5%E9%97%A8

hbase

分布式表结构,是基于google bigtable论文的开源实现。适用于存储海量稀疏数据,java API性能最高,也可以通过thrift协议提供其他语言的API。底层存储基于HDFS。

 hbase在淘宝的应用和优化小结 

Facebook为何选择了Hadoop和HBase

GFS&Bigtable设计的优势

云计算之分布式表格系统  淘宝DBA的文章

google bigtable论文

内网资源:

http://wiki.babel.baidu.com/twiki/bin/view/Main/HBase%E6%B5%85%E8%B0%88

http://docs.babel.baidu.com/doc/e0fcda83-ca32-4e4a-bccc-0f0d89ad1b0f

OceanBase

已开源,官网

OceanBase介绍 淘宝自己开发的大数据分布式存储,支持高一致性和高可用性。思路是将新的增删改操作记录在update server的内存表里,一般主备并写commit log,并限制内存表的大小,超过之后冻结该表,写新表。而旧数据以sstable的形式存储在chunk server的SSD/磁盘上,主键顺序排列,多备份。chunk server在主机空闲时,会将冻结的内存表合并到chunk server里。在查询时,会从update server和chunk server读取并合并数据。在写事务时,操作的是update server,所以事务响应较快。

由于增删改数据存储在update server的内存里,其估算的是若一条操作占用100B,则10G可存储1亿条,且通过冻结/合并操作,能够将内存flush至硬盘。但考虑到update server和其中控机都是单点或主从互备,若是过于频繁或吞吐量极大的写操作,可能也不适合。

其chunk server的数据结构见博文。采用类似bigtable的结构B+树维护主键索引,叶子节点包含前开后闭的数据。数据被划分为8~64KB的block,叶子节点对block建立块索引;并且针对block有多种块压缩算法可配置;叶子节点作为独立单位,可以有多个copy。当block被读取时,其所在叶子节点的块索引被load进缓存,下次使用可避免磁盘查找;而长期不被访问的叶子节点,会被从缓存中flush掉。另外,近期访问过的block也会被cache住(猜测可能直接用是的操作系统的cache)。

读操作涉及update server和chunk server。而两者的数据合并,是否由root server还是application自己进行?若是前者,其计算压力是否大?若是后者,复杂度如何?

Mysql存储大数据/海量数据的瓶颈

mysql单机200GB的数据性能较好

 

存储介质选型

当前各种存储介质的功能、性能差异都较大,不像关系数据库时代,虽然mysql、oracal等实际是求同存异。如HBase一书作者所言,各存储介质一般都先指明自己无法支持的功能。所以,更要求我们先了解并预估一段时间内,数据存储的需求,从几个维度来选择合适的介质。

维度的把握有以下几种:

  • 数据量
  • 事务/一致性要求
  • 分区容忍度
  • 数据读取:顺序/随机
  • 读写比和性能要求(存储模型、数据模型)
  • 批量读写支持和性能
  • 查询复杂度(数据模型、是否支持二级索引)
  • 改变表结构/索引成本
  • 与其他存储介质的同步成本
  • 分布式的支持程度
  • 水平扩展成本
  • 容灾能力

别人的性能测试报告

A vendor-independent comparison of NoSQL databases: Cassandra, HBase, MongoDB, Riak

2013-09-11

1.1 敏捷联盟

敏捷这个词被滥用了很久,部分人认为站会、自动部署、没计划、没文档就是敏捷了。其实这都是片面且偏激的看法。从敏捷宣言的解读就可以看出,在强调个体能力和沟通的同时,它也不忽视工具。而在强调代码的同时,也不忽视文档,只是不要求“面面俱到”的文档,而是维护系统原理和架构文档,细节留给代码。而响应变化胜过遵循计划方面,我理解,在互联网行业里,从RD的角度来看,由于来自PM或用户的需求是多变的,所以无法生造出一个长远(横跨几个月)且不变的计划;但从PM或项目经理的角度,得有谱,得规划出产品的长远意义和走向,否则项目将失去灵魂。

1.2  原则

对于我们来说,与其规划一个耗时数月的产品,不如拆分为小功能,花上一两周作出第一版(需要有核心的产品价值和可快速迭代的架构),快速上线(不要局限于一个入口,尤其是需要有我们完全可控的入口),然后收集用户反馈、分析用户行为,持续升级和推广。这里不局限于一个入口,是有感于之前创业阶段,把宝都压在淘宝APP上,完全受制于对方的政策。可快速迭代的架构,我理解必须是内聚和解耦且拥有全面自动化回归case的,这样才可以放心的对某一些子功能动手术。所以,这里强调的是迭代规划、架构、人、数据监控与分析、推广

敏捷中人的作用尤其重要!对程序员的要求有:

  • 视软件如己出,为自己做事,且相信产品会为用户、世界带来极大的价值(后者可能对于我这样的人比较有意义)。只有这样,才有持续的动力 提高自己的技能、避免坏味并写出高质量的代码、主动发现有问题的点并修复它、自驱动领取力所能及的task等等。
  • 言出必行,由于强调的是面对面的交谈,文档、邮件仅作为备忘录记录大事件,所以对于细节更多是通过人的自律来保证的(在敏捷初始,可能还是需要通过细致的TODO list来保证吧?在涉及团队间交互时,接口文档还是必不可少的。)其实,个人觉得,这是不分行业的,是基本的要求,就是按时按质完成工作。

进度的评估,以可用功能完成进度为准,不包含调研、设计、文档、基础lib库的进展。因为后者都太虚无,PM或用户看不到真正的效果,也无法准确的验收进度。这也从另一方面,强迫敏捷开发团队将需求拆分为可独立上线的子功能,否则进度一直都是0%!

最后,每隔一段时间,敏捷团队需要坐下来回顾实施过程中的经验和困难,并作出调整。这一方面是积累,另一方面也可以看出敏捷的原则不是定死的,而是可以根据团队的情况,灵活应用。

 

2013-9-12

2.1.3 短交付周期

极限编程里有“发布计划”、“迭代计划”两个概念。前者是多个完整的story,进行一次发布或上线,持续3个月。后者虽然也由一个或多个story组成,但仅完成开发、测试并持续集成至版本仓库,不发布,持续2周。这种发布的频率可能是产生自传统软件行业,以通信行业为例,一个完整的系统交付可能持续数年甚至更长,每3个月做一个版本升级已经很快。但个人感觉虽然频率并不适合互联网,但思想仍可以借鉴。

3个月的发布计划,会迫使需求提出者作出较为长远的规划,避免需求无目的的堆积。而将多个有组织的需求,再拆分为较小的开发周期,并在此周期内保持需求的稳定,可以使开发者不至于因为需求的频繁变动而乱了节奏。但只要需求未被纳入开发迭代,提出者就可以对需求进行调整,也保持了快速应变的能力。

应用到互联网行业,我们是否仍然是做3个月的规划,2个周的迭代。改变的是迭代结束就上线,将效果交给最终的用户去评判,并加入监控和分析,对于影响较大的紧急反馈在RB分支里在几天内立刻修复并上线,而其他反馈并入随后的迭代里。

2.1.12 简单的设计、2.1.13 重构

简单的设计、不提前设计,这个在现实中如何平衡?而这两点,其实也是基于“重构”来的。简单的设计,在面对新需求,需要变更代码、lib库甚至架构时,如何处之?答案是有全面自动化case保证的重构和高质量的工程师!但现实中,100%全面的case是不存在的,人的方面更是变化多端。所以,个人觉得,需要折中。

  • 欢迎重构,但尽量把重构放在本迭代中,不把坏味代码留到发布版本里,减少后面为了消除代码坏味而进行的重构。
  • 通过数据推测性能需求,通过对需求提出者的诘问推测功能需求,为可预测的将来做准备。
  • 在需要对已有功能做重构时,化整为零,每重构完一个小功能就build,确保无误;并且尽量采取小流量的方式先试点再推广。

2.1.14 隐喻

TODO