0
0

【分布式系统工程实现】系统可扩展性演化

chuanhui 发表于 2010年11月04日 22:16 | Hits: 2255
Tag: 分布式架构 | Commit Log | Homogeneous System | Scalability

一般来说,只要多台机器通过互相协调共同执行某项任务,我们都会将这套系统称为”分布式系统”,这样显得更有技术含量。从这个意义上讲,Memcache集群,Mysql sharding集群,Yahoo PNUTS,Google GFS&Bigtable,Amazon Dynamo以及国内众多专用的NOSQL系统都是分布式系统。分布式系统的难点主要在于可扩展性,随着机器数量的增多,集群能力是否能够接近线性扩展,因集群规模扩大而产生的容错需求,负载的动态迁移,对系统的设计和实现是一个巨大的挑战。我们经常会讲,NOSQL系统相比数据库有更好的可扩展性,但我们很少探究其中的原因,我们很少探究数据库和可扩展的分布式系统,比如GFS&Bigtable之间的差距。本文就系统可扩展性问题抛一个砖头,希望有牛人能够一起分享自己的经验。

数据库可以通过水平切分和垂直切分的方式实现可扩展性。垂直切分主要基于业务的角度,水平切分主要基于系统的角度。简单来说,数据库水平切分就是通过一系列切分规则将数据水平分布到不同的DB和table中,再通过相应的DB路由或者table路由定位到需要查询的DB或者table,进行Query操作。可以引入一个数据库访问中间层进行数据路由,读写分离并执行简单的order by, group by, limit等操作,如淘宝的TDDL。

这个架构的可扩展性不好,根本原因是机器同构。假设数据库服务的数据为1TB,线上数据拷贝限速20MB/s,那么新机器上线拷贝数据的时间为1TB / 20MB/s = 50000s,大概是十几个小时,这是不可接受的。因此,数据库的架构一般会使用共享存储,大大提高了系统成本,与可扩展分布式系统产生的初衷相违背。机器同构的问题不仅仅出现在数据库系统,大多专用的NOSQL系统都有这样的问题,比如,有的系统底层使用了Berkerly DB或者其它针对特定应用的Key-Value存储引擎,上层仍然采用将机器分成多个组,组内的机器同构,通过Replication同步保证可靠性,数据通过Hash或者其它方法分布到不同的分组。这样的NOSQL系统与数据库在可扩展性上没有本质的差别,不同点主要在于:NOSQL系统不需要支持一些View,外键,多表join等大规模系统基本不用的功能,且为应用定制,往往很高效,系统规模较小,在工程上可控,开发人员对代码熟悉,有利于人员培养,系统优化等。同构的系统虽然可扩展性不好,技术人员总会觉得缺少了什么,不过仍然能够解决大多数问题,后续章节将专门阐述。

解决系统的可扩展性问题,往往需要将数据分成一个一个的小段,在Bigtable或者PNUTS等系统中称为子表,英文名为Tablet。系统如果需要有很好的可扩展性,就需要支持机器宕机时子表能够迅速迁移到整个集群中所有可用的机器,而不是某一台特定的机器。如果数据是静态的,那么一切变得简单。然而,现实中的数据往往是动态更新的,大多数系统设计时也会将数据更新操作以操作日志(commit log)的形式持久化到磁盘中,如果有稳定可靠的地方,比如分布式文件系统,存储操作日志,那么每台机器上的数据分片(Tablet)都可以认为是无状态的,机器宕机时,集群中所有的机器都可以加载静态数据并从稳定可靠的操作日志存放处获取动态更新,问题得到解决。因此,高可扩展性系统设计的关键点就在于稳定可靠的地方存储操作日志

大多数线上系统服务的数据都是很大的,如TB ~ 百TB之间,然而,动态的更新一般是比较少的,比如每天的更新只有几百个GB。因此,稳定可靠的日志存储系统的设计变得相对简单,比如Yahoo PNUTS采用消息中间件的方式存储操作日志。根据公开的资料推断,Yahoo内部使用的消息中间件Yahoo Message Broker也是一个同构的系统,然而,由于只需要存储线上的更新数据,数据量很小,比如每天100GB,保留三天则数据量为300GB,假设采用10组同构的机器存放数据,每组服务的数据量为30GB,增加机器副本的数据拷贝时间为30GB / 20MB/s = 1500s,这是可以接受的。

然而,Yahoo PNUTS系统可扩展性基于一个假设:系统动态更新比较少。如果系统需要同时支持线下和线上应用,比如支持线下的MapReduce计算,更新量很大,存储操作日志的消息中间件的可扩展性成了一个问题。因此,Google的设计采用GFS+Bigtable双层结构,采用底层可扩展的分布式文件系统GFS存放操作日志,由于日志操作为追加,GFS的Append模型支持Bigtable已经足够了。另外,由于底层的GFS可扩展性很好,Bigtable的持久化数据,即SSTable文件也存放在GFS中,从而当机器宕机时,Bigtable的数据不需要迁移,仅仅需要重新加载索引数据到内存中,减少了数据迁移时间。Google宣称他们做到了机器随时推进推出,正是因为他们的系统可扩展性做得很好。

Amazon Dynamo的思路就是通过牺牲一致性来避免复杂的操作日志问题。Amazon Dynamo不保证同一个时刻对于同一份数据只有一个写节点,因此,多个节点的数据写入顺序可能不相同,Dynamo中有一些NWR策略来权衡数据一致性及可用性,不过数据冲突是无法避免的,因此,需要引入vector clock等冲突处理方法。Dynamo中可扩展性主要是通过虚拟节点的方式实现的,每台机器宕机时,数据和服务可以迁移到集群中的所有机器。由于不需要考虑数据一致性,事情变得相对简单。

高可扩展性的系统有一个优势就是规模效应,随着集群增大,成本优势非常明显,因此很适合提供云服务,劣势就是前期投入太大,开发及稳定周期太长,我们往往可以采取一些折衷的方案。比如我们可以将动态更新操作存放到单机内存中,静态数据存放到多台机器的磁盘中,定期将静态数据和动态数据合并,读取操作同时读取静态数据和动态数据部分,由于动态数据存放在内存中,这样的系统设计对于大多数应用性能不成问题,且极大地减低了系统整体复杂性。更为重要的是,只要我们理解了分布式系统可扩展性设计的关键点,提前制定好系统发展路线图,经过一段时间积累后一定能够设计和开发出可扩展的分布式系统。

原文链接: http://www.nosqlnotes.net/archives/17

0     0

我要给这篇文章打分:

可以不填写评论, 而只是打分. 如果发表评论, 你可以给的分值是-5到+5, 否则, 你只能评-1, +1两种分数. 你的评论可能需要审核.

评价列表(0)