书名:分布式系统设计与实践
ISBN:978-7-115-51945-0
本书由人民邮电出版社发行数字版。版权所有,侵权必究。
您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。
我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。
如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。
编 著 李庆旭
责任编辑 杨海玲
人民邮电出版社出版发行 北京市丰台区成寿寺路11号
邮编 100164 电子邮件 315@ptpress.com.cn
网址 http://www.ptpress.com.cn
读者服务热线:(010)81055410
反盗版热线:(010)81055315
本书对近年来涌现出的各种主流分布式技术做了简要介绍和全面梳理。本书将分布式系统中涉及的技术分为前端构造技术、分布式中间件技术和分布式存储技术三大类,对每类技术都详细介绍了其原理、主流实现的设计思想和架构,以及相关应用场景。此外,本书还总结了分布式系统的构建思想,并分别针对业界几个非常成功的大型分布式系统(谷歌搜索系统、淘宝网电商平台、阿里云公有云平台、领英社交平台)进行了案例研究。
本书适合业界的架构师、工程师、项目管理人员,也适合大中专院校的高年级本科生和研究生参考和阅读。
我很喜欢看书。从小到大,我看过很多书。
每看一本好书,我都会对书的作者充满感激和敬意,因为他愿意花那么多精力,写一本那么好的书给别人看,实在是非常值得尊敬。我知道,写书是赚不了多少钱的,一个人不为名、不为利,却愿意花很多精力写一本好书给别人去读、去欣赏,实在是难能可贵!
因此,我一直有一个想法,就是有一天,我也要尽力去写一本“好点儿”的书,一则对自己的所学做一个系统的整理,二则也为读者做些贡献。
我不知道是否有人会喜欢我的这本书,但无论如何,我已经尽力把它写好,因为我想和那些自己曾经读过的好书的作者一样,奉献给读者一本值得读的书。
我从1991年开始接触计算机,绝对算是一个“老码农”了。屈指一算,从那时到现在,计算机技术经历了几次重要的更新换代。
第一次发生在20世纪90年代初,是从DOS到Windows的换代。这一次换代淘汰了一批落后的公司和产品,亦有一批新的公司和产品崛起。当年DOS下的WPS如日中天,然而Windows一经推出,就难觅WPS的踪迹了。直到21世纪初,新版Windows下的金山WPS才姗姗而来。如果当年求伯君先生能及时推出新版的Windows下的WPS,那么中文办公软件的市场也许就不是今天这样了。
第二次换代发生在20世纪90年代末到21世纪初,Java和.NET这样的基于虚拟机的开发技术开始兴起。在DOS/Windows下,C/C++一直是主流的开发语言,而随着计算机软件的复杂度越来越高,C/C++语言开发效率低、查错难的弊端越来越突出,于是Java和.NET这样的基于虚拟机的开发技术日益受到开发者的青睐。这一波技术换代使Java的应用范围越来越广,也动摇了微软公司的技术在开发领域中无可替代的地位。
进入21世纪后,由于互联网技术,尤其是移动互联网技术的发展,诞生了一批大型互联网公司(谷歌、亚马逊、Facebook、百度、阿里巴巴、腾讯等)。在互联网发展的初期,这些公司在汹涌而来的大数据面前毫无准备,被折腾得筋疲力尽。痛定思痛后,以谷歌为代表的互联网新贵们,开发了许多优秀的技术(GFS、Bigtable、Hadoop等),完美而优雅地解决了大多数曾经令它们头疼的问题。继谷歌将其技术以论文的形式发表后,业界就开始模仿其设计和架构,相继开源了许多优秀的产品(如Apache Hadoop系列产品)。从此,大型分布式技术的大门被轰然推开,一个又一个大型的分布式应用(淘宝网上商城、京东网上商城、微信、谷歌搜索、Twitter社交平台、Facebook社交平台等)相继诞生。这就是以移动互联网和分布式计算的大规模应用为代表的第三次技术换代。无疑,这一次换代又是一次各大公司实力的大洗牌。
第四次大的技术换代是什么?也许它正在进行(如果它是人工智能的话),也许还没有开始……
每一次大的技术换代,都会有公司和技术被无情地淘汰,从Novell到Borland,到Netscape,再到Nokia,昔日霸主早已风光不再。但被淘汰的不仅有大公司,同时被淘汰的还有不少从事技术工作的工程师和架构师。因此,为了不被技术浪潮无情地拍倒,每一个IT从业者都应该对新技术心存敬畏,都应该关注技术的发展。
今天,对于在IT行业从事技术工作的人,无论是工程师、架构师还是管理者,也无论从事的工作是否与分布式相关,都应该了解分布式技术,因为总有一天,你会遇到它、接触它、使用它、理解它、完善它。
然而,分布式技术涉及的方面(存储、计算、框架、中间件等)是如此之多,且迄今为止尚未见到一本书对其进行概括和梳理,要想对分布式技术有全面的了解,特别是对初学者而言,何其难哉!
因此,本书试图对近年来涌现出的各种主流分布式技术做一个简要介绍,以使不太熟悉这个领域的读者能了解其概貌、原理和根源。
本书共分为以下6部分。
在本书写作的过程中,参考了许多网上的资料和书籍,感谢这些资料的作者们。由于涉及的资料太多,无法将其作者一一列出,谨表歉意。
感谢人民邮电出版社的杨海玲编辑,没有你的辛勤付出,也不会有本书的顺利出版。
另外,还要感谢我的好朋友申天雷,感谢你在繁忙的工作之余抽出时间来全面审阅这本书。
最后,感谢我的家人。没有父母的养育,我不可能有机会掌握这些知识;没有我岳父母帮我看管孩子,没有我爱人的关心与支持,我不可能有时间来写作;没有我儿子那双充满期待的眼睛,我也不可能一直坚持把本书写完!
由于分布式系统涉及的内容实在太多,我不可能对其中每个细节都有很深刻和精确的理解,因此,书中错误及疏漏之处在所难免,欢迎批评指正。
李庆旭
2019年夏于北京
本书由异步社区出品,社区(https://www.epubit.com/)为您提供相关资源和后续服务。
本书提供源代码下载,要获得相关配套资源,请在异步社区本书页面中单击 ,跳转到下载界面,按提示进行操作即可。注意:为保证购书读者的权益,该操作会给出相关提示,要求输入提取码进行验证。
作者和编辑尽最大努力来确保书中内容的准确性,但难免会存在疏漏。欢迎您将发现的问题反馈给我们,帮助我们提升图书的质量。
当您发现错误时,请登录异步社区,按书名搜索,进入本书页面,单击“提交勘误”,输入勘误信息,单击“提交”按钮即可。本书的作者和编辑会对您提交的勘误进行审核,确认并接受后,您将获赠异步社区的100积分。积分可用于在异步社区兑换优惠券、样书或奖品。
我们的联系邮箱是contact@epubit.com.cn。
如果您对本书有任何疑问或建议,请您发邮件给我们,并请在邮件标题中注明本书书名,以便我们更高效地做出反馈。
如果您有兴趣出版图书、录制教学视频,或者参与图书翻译、技术审校等工作,可以发邮件给我们;有意出版图书的作者也可以到异步社区在线提交投稿(直接访问www.epubit.com/selfpublish/submission即可)。
如果您来自学校、培训机构或企业,想批量购买本书或异步社区出版的其他图书,也可以发邮件给我们。
如果您在网上发现有针对异步社区出品图书的各种形式的盗版行为,包括对图书全部或部分内容的非授权传播,请您将怀疑有侵权行为的链接发邮件给我们。您的这一举动是对作者权益的保护,也是我们持续为您提供有价值的内容的动力之源。
“异步社区”是人民邮电出版社旗下IT专业图书社区,致力于出版精品IT技术图书和相关学习产品,为作译者提供优质出版服务。异步社区创办于2015年8月,提供大量精品IT技术图书和电子书,以及高品质技术文章和视频课程。更多详情请访问异步社区官网https://www.epubit.com。
“异步图书”是由异步社区编辑团队策划出版的精品IT专业图书的品牌,依托于人民邮电出版社近30年的计算机图书出版积累和专业编辑团队,相关图书在封面上印有异步图书的LOGO。异步图书的出版领域包括软件开发、大数据、AI、测试、前端、网络技术等。
异步社区
微信服务号
之所以需要有分布式系统,最根本的原因还是单机的计算和存储能力不能满足系统的需要,但要把成百上千台计算机组织成一个有机的系统绝非易事。
这一部分会对典型的分布式系统的组成及其每个组件的功能做简要介绍,以便读者对分布式系统有一个总体的了解。
1999年8月6日,CNN报道了一起eBay网站的事故:从7:30开始,整个网站崩溃,一直持续了9个多小时。下午5:30后,技术人员开始进行系统恢复,但搜索功能依然不能使用。
2011年4月21日至22日,亚马逊EC2(Elastic Computer Cloud)服务出现大面积事故,导致数以千计的初创公司受到影响,而且造成大约11小时的历史数据永久性丢失。
2013年4月27日,《大掌门》游戏的开发商玩蟹科技CEO叶凯在微博上吐槽,“我们在阿里云上用了20多台机器。半年时间,出现过1次所有机器全部断电,2次多个硬盘突然只读,3次硬盘I/O突然变满……”。
2013年12月28日,春运第一天,铁道部首次推出了网上订票系统,但很快就出现许多用户无法访问、响应缓慢甚至串号等事故。
2017年9月17日,谷歌的网盘服务Drive出现故障,成千上万用户受到影响。
上面的这几起事故,当时都闹得沸沸扬扬,不仅给受影响的用户带来了很大的损失,也极大地影响了厂商的形象。事实上,几乎每一家互联网公司的后台系统都曾经不止一次地经历过这样或那样的尴尬时刻。可以这样说,几乎每一家互联网公司的后台架构都是在发现问题、解决问题的循环中发展起来的。
即便是执分布式系统技术牛耳的谷歌,在2017年9月,也出现过分布式系统的故障。可见,开发并维护一个成功的分布式系统是多么不易!
最早得到广泛应用的分布式系统是诞生于20世纪70年代的以太网。尽管分布式系统存在的历史已经有近半个世纪,然而其大规模的发展和应用则是2000年以后的事情。
21世纪以来,随着雅虎、谷歌、亚马逊、eBay、Facebook、Twitter等众多互联网公司的崛起,其用户量以及要处理的数据量迅速增长,远远超过了传统的计算机系统能够处理的范围,因此,以谷歌为代表的互联网公司提出了许多新技术(如HDFS、Bigtable、MapReduce等)。以BAT为代表的中国互联网公司,也在21世纪整体崛起,在初期借鉴美国公司技术的基础上,他们也自行开发了许多新的技术(如淘宝的管理海量小文件的分布式存储系统TFS、阿里巴巴开源的分布式调用框架Dubbo、阿里巴巴开源的数据库中间件Cobar等)。
为了解决分布式系统中的各种各样的问题,各大互联网公司开发了各种各样的技术,当然,这也促进了当今分布式系统技术领域的飞速发展。为了存储大量的网站索引,谷歌设计了GFS分布式文件存储系统和基于列存储的Bigtable NoSQL数据库系统;为了计算PageRank算法中的页面rank值,谷歌又设计了MapReduce分布式计算系统;为了方便其分布式系统中不同主机间的协调,谷歌还设计了Chubby分布式锁系统;为了解决不同语言实现的组件间的通信问题,Facebook设计了Thrift;为了解决大量消息的快速传递问题,领英设计了Kafka……这个列表可以很长很长。
为了“压榨”分布式系统中每个组件的性能,人们已经不再仅仅满足于在程序库(如网络编程库Netty、内存管理库TCMalloc等)、程序框架(如Spring)等“略显浅薄”的地方提高,而是已经渗透到了硬件(如谷歌为其计算中心专门设计了计算机)、网络(如SDN)、操作系统(如各大互联网公司定制的Linux内核)、语言(如谷歌设计的Go语言)、数据库系统(如各种NoSQL系统)、算法(如人工智能领域的突飞猛进)等各种计算机基础领域。
毫无疑问,我们处于计算机技术发展最为迅猛的时代。在这个如火如荼的时代里,许多尘封多年的计算机技术(如人工智能、分布式系统、移动计算、虚拟计算等),一改往日不温不火的模样,在互联网这片广袤的土地上如日中天,发展迅速。
今天的计算机领域,已经与20年前大为不同。20年前,只需要对操作系统、数据库、网络、编译等领域有深刻的理解,再熟练掌握几门计算机语言,了解一些常见的软件架构(客户服务器架构、管道架构、分层架构等)和软件工程(主要是瀑布模型)的知识,基本上就能胜任大多数软件开发工作了。而今天,仅了解这些基础知识已经远远不够,因为在近20年内,人类创造了太多的新技术,而这些新技术又大都起源并服务于分布式计算领域。
一个大型的分布式系统虽然非常复杂,但其设计目标却往往是非常简单的,例如,京东和淘宝这样的电商,其设计目标是卖东西;谷歌和百度这样的搜索引擎,其设计目标是帮助大家在网上找相关的内容;Facebook和微信这样的社交应用,其设计目标是方便大家相互联系并分享自己生活中的点点滴滴。
如前文所述,之所以需要有分布式系统,最根本的原因还是单机的计算和存储能力不能满足系统的需要。但要把成百上千台计算机组织成一个有机的系统,绝非易事。在人类社会中,其实也一样,找到1000个人容易,但要把这1000个人组织成一只能战斗的军队可就没那么简单了。
一个典型的分布式系统如图1-1所示。
图1-1 一个典型的分布式系统
本章下面的内容先就后端最重要的分布式协调组件、后端存储系统和后端计算系统做一个概要的介绍。
分布式系统之所以存在,最根本的原因是数据量或计算量超过了单机的处理能力,因此不得不求助于水平扩展[4],而为了协调多个节点的动作,则不得不引入分布式协调组件。
在单机操作系统中,几个相互合作的进程(如生产者/消费者模型中的生产者进程和消费者进程),如果需要进行协调,就得借助于一些进程间通信机制,如共享内存、信号量、事件等。分布式协调组件提供的功能,本质上就是分布式环境中的进程间通信机制。
也许,有人会觉得这有何难,用一个数据库不就解决了吗?如代码清单1-1所示,将分布式锁信息保存在一张数据库表中(假如表名叫LOCK_TABLE),增加一个锁就是向LOCK_TABLE表中添加一新行(假如该行ID为MYCLOCK1),要获得该锁,只需要将MYCLOCK1行的某个字段(如LOCK_STATUS)置为1;要释放该锁,只需要将此字段置为0。利用数据库本身的事务支持,这个问题不就解决了吗?
代码清单1-1 利用数据库实现分布式锁
1. ' 获得锁
2. START TRANSACTION;
3. UPDATE LOCK_TABLE
4. SET LOCK_STATUS = 1, LOCK_OWNER="process1"
5. WHERE ID="MYCLOCK1" AND LOCK_STATUS=0;
6. COMMIT;
7. 调用者检查LOCK_OWNER字段是否为"process1",即可获知是否加锁成功
8. ' 释放锁
9. START TRANSACTION;
10. UPDATE LOCK_TABLE
11. SET LOCK_STATUS = 0, LOCK_OWNER=""
12. WHERE ID="MYCLOCK1" AND LOCK_STATUS=1 AND LOCK_OWNER="process1";
13. COMMIT;
然而,事情远没有那么简单。在分布式环境中,节点/网络故障为常态,如果采用代码清单1-1所示的方案,假如数据库所在的节点宕机了,整个系统就会陷入混乱。因此,这种有单点故障的方案肯定是不可取的。
分布式协调组件对外提供的是一种分布式同步服务。为了获得健壮性,一个协调组件内部也是由多个节点组成的,节点[5]之间通过一些分布式一致性协议(如Paxos、Raft)来协调彼此的状态。如果一个节点崩溃了,其他节点就自动接管过来,继续对外提供服务,好像什么都没有发生过一样。
另外,为了应用程序的方便,分布式协调组件经常还会允许在其上存放少量的信息(如主服务器的名称),这些信息也是由分布式一致性协议来维护其一致性的。
与单机系统类似,分布式系统的存储也分为两个层次:第一个层次是文件级的,即分布式文件系统,如GFS(Google File System)、HDFS(Hadoop Distributed File System)、TFS(Taobao File System)等;第二个层次是在文件系统之上的进一步抽象,即数据库系统。不过,分布式系统下的数据库远比单机的关系型数据库复杂,因为数据被存储在多个节点上,如何保证其一致性就成了关键,所以,分布式系统下的数据库采用的大都是最终一致性[6],而非满足ACID[7]属性的强一致性。
由于对一致性支持的不同,传统的ACID理论就不再适用了,于是,Eric Brewer提出了一种新的CAP[8]理论。CAP理论听起来高大上,但实际上并没有那么复杂。它的意思是,在分布式系统里,没有办法同时达到一致性、可用性和网络分区可容忍性,只能在三者中择其二。
不过,要注意CAP中的C和A与ACID中的C和A的含义是不同的(如表1-1所示),网络分区可容忍性的含义较为晦涩,是指一个分布式系统中是否允许出现多个网络分区。换言之,如果网络断了,一个系统中的多个节点被分成了多个孤岛,这允许吗?如果允许,就满足网络分区可容忍性,否则就不满足。
表1-1 CAP与ACID中的C和A的不同
属性 |
CAP |
ACID |
---|---|---|
C |
英文是consistency,指数据不同副本(replica)之间的一致性 |
英文也是consistency,但指数据库的内容处于一致的状态,如主键与外键的一致性 |
A |
英文是availability,指系统的可用性 |
英文是atomicity,指事务的原子性 |
对于CAP理论,其实很好理解。我们可以想一想,如果需要满足网络分区可容忍性,即允许孤岛的存在,那么当孤岛产生时,只能要么继续提供服务(即满足可用性),要么停止服务(即满足一致性),其他的情况也类似。然而,在分布式系统中,由于孤岛的不可避免性,因此实际的系统只能在一致性和可用性中选择其一,即只能是满足一致性和网络分区可容忍性或者满足可用性和网络分区可容忍性的系统。
采用最终一致性的数据库系统,统称为NoSQL(Not only SQL)系统。根据数据模型的不同,NoSQL系统又分为以下几大类:
近几年,还涌现出一类称为NewSQL的系统(如谷歌的Megastore、谷歌的Spanner、阿里巴巴的OceanBase和PingCAP TiDB),号称既满足关系型数据库的ACID属性,又可以如NoSQL系统那般水平伸缩。然而,这些系统本质上还是满足最终一致性的NoSQL系统,只不过,它们将可用性和一致性处理得非常好,在外界看来,似乎同时满足了可用性和一致性,实则只是在实现上做了“手脚”,将不一致性“隐藏”起来,并将其“默默”地消化掉。
例如,谷歌Megastore将同一数据的不同分区存放在不同的数据中心中,在每个数据中心内部,属于同一个分区的数据存放在同一个Bigtable中。借助于Bigtable对单行数据读写的事务支持,Megastore支持同一个分区内的ACID属性,但对于跨分区(即跨数据中心)的事务,则通过两阶段提交实现,因此,也是最终一致的。
再如阿里巴巴的OceanBase,它将数据分为两部分,一部分是较早的数据(称为基准数据),另一部分是最新的数据(称为增量数据),基准数据与增量数据分开存储,读写请求都由一个专门的合并服务器(Merge Server)来处理。合并服务器解析用户的SQL请求,然后生成相应的命令发给存储基准数据和增量数据的服务器,再合并它们返回的结果;此外,后台还定期将增量数据合并到基准数据中[9]。OceanBase定期将更新服务器(Update Server)上的增量数据合并到各个数据块服务器(Chunk Server)中。因此,OceanBase也是最终一致的,但通过合并服务器把暂时的不一致隐藏起来了。
因此,本质上,只有两种数据库系统,即满足ACID属性的RDBMS和满足最终一致性的NoSQL系统。所谓的NewSQL,只不过是披着SQL系统外衣(即SQL支持和ACID属性)的NoSQL系统而已。
分布式存储系统只解决了大数据的存储问题,并没有解决大数据的计算问题。当计算量远远超过了单机的处理能力后,该怎么办呢?一种方式是各自开发专属的分布式计算框架,但这些计算框架很难做到通用和共享。因此,在不同公司或同一公司的不同团队中,存在着各种各样的分布式计算框架,造成了很大的浪费,而且框架的质量也良莠不齐。
谷歌公司于2004年发表的MapReduce论文几近完美地解决了这个问题。MapReduce通过下面两个看似简单却包含了深刻智慧的函数,轻而易举地解决了一大类大数据计算问题。
map (<K1, V1>) → list(<K2, V2>)[10]
reduce (<K2, list(V2)>) → list(V3)[11]
如图1-2所示,使用MapReduce解决问题的步骤如下。
(1)需要将输入表示成一系列的键值对<K1, V1>。
(2)定义一个map函数,其输入是上一步的一个键值对<K1, V1>,其输出则是另一种键值对<K2, V2>的列表。
图1-2 MapReduce工作原理
(3)运行时,MapReduce框架会对每一个输入的键值对<K1, V1>调用map函数(执行map函数的机器称为Mapper),并生成一系列另一种键值对<K2, V2>。然后,MapReduce框架会根据K2进行分区(partition),即根据K2的值,将<K2, V2>对在多个称为Reducer(即执行reduce函数的机器)的机器间进行分发。
(4)还需要定义一个reduce函数,该函数的输入是一系列K2和与其对应的V2值的列表,输出是另一种值V3的列表。
(5)运行时,MapReduce框架会调用reduce函数,由reduce函数来对同一个K2的V2的列表进行聚合。
MapReduce本质上是一种“分而治之”的策略,只不过数据规模很大而已。它首先把全部输入分成多个部分,每部分启动一个Mapper;然后,等所有Mapper都执行完后,将Mapper的输出根据K2做分区,对每个分区启动一个Reducer,由Reducer进行聚合。
MapReduce看似简单,却能够解决一大类问题。MapReduce能够解决的问题具有下列特征。
对于那些不断有新数据进来,而且对实时性要求很高的计算(如实时的日志分析、实时的股票推荐系统等),MapReduce就不适用了。于是,流处理系统应运而生。
根据对新数据的处理方式,流处理系统分为以下两大类。
在分布式计算领域,还有一种混合了批处理和流处理的系统,这类系统的一个例子是电商的智能推荐系统,其既需要批处理的功能(为了确保响应速度,预先将大量的计算通过批处理系统完成),也需要流处理的功能(根据用户的最新行为,对推荐系统进行实时调整)。
对于这类系统,有一种很流行的架构,即Lamda架构(如图1-3所示),其思想是用一个批处理系统(如MapReduce)来进行批处理计算,再用一个实时处理系统(如Apache Spark/Storm)来进行实时计算,最后用一个合并系统将二者的计算结果结合起来并生成最终的结果。
图1-3 Lamda架构
对于混合系统的实现,有篇非常有趣的文章值得一读,“Questioning the Lambda Architecture”一文中提到了Lamda架构的一个很大的缺点,即处理逻辑需要在批处理系统和流处理系统中实现两遍。该文提到了一种新的混合系统实现方式,即利用Kafka可以保存历史消息的特性,根据业务的需要,在Kafka中保存一定时间段内的历史数据,当需要进行批处理时,则访问Kafka中保存的历史数据,当需要实时处理时,则消费Kafka中的最新消息。如此这般,处理逻辑就只需要实现一套了。感兴趣的读者,可以读一读此文。
一个人类社会的组织,要想实现其组织功能,组织内的人需要按照某种方式被组织起来,例如,有的人负责管理,有的人负责执行,等等。由许多节点组成的分布式系统也一样,系统中的节点也需要被有机地组织起来,才能实现想要完成的功能。也就是说,有些节点需要承担这样的角色,而另一些节点则需要承担另外的角色。根据所承担角色的不同,节点之间的关系不外乎下面两种。
相对而言,主从式系统实现起来要简单些,而对等式系统实现起来则困难些。
[1] 所谓集群,是指采用同样或类似配置的许多台机器,为了达到一个共同的目的而组成的系统。
[2] 像谷歌和百度这样的公司,因为索引的页面量非常庞大,需要很大的存储空间。微信和Facebook这样的社交应用亦然。
[3] 例如谷歌,其PageRank算法就需要很大的计算量;再如京东和淘宝这样的电商,其商品推荐系统也需要很大的计算量。
[4] 水平扩展(scale out)与垂直扩展(scale up)是一对相对的概念,前者是指通过增加额外的节点来扩展系统的处理能力,后者则指通过升级单个节点的硬件(CPU、内存、磁盘)来进行扩展。
[5] 节点与机器可以是物理的实体(即物理机器),也可以是虚拟的实体(如虚拟机、Docker容器)在本书中这两个概念在本书中不加区别,常互换使用。
[6] 最终一致性即在“有穷”的时间内,各个节点上的数据最终会收敛到一致的状态,当然这里的“有穷”经常是指很短暂的时间,几分或几秒就算比较长的了。
[7] ACID指的是原子性(Atomicity)、一致性(Consistency)、独立性(Isolation)和持久性(Durability)。
[8] CAP指的是一致性(Consistency)、可用性(Availability)和网络分区可容忍性(Tolerance to Network Partitions)。
[9] 阿里巴巴的OceanBase的这种实现方式实际上就是所谓的Lamda架构。
[10] map函数的功能是将输入的键值对映射成一个新的键值对列表。
[11] reduce函数的功能是将一个键和一个值的列表映射成一个新的值的列表。
典型的分布式系统由前端和后端组成,其需求有很大的不同,因而构造技术也各异。
前端的需求主要是在尽可能短的时间内迅速接收和处理大量的请求。前端的核心技术是如Apache和Nginx这样的Web服务器,在此之上,为了简化和加快应用的开发,业界开发了大量的Web框架。有基于Java语言的Web框架,如Java EE、Spring,也有基于PHP的Web框架,如Code Igniter。新型的Go语言则内置了许多Web开发功能,极大地简化了前端的开发工作。
对于大型的分布式系统,单个Web服务器已经远远不能满足业务的需要,因此,就有了代理和负载均衡技术,以提高前端的处理能力和响应速度。