技术领域—海量存储计算
PB 时代的来临
Petabyte ,2 的50 次方个字节。这个对很多人还是很陌生的计量单位,已经变得越来越普遍和触手可及。2004 年8 月,GOOGLE 日常任务输入的数据已经达到了3PB ;2005 年Mark Hurd 从Teradata 来到HP 出任CEO ,开始建设基于Neo View 的8PB 的HP EDW 。2006 年,YAHOO 构建了世界上第一个基于ORACLE RAC 的PB 级别数据中心。2007 年9 月,GOOGLE 的日常任务的输入数量膨胀到403 个PB ,而输出文件的尺寸也达到了14PB 。2008 年6 月,wired 杂志刊登标题为The Petabyte Age 的文章,不仅是互联网行业,越来越多的传统行业公司的数据中心也开始达到PB 的数据量级。时至今日,最近看到的一个新闻是一家名为Zynga 的社会游戏公司在2010 年的 Oracle Open World 上宣布,他们每天的数据净增量达到了1 个PB ,每个礼拜需要新增1000 台服务器存储这些数据。
再来看看我们自己公司内部的情况,基于hadoop 的云梯一群集已经达到了1400 台服务器的规模,淘宝数据仓库的数据量已经达到了1PB (实际存储3PB );B2B 的数据仓库的数据量也已经达到了320TB ,预计2011 年底必然会达到1PB 。越来越多的用户和业务数据被记录在案,10 亿条记录,只能存放B2B 中文站2 天的页面曝光访问(CTR) 记录。在这样一个数据不断膨胀的时代中,数据已经如洪水般汹涌泛滥。数据查找和调用困难,一些用户提出申请之后往往要等到第二天才能得知结果,直接影响到了用户满意度的提升和新业务的布局。在技术上,我们需要一个怎样的技术基础架构,才能够满足数据量的不断膨胀下的计算和存储需求。而当我们解决了最基础的数据量和计算能力这个温饱问题后,开始把目光移向数据服务、数据价值的时候 ,我们又需要怎样的技术基础架构,能够将如此海量的数据提供对外的服务 ,将我们对数据的认识直接转换为数据的产品并为我们的最终客户带来真正的价值?
THE NOSQL MOVEMENT
在谈论我们的技术基础架构前,我还想先花点时间谈谈最近非常热的NOSQL 。对于大多数开发人员而言,NOSQL 更多时候意味着Say NO to SQL ,或者Non-Schematic 。传统的关系数据库模型和应用代码对象模型通常是以不同方式建立起来的,这导致开发人员需要将代码映射到关系模型去克服这种不兼容性。这个过程被称为对象/ 关系映射。而基于K/V 的方式天生是基于对象的,相比基于关系模型和Schema 的RDBMS 更为简洁(对象/ 关系 VS 序列化/ 反序列化);底层代码中的对象类的映射关系比对象/ 关系映射要直接得多。这种简洁的开发模式对于很多相对明确简单的业务场景,很大程度上提高了开发人员的效率,显著减少了开发时间。
对于很多系统架构师而言,在数据量如此膨胀的今天,一个必须要考虑的特性是系统的可伸缩性(Scalability ) ,这个特性正变的越来越重要,以至于在重要性程度方面已经开始凌驾,甚至侵蚀其他系统特性。RDBMS 经过20 多年的历史,数据一体化管理和分析已经发展的非常成熟了。RDBMS 为数据库用户提供了简单、健壮、灵活以及兼容性的组合,但它在其中每个领域里的性能,不一定就优于其他追求某一项好处的独立替代方案 [1] 。在系统的可伸缩性上,RDBMS 传统的方案是向上扩展( Scale Up ),但通常只能单台服务器节点上进行(或者是在单组存储上水平扩展)。 Scale Up 的方案操作简单, 但是规模有限, 代价越来越大。即便抛开Scale Up 的价格和规模问题,对可伸缩性的需求,可能会变化得非常迅速和庞大。如果你的系统负载一夜之间翻倍,你能在多少时间内完成硬件升级?这一特点使得RDBMS 在大型应用场景被大幅限制,唯一的可选方案是 Scale Out, 通过增加多个逻辑单元的资源, 并使它们如同一个集中的资源那样提供服务来实现系统的扩展性。Sharding 是一种scale out 的扩展方法,但目前还没有非常成功的Sharding 框架,关系数据库的复杂性开始影响Scale Out 所能达到的潜在的扩展规模。当试图扩展到成百上千个节点(而不是几个)的时候将导致系统的复杂性不堪重负。
如同google 倡导的那样,The Data center as a Computer 。对于一个从来没有见过PB 的数据量,上千台机器的新人工程师,系统的扩展性要求能让他像在单机上一样开发。在这种情况下,基于分布式、具有扩展性的键值存储处理模式逐渐出现,为此甚至会而牺牲掉关系数据库所带来的其他好处。使用大量且相对廉价的机器作为存储与计算结点以解决海量数据环境下的昂贵的硬件成本问题;采用键/ 值对(key/value pair 的泛型结构) 存储,系统提供基本get(key),put(key, value),delete(key) 等数据访问接口;所有的数据都被看做是键/ 值对,这使得整个系统模型非常简单 ,大多数系统采用 “一致性哈希”(Consistent Hashing )来实现数据(键/ 值对)的群集分布、快速定位查找以及动态扩展时减少需要重新分布的虚拟节点的数目。数据在结点上存在分割与冗余,保证高可用性及性能;同时牺牲部分的数据一致性要求实现数据的高可用性和分区容错性。根据 CAP theorem ,数据的一致性、高可用性和数据分布三个方面是相互制约的,不可能同时达到最好。
万能的钥匙?
键/ 值对是面向于对象的,所有该对象的数据都能随时被被存储进该项目中。这个模型允许一个单一的项目包含完所有相关数据,以此消除对多表的数据连接的需求来扩充能满足的业务场景 。而在关系数据库中,数据需要被联接到一起,以便能重组为相关属性。对于数据的整合,这样一个稀疏存储(sparse storage) 的数据模型是相当合适的,我们可以把来自不同业务系统的数据,根据统一个对象实体的KEY 值放置入同一个数据域中 。 比如Member 的信息,我们可以把来自网站的,CRM 的,P4P 的不同的源系统的Member 信息按照同一个Key 值整合到同一个对象实体中,利用Non-Schematic 的特性实现用户属性的任意增删,从而构造一张超级的大宽表,整合了该用户的所有属性。
虽然在关系数据库中的需求在键/ 值数据库已大为减少,但是有些东西(关系联接)还是不可避免。那些关系一般存在于核心实体之间。比如说,用户的产品(Product/Offer )、订单(Order )、反馈(Feedback )和用户信息表(Member) 之间的关系。一个用户会拥有多个产品,订单,反馈。在描述一个用户所拥有的产品,订单和反馈的时候,是没有无法将所有这些产品,订单,反馈的属性信息都写入到用户的属性表中(虽然在技术上可以用多个嵌套表或者Super Column Family 来实现),在这个时候,两个实体对象之间的Join 不可避免。
当我们在一个键/ 值对的平台上积累汇总并整合来自各个业务系统的用户数据,而且通过键/ 值对的方式,你已经可以对外提供基于某个KEY (比如某个用户)的海量并发访问,同时获得极强的系统可伸缩性。现在你想为客户创造新价值,或者还想利用这些数据产生新的收入。你就会发现自己被严重限制了,甚至连直接的分析型查询都很困难。在键/ 值对存储的平台上,类似追踪(用户的)使用模式、基于用户历史提供建议等事情,即便不是不可能也是非常困难的。当需要进行数据的范围查找,多个搜索条件的合并这些情况下,这些应用对于RDBMS 来说并不是太大的问题的问题,但是因为NoSQL DB “分布式框架”本身的特性,使得键/ 值对平台中并不能很好支持范围检索(包括非等值比较),集合和针对集合的多个布尔表达式(Union/And/Or …)等等操作。虽然有一些技术手段( 比如分布式二级B 树索引,前置哈希索引,全文倒排索引) 可以部分解决这些查询问题,你会发现必须在系统中引入了越来越多复杂的机制来实现这些功能,实现的成本是巨大的,并导致整个系统的复杂度因此大大增加。结果,你将不得不从键/ 值数据库中分离出来的,建立一个独立的分析型数据库,以便执行那样的分析。你该在哪里才能做这样的事情?又该如何去做?归根结底,虽然规模和可伸缩性是一项重要考虑因素,但不要把它排在使用数据,将数据转换成为资产的能力的前面 。如果你的系统中沉淀的数据无法给用户带来真正的价值,这世上的一切伸缩性都将一无是处 [1] 。
接下来就公司目前使用的几种不同类型的系统谈谈个人看法:
基于键/ 值的分布式存储
分布式键/ 值存储目前在B2B 使用的比较广泛的Cassandra ,包括国际站,CRM,DW 目前都在使用。Cassandra 它在设计上整合了Google Big table 和Amazon 的 Dynamo 优点的系统,在系统的设计上有很多的可取之处。 一方面继承了Dynamo 在 集群方面的技术,另一方面又借鉴了Bigtable 的 数据模型,这使得Cassandra 区别于Dynamo 单纯的key/value 结构,具有更丰富的数据表现形式。Cassandra 系统架构中一个闪亮的发光点是全对称设计,没有master 节点的单点故障(相对而言,hadoop 的hdfs 的name node 的单故障点目前还没有一个太好的解决方案)。Cassandra 采用 Gossip 协议主要用来管理集群会员信息,通讯效率非常高, 只需要Log(N) 回合就可以将状态传递给集群的N 个节点,每隔T 秒, 每个节点都会自增自己的Heartbeat 信息并通过Gossip 传递给其他节点。
另一个显著的优点是,虽然Cassandra 被设计为一个AP 的系统,但是Cassandra 允许你根据实际的需要来满足不同的系统特性。如果系统要求必须100% 的读取到之前写入的内容,可以将 Consistency Level 设置为ALL 要求所有节点都有数据的一致的副本,这时候系统不具有对任何节点失效和分区容错性。而如果为了获取最佳的性能,将 Consistency Level 设置为ONE 的情况下,从任意一个保存有这个副本的节点获取数据就可以(此时系统拥有了非常高的可用性和分区容错性)。而 Consistency Level 设置为QUORUM ,则意味着大部分存放该数据的节点上的副本是一致的,这是一个折衷的设计,系统提供了合理的节点失效与网络分裂的耐受性的同时也提供了很高的一致性。C,A,P 在Cassandra 中可以按需设置。
虽然Cassandra 拥有了如此多的优点,它的缺点同样也同样显著。因为其底层存储设计的特性,Cassandra 则更适合于实时事务处理和提供交互型数据,而不适合于数据仓库、大型数据的处理和分析,这点从开发人员的背景上也能看出端倪。对 于cassandra 的性能描述,江湖传言多有误会的地方, 据Facebook 的工程师Avinash Lakshman 介绍,Cassandra 仅用0.12 毫秒就可以写入50GB 的数据,比MySQL 快了超过2500 倍。 这应该是个谬误。
找来Avinash Lakshman 的PPT 对照:
MySQL > 50 GB Data ;Writes Average : ~300 ms;Reads Average : ~350 ms;
Cassandra > 50 GB Data;Writes Average : 0.12 ms;Reads Average : 15 ms;
这里的0.12 毫秒的写入速度应该是50GB 的数据库尺寸下单个KV 的写入速度,而不是系统写完50GB 的时间。如果真要在0.12 毫秒内写完50GB ,意味着这个系统每秒能写入50/0.12*1000G=416TB 。在实际的测试中,每次读取Cassandra 至少要将本地数据节点内该KEY 的所有数据都读取出来,MERGE 最新的Timestamp 的VALUE 后返回结果,系统的读取性能表现的较为糟糕。
8 月13 号发布的Cassandra 0.7 beta1 版本,有很多很吸引人的特性,在读取的性能上,做了很大的改进。
包括:
Ø 开始重点使用RowCache ,将其读取性能提升了8X 。
Ø 支持secondary index ,目前的实现机制就是用反转的方式,支持联合索引。
Ø 支持hadoop 格式的输出,可以使得数据仓库更容易从Cassandra 中抽取数据。
Ø 无索引的筛选过滤查询仍然不支持,需要再通过hadoop 的M/R 实现。
基于文档的分布式数据库
我们目前在使用Mongo DB 在构建一个基于客户的实时分析的系统。Mongo DB 的名字来自humongo us 这个单词的中间部分,从名字可见其野心所在就是海量数据的处理。跟CouchDB 一样,Mongo 是一个面向文档的JSON 数据库,被设计为一个真正的对象数据库,而不是一个纯粹的键/ 值存储。Mongodb 的内存映射文件机制以及schema-free 的特点,让我们可以保持高速添加数据,不用担心数据库会出现堵塞。另外 ,MongoDB 支持非常丰富的查询功能。几乎常用的SQL 功能在它里面都有相应的方法来实现。而且支持索引,能够根据某一列进行WHERE 条件快速筛选。MongoDB 适合用来描述一个具有个性化特征的实体对象正,快速无阻塞的数据数据并行写入功能以及丰富的查询功能 是MongoDB 的亮点,对于实时分析、logging 、全文搜索这样的场景是合适的选择。
MongoDB 其中一个问题是占用空间过于虚高,原来1G 的flatfile 它需要4 倍的磁盘空间存储。另一方面mongodb 的sharding 到现在为止仍不太成熟。Mongo DB 没有像其他一些NOSQL 产品那样选择一致性哈希来进行数据分片。它使用的是一种RANGE-BASED 机制来进行数据的分片,在使用sharding 功能的时候会让你指定一个COLUMN 作为SHARD KEY 。 我们尝试通过一致性哈希算法来自己做DB 之间的切片,把数据人工分到不同的机器上。采用自己实现的分片机制,性能相对使用Mongo DB 自带的sharding ,性能更稳定,且更新速度一直保持在一个比较快的水平。 当然,自己来实现数据分片,很多功能都需要自己手工来实现。比如说where 条件的筛选,需要在每台机器上都执行一遍,然后再对各个结果集进行一个合并。GROUP BY 也一样,先在每台机器上GROUP BY 一下,然后还要再来一次。而使用MongoDB 自带的sharding 功能的时候,你只需要发一条命令给它,它会自动进行处理,直接返回最终的结果给你。
基于分布式文件的数据库
hadoop/Hbase/Hive/PIG 是我们目前更为使用广泛的一项技术,在全球范围hadoop 也受到越来越多的关注,Shelton 在他的presentation 中很自豪的说hadoop 是海量数据处理的趋势和未来。2010 年参加hadoop 峰会达到了1000 人(门票在开幕10 天前就卖光了),包括James Gosling 也参加了这次峰会。Yahoo 和facebook 在hadoop 上实现的应用令人印象极其深刻 。Irving 声称 “我们相信Hadoop 已经为主流企业的应用做好了准备”。
看看Yahoo 们用hadoop 都在做些什么,他们使用hadoop 个性化他们的主页:[4]
Ø 实时服务系统使用Apache 从数据库中读取从user 到interest 的映射
Ø 每隔5 分钟,他们使用生产环境中的Hadoop 集群基于最新数据重新排列内容,并每7 分钟更新结果
Ø 每个星期,他们在Hadoop 科研集群上重新计算他们关于类别的机器学习模式
Facebook 透露了更多使用hadoop 的技术细节,他们展示了Hive 与Hbase 和RCFile 的集成。Facebook 正在尝试将HBase 用于数据仓库里对于维度属性的持续更新。他们将Hive 集成到20 个节点的HBase 集群——从Hive 向HBase 载入6TB gzip 压缩的数据块用了30 个小时,在这种配置下可以达到30GB/ 每小时的增加载入速率。在HBase 运行表扫描比执行原生的Hive 查询要慢五倍(使用了RCFile ,Hive 中一种新的存储格式,将数据按列式存储。采用这种格式,平均减少了20% 的存储需求,同时可以达到更好的性能)[3]
Facebook 使用hadoop 一个成功的经验是:95% 的Facebook 任务由Hive 写成,通常可以在HIVE 中可以用类SQL 语言在十分钟内完成一个任务(Schroepfer 特别给了一个hadoop job 和HIVE job 的对比页面)。Facebook 提供一个称之为为HiPai 的Web 工具让业务分析师使用Hive ,只需要简单的撰写查询语句,支持查询载入仓库的近20000 个表。say NO to SQL ? NOWAY! 对于绝大多的数据的分析任务而言,SQL 是一种非常简单、易懂、结构化且高效的语言,学习和使用成本都很低,能极大的降低使用者的门槛,将数据开放给更多的非技术的业务分析人员使用,从业务的角度理解并消费数据。对于数据分析人员而言,SQL 是一个最简单犀利的武器,远没有到对SQL 说NO 的时候。
另一个重要的变化是:虽然在最开始被设计为批量任务处理(包括HDFS 也是一个只允许一次写入的文件系统),Hadoop 一直被看做不适合于实时的数据分析,数据的实时更新一直是困扰hadoop 的一个问题。从06 年的研究到07 年的科学影响分析再到08 年日常生产任务,当前yahoo 已经做到了每个页面点击背后都有hadoop 。facebook 通过将Hbase ,Hive 等各个模块之间的协作整合,一步一步从每天的批处理过渡到实时的查询—— 预见将会出现最快查询在一分钟内就可以返回的系统,这必将为一系列新兴的应用开启大门 。
必须看到,hadoop 还不是一个完善的系统,包括这次峰会中 Irving 也提到的,当hadoop 的集群扩张到一定程度的时候,资源的调度机制在大量不同优先级的任务之间的调度就会显的开始有些捉襟见肘(一般的认为2000 节点是hadoop 的一个门槛,yahoo 已经构建了一个4000 节点的群集)。去年yahoo 在map reduce 上改善的重点是在混合压力的情况下,保证工作工作负载的健壮性,构造新的调度容量程序,通过安全围栏( safety rails )来保证资源使用限制。
另一个问题还是老调重弹的非全对称式的设计。为了减轻HDFS 的Name Node 的单点故障问题他们都将数据复制到多个群集,分布式文件系统的中断可以使用备份文件系统来弥补和解决name node 出现的故障。同时,为了保证应用的之间的解耦,无论是yahoo 还是facebook ,都将他们的hadoop 群集根据应用分解成多个群集。
到这里已经啰嗦了大约6000 字谈论了很多的背景和现状,外面世界和公司内部的情况。 数据中心将成为整个企业数据化运营中一个环节,如yahoo 号称的那样,data center behind every click ;数据中心为各个业务系统以及企业的外部用户提供分析整合后的数据,通过对数据的整合和汇总计算,发现数据的规律与价值并通过数据服务提供给最终用户,可以预见数据中心会越来越多的面临来自以下两个方面的需求和挑战:
Ø 随着对外提供数据服务的增加,数据中心将会成为整个企业服务流程中的一个环节,对数据分析的结果需要直接的对外提供服务 。这要求数据中心的系统平台能够对于广告信息投放, 用户兴趣预测,推荐引擎这样的业务都能够有更快的刷新计算频率(1 分钟刷新),计算完成的结果能近乎实时的被前台应用服务所直接访问、应用; 数据中心提供的数据服务要求是基于事件触发(Event Driving Architecture )更为灵活主动的架构,并直接面对网站用户,要求7*24 的系统可用性以及每日亿万级别PV 的并发访问需求;
Ø 提供数据服务的客户越来越多,常规的数据报表的开发需要更为简单直观,对报表组件工具需要组件化,做客户化定制封装;客户消费数据的能力也越来越强,我们需要一个更为开放的平台 ,让更多用户随时可以面对数据,随时按照自己的想法来获取所希望的数据 ;
现在,让我们放松一下,连接上 Pasiv Device 跟随Dream Architect ,开始从现实系统进入未来的梦境的旅程,一起来构造属于阿里巴巴未来所需要计算存储平台。
Overall System Architecture
系统的总体架构将满足以下特性:
Ø Distributed & Parallel
如前文所述,系统的可伸缩性是我们的系统架构中必须要考虑的一个重要因素,解决Scale Out 的必由之路是走分布式计算的道路。将系统的数据、服务请求、负载压力都能均摊到多个处理节点中。根据业务的需要,可以通过垂直分区(比如将业务功能拆分不同的功能模块,并将这些不同的功能模块交由不同的处理单元实现)和水平分区(比如将一组数据元素切分为许多个实例,并这个数据元素的不同数据实例交由不同的处理单元完成)来实现功能的分布式。
分布式带来的另一个好处并行化,将一个任务拆解为许多个逻辑单元,将这许多个逻辑单元交由多个处理单元并行的处理从而大幅提升批处理任务的性能。
Ø Transparent & Elasticity
后台复杂的分布式逻辑对应用和开发人员隐藏,能让开发人员开发代码像在单机上一样开发。
数据群集存储服务,应用对数据访问透明,无需关心存储的位置;遵循于CAP theorem 的跨多节点数据分布模型而设计,支持数据的水平伸缩。这意味着对于多数据中心和动态供应(在生产集群中透明地加入/ 删除节点)的必要支持,也即弹性[2] 。
Ø High Availability & Fault Tolerance
Data Center 发展到今天,已经不再是一个单纯的后台系统。随着应用的深入和实时化的推进,Data Center 越来越前台化,需要提供7*24 可用性级别;任意硬件设备导致的宕机是完全不可接受