一、分布式系统的难点
分布式系统比起单机系统存在哪些难点呢?
1. 网络因素
由于服务和数据分布在不同的机器上,每次交互都需要跨机器运行,这带来如下几个问题:
1. 网络延迟:性能、超时
同机房的网络IO还是比较块的,但是跨机房,尤其是跨IDC,网络IO就成为不可忽视的性能瓶颈了。并且,延迟不是带宽,带宽可以随便增加,千兆网卡换成万兆,只是成本的问题,但延迟是物理限制,基本不可能降低。
这带来的问题就是系统整体性能的降低,会带来一系列的问题,比如资源的锁住,所以系统调用一般都要设置一个超时时间进行自我保护,但是过度的延迟就会带来系统的RPC调用超时,引发一个令人头疼的问题:分布式系统调用的三态结果:成功、失败、超时。不要小看这个第三态,这几乎是所有分布式系统复杂性的根源。
针对这个问题有一些相应的解决方案:异步化,失败重试。 而对于跨IDC数据分布带来的巨大网络因素影响,则一般会采用数据同步,代理专线等处理方式。
2. 网络故障:丢包、乱序、抖动。
这个可以通过将服务建立在可靠的传输协议上来解决,比如TCP协议。不过带来的是更多的网络交互。因此是性能和流量的一个trade off。这个在移动互联网中更需要考虑。
2. 鱼与熊掌不可兼得——CAP定律
CAP理论是由Eric Brewer提出的分布式系统中最为重要的理论之一:
- Consistency:[强]一致性,事务保障,ACID模型。
- Availiablity:[高]可用性,冗余以避免单点,至少做到柔性可用(服务降级)。
- Partition tolerance:[高]可扩展性(分区容忍性):一般要求系统能够自动按需扩展,比如HBase。
CAP原理告诉我们,这三个因素最多只能满足两个,不可能三者兼顾。对于分布式系统来说,分区容错是基本要求,所以必然要放弃一致性。对于大型网站来说,分区容错和可用性的要求更高,所以一般都会选择适当放弃一致性。对应CAP理论,NoSQL追求的是AP,而传统数据库追求的是CA,这也可以解释为什么传统数据库的扩展能力有限的原因。
在CAP三者中,“可扩展性”是分布式系统的特有性质。分布式系统的设计初衷就是利用集群多机的能力处理单机无法解决的问题。当需要扩展系统性能时,一种做法是优化系统的性能或者升级硬件(scale up),一种做法就是“简单”的增加机器来扩展系统的规模(scale out)。好的分布式系统总在追求”线性扩展性”,即性能可以随集群数量增长而线性增长。
可用性和可扩展性一般是相关联的,可扩展行好的系统,其可用性一般会比较高,因为有多个服务(数据)节点,不是整体的单点。所以分布式系统的所有问题,基本都是在一致性与可用性和可扩展性这两者之间的一个协调和平衡。对于没有状态的系统,不存在一致性问题,根据CAP原理,它们的可用性和分区容忍性都是很高,简单的添加机器就可以实现线性扩展。而对于有状态的系统,则需要根据业务需求和特性在CAP三者中牺牲其中的一者。一般来说,交易系统类的业务对一致性的要求比较高,一般会采用ACID模型来保证数据的强一致性,所以其可用性和扩展性就比较差。而其他大多数业务系统一般不需要保证强一致性,只要最终一致就可以了,它们一般采用BASE模型,用最终一致性的思想来设计分布式系统,从而使得系统可以达到很高的可用性和扩展性。
CAP定律其实也是衡量分布式系统的重要指标,另一个重要的指标是性能。
一致性模型
主要有三种:
- Strong Consistency(强一致性):新的数据一旦写入,在任意副本任意时刻都能读到新值。比如:文件系统,RDBMS,Azure Table都是强一致性的。
- Week Consistency(弱一致性):不同副本上的值有新有旧,需要应用方做更多的工作获取最新值。比如Dynamo。
- Evantual Consistency(最终一致性):一旦更新成功,各副本的数据最终将达到一致。
从这三种一致型的模型上来说,我们可以看到,Weak和Eventually一般来说是异步冗余的,而Strong一般来说是同步冗余的(多写),异步的通常意味着更好的性能,但也意味着更复杂的状态控制。同步意味着简单,但也意味着性能下降。
以及其他变体:
- Causal Consistency(因果一致性):如果Process A通知Process B它已经更新了数据,那么Process B的后续读取操作则读取A写入的最新值,而与A没有因果关系的C则可以最终一致性。
- Read-your-writes Consistency(读你所写一致性):如果Process A写入了最新的值,那么 Process A的后续操作都会读取到最新值。但是其它用户可能要过一会才可以看到。
- Session Consistency(会话一致性):一次会话内一旦读到某个值,不会读到更旧的值。
- Monotonic Read Consistency(单调一致性):一个用户一旦读到某个值,不会读到比这个值更旧的值,其他用户不一定。
等等。
其中最重要的变体是第二条:Read-your-Writes Consistency。特别适用于数据的更新同步,用户的修改马上对自己可见,但是其他用户可以看到他老的版本。Facebook的数据同步就是采用这种原则。
二、分布式系统常用技术和应用场景
- consistent hashing [with virtual node]:一致性哈希,数据分布
- vector clock:时钟向量,多版本数据修改
- Quorum W+R>N [with vector clock]:抽屉原理,数据一致性的另一种解决方案。时钟向量,多版本数据修改。
- Merkle tree [with anti-entropy]:数据复制
- MVCC:copy-on-write与snapshot
- 2PC/3PC:分布式事务
- Paxos:强一致性协议
- Symmetry and Decentralization:对称性和去中心化。对称性(symmetry)简化了系统的配置和维护。去中心化是对对称性的延伸,可以避免master单点,同时方便集群scale out。
- Map-Reduce:分而治之;移动数据不如移动计算。将计算尽量调度到与存储节点在同一台物理机器上的计算节点上进行,这称之为本地化计算。本地化计算是计算调度的一种重要优化。
- Gossip协议:节点管理
- Lease机制:
consistent hashing:一致性哈希,解决数据均衡分布问题
我们通常使用的hash算法是hash() mod n,但是如果发生某个节点失效时,无法快速切换到其他节点。为了解决单点故障的问题,我们为每个节点都增加一个备用节点,当某个节点失效时,就自动切换到备用节点上,类似于数据库的master和slave。但是依然无法解决增加或删除节点后,需要做hash重分布的问题,也就是无法动态增删节点。这时就引入了一致性hash的概念 ,将所有的节点分布到一个hash环上,每个请求都落在这个hash环上的某个位置,只需要按照顺时针方向找到的第一个节点,就是自己需要的服务节点。当某个节点发生故障时,只需要在环上找到下一个可用节点即可。
一致性hash算法最常用于分布式cache中,比如注意的memcached。Dynamo也用其作为数据分布算法,并且对一致性算法进行了改进,提出了基于虚拟节点的改进算法,其核心思路是引入虚拟节点,每个虚拟节点都有一个对应的物理节点,而每个物理节点可以对应若干个虚拟节点。
关于一致性hash的更多内容,可以参考笔者另一篇博文:Memcached的分布式算法学习。
这篇文章也可以看看:某分布式应用实践一致性哈希的一些问题
virtual node
前面说过,有的Consistent Hashing的实现方法采用了虚拟节点的思想。使用一般的hash函数的话,服务器的映射地点的分布非常不均匀。因此,使用虚拟节点的思想,为每个物理节点(服务器)在continuum上分配100~200个点。这样就能抑制分布不均匀,最大限度地减小服务器增减时的缓存重新分布。
Quorum W+R>N:抽屉原理,数据一致性的另一种解决方案
N: 复制的节点数,即一份数据被保存的份数。 R: 成功读操作的最小节点数,即每次读取成功需要的份数。 W: 成功写操作的最小节点数 ,即每次写成功需要的份数。
所以 W+R>N的意思是:对于有N份拷贝的分布式系统,写到W(W<=N)份成功算写成功,读R(R<=N)份数据算读成功。
这三个因素决定了可用性,一致性和分区容错性。W+R>N可以保证数据的一致性(C),W越大数据一致性越高。这个NWR模型把CAP的选择权交给了用户,让用户自己在功能,性能和成本效益之间进行权衡。
对于一个分布式系统来说,N通常都大于3,也就说同一份数据需要保存在三个以上不同的节点上,以防止单点故障。W是成功写操作的最小节点数,这里的写成功可以理解为“同步”写,比如N=3,W=1,那么只要写成功一个节点就可以了,另外的两份数据是通过异步的方式复制的。R是成功读操作的最小节点数,读操作为什么要读多份数据呢?在分布式系统中,数据在不同的节点上可能存在着不一致的情况,我们可以选择读取多个节点上的不同版本,来达到增强一致性的目的。
NWR模型的一些设置会造成脏数据和版本冲突问题,所以一般要引入vector clock算法来解决这个问题。
需要保证系统中有max(N-W+1,N-R+1)个节点可用。
关于NWR模型,建议阅读 分布式系统的事务处理,写的很通俗易懂。
vector clock:时钟向量,多版本数据修改
参见 分布式系统的事务处理,写的很通俗易懂。
lease机制
chubby、zookeeper 获得lease(租约)的节点得到系统的承诺:在有效期内数据/节点角色等是有效的,不会变化的。
lease机制的特点:
- lease颁发过程只需要网络可以单向通信,同一个lease可以被颁发者不断重复向接受方发送。即使颁发者偶尔发送lease失败,颁发者也可以简单的通过重发的办法解决。
- 机器宕机对lease机制的影响不大。如果颁发者宕机,则宕机的颁发者通常无法改变之前的承诺,不会影响lease的正确性。在颁发者机恢复后,如果颁发者恢复出了之前的lease 信息,颁发者可以继续遵守lease的承诺。如果颁发者无法恢复lease信息,则只需等待一个最大的lease超时时间就可以使得所有的lease都失效,从而不破坏lease机制。
- lease机制依赖于有效期,这就要求颁发者和接收者的时钟是同步的。
- 如果颁发者的时钟比接收者的时钟慢,则当接收者认为lease已经过期的时候,颁发者依旧认为lease有效。接收者可以用在lease到期前申请新的lease的方式解决这个问题。
- 如果颁发者的时钟比接收者的时钟快,则当颁发者认为lease已经过期的时候,可能将lease颁发给其他节点,造成承诺失效,影响系统的正确性。对于这种时钟不同步,实践中的通常做法是将颁发者的有效期设置得比接收者的略大,只需大过时钟误差就可以避免对lease的有效性的影响。
工程中,常选择的lease时长是10秒级别,这是一个经过验证的经验值,实践中可以作为参考并综合选择合适的时长。
双主问题(脑裂问题)
lease机制可以解决网络分区问题造成的“双主”问题,即所谓的“脑裂”现象。配置中心为一个节点发放lease,表示该节点可以作为primary节点工作。当配置中心发现primary有问题时,只需要等到前一个primary的lease过期,就可以安全地颁发新的lease给新的primary节点,而不会出现“双主”问题。 在实际系统中,若用一个中心节点作为配置中心发送lease也有很大的风险。实际系统总是使用多个中心节点互为副本,成为一个小的集群,该小集群具有高可用性,对外提供颁发lease的功能。chubby和zookeeper都是基于这样的设计。
chubby一般有五台机器组成一个集群,可以部署成两地三机房。chubby内部的五台机器需要通过Paxos协议选取一个chubby master机器,其它机器是chubby slave,同一时刻只有一个chubby master。chubby相关的数据,比如锁信息,客户端的session信息等都需要同步到整个集群,采用半同步的做法,超过一半的机器成功就可以回复客户端。最后可以确保只有一个和原有的chubby master保持完全同步的chubby slave被选取为新的chubby master。
Gossip协议
Gossip用于P2P系统中自治节点获悉对集群认识(如集群的节点状态,负载情况等)。 系统中的节点定期互相八卦,很快八卦就在整个系统传开了。 A、B两个节点八卦的方式主要是:A告诉B知道哪些人的什么八卦;B告诉A这些八卦里B知道哪些更新了;B更新A告诉他的八卦...... 说是自治系统,其实节点中还有一些种子节点。种子节点的作用主要是在有新节点加入系统时体现。新节点加入系统中,先与种子节点八卦,新节点获得系统信息,种子节点知道系统中多了新节点。其他节点定期与种子节点八卦的时候就知道有新节点加入了。 各个节点互相八卦的过程中,如果发现某个节点的状态很长时间都没更新,就认为该节点已经宕机了。
Dynamo使用了Gossip协议来做会员和故障检测。
2PC、3PC、Paxos协议: 分布式事务的解决方案
分布式事务很难做,所以除非必要,一般来说都是采用最终一致性来规避分布式事务。
目前底层NoSQL存储系统实现分布式事务的只有Google的系统,它在Bigtable之上用Java语言开发了一个系统 Megastore,实现了两阶段锁,并通过Chubby来避免两阶段锁协调者宕机带来的问题。Megastore实现目前只有简单介绍,还没有相关论文。
2PC
实现简单,但是效率低,所有参与者需要block,throughput低;无容错,一个节点失败整个事务失败。如果第一阶段完成后,参与者在第二阶没有收到决策,那么数据结点会进入“不知所措”的状态,这个状态会block住整个事务。
3PC
改进版的2PC,把2PC的第一个段break成了两段: 询问,然后再锁资源,最后真正提交。3PC的核心理念是:在询问的时候并不锁定资源,除非所有人都同意了,才开始锁资源。
3PC比2PC的好处是,如果结点处在P状态(PreCommit)的时候发生了Fail/Timeout的问题,3PC可以继续直接把状态变成C状态(Commit),而2PC则不知所措。
不过3PC实现比较困难,而且无法处理网络分离问题。如果preCommit消息发送后两个机房断开,这时候coordinator所在的机房会abort,剩余的participant会commit。
Paxos
Paxos的目的是让整个集群的结点对某个值的变更达成一致。Paxos算法是一种基于消息传递的一致性算法。Paxos算法基本上来说是个民主选举的算法——大多数的决定会成个整个集群的统一决定。
任何一个点都可以提出要修改某个数据的提案,是否通过这个提案取决于这个集群中是否有超过半数的结点同意(所以Paxos算法需要集群中的结点是单数)。这个是Paxos相对于2PC和3PC最大的区别,在2f+1个节点的集群中,允许有f个节点不可用。
Paxos的分布式民主选举方式,除了保证数据变更的一致性之外,还常用于单点切换,比如Master选举。
Paxos协议的特点就是难,both 理解 and 实现 :(
关于2PC,3PC和Paxos,强烈推荐阅读 分布式系统的事务处理。
目前大部分支付系统其实还是在2PC的基础上进行自我改进的。一般是引入一个差错处理器,进行差错协调(回滚或者失败处理)。
MVCC:多版本并发控制
这个是很多RDMS存储引擎实现高并发修改的一个重要实现机制。具体可以参考:
Map-Reduce思想
1. 分而治之
2. 移动数据不如移动计算
如果计算节点和存储节点位于不同的物理机器则计算的数据需要通过网络传输,此种方式的开销很大。另一种思路是,将计算尽量调度到与存储节点在同一台物理机器上的计算节点上进行,这称之为本地化计算。本地化计算是计算调度的一种重要优化。
经典论文和分布式系统学习
Dynamo
HBase
LSM Tree
- LSM(Log Structured Merge Trees)是B+ Tree一种改进
- 牺牲了部分读性能,用来大幅提高写性能
- 思路:拆分树
- 首先写WAL,然后记录数据到入到内存中,构建一颗有序子树(memstore)
- 随着子树越来越大,内存的子树会flush到磁盘上(storefile)
- 读取数据:必须遍历所有的有序子树(不知数据在哪棵子树)
- Compact:后台线程对磁盘中的子树进行归并,变成大树(子树多了读得慢)
事实上,lucene的索引机制也类似HBase的LSM树。也是写的时候分别写在单独的segment,后台进行segement合并。
相关推荐
在IT行业中,Java语言因其平台无关性、丰富的库支持以及高效性能,在构建大型分布式系统方面扮演着重要角色。本文将深入探讨大型分布式系统中的Java应用,包括其核心概念、技术框架以及实现策略。 首先,我们要理解...
本文将从分布式系统测试的四个方面——测试环境、功能测试、压力测试与性能测试、自动化测试出发,详细分析分布式系统测试中的难点。 首先,分布式系统测试环境的搭建是测试的第一步,也是难点之一。分布式系统通常...
阿里巴巴的技术嘉年会上,陈鑫/神秀分享了他们在分布式系统测试方面的实践经验和策略,深入探讨了分布式系统测试的难点、自动化实践以及具体的实践经验分享。 ### 分布式系统的特点与测试要求 分布式系统的设计...
分布式系统是为了解决传统单体架构面对大规模业务和数据量时遇到的性能瓶颈问题而产生的。随着业务量的不断扩张,原本部署在同一台服务器上的应用程序、数据库和文件存储等系统会遇到性能瓶颈,尤其是在高访问量的...
总之,分布式系统的难点在于如何实现服务的解耦、通信的高效与安全、故障的快速定位和恢复,以及运维的自动化。亚马逊通过组织架构的调整、技术选型的灵活、运维文化的塑造和持续的学习改进,成功地构建了大规模的...
### 超大流量分布式系统架构解决方案概览 #### 一、引言 在当今互联网时代,随着用户规模和业务复杂度的快速增长,构建能够应对超大流量的分布式系统成为了许多企业的迫切需求。《20年IT老民工苦心编撰成超大流量...
分布式应用系统更新及实现方式,涉及了一系列与分布式系统更新机制相关的关键知识点。在理解和掌握这些知识的过程中,首先需要对分布式系统以及版本控制等基础概念有所了解。 分布式系统是指一组独立的计算机,它们...
这要求在配电系统规划和分布式系统设计中充分考虑光伏发电站的短路电流贡献,并进行相应的设备选型和改造。 第四,分布式光伏并网技术对电能质量的影响也是一个重要的技术问题。电能质量的下降主要表现在谐波和闪变...
分布式系统作为应对移动互联网和云计算时代需求的架构选择,其具备的易扩展性、高可靠性和灵活性使其成为应用软件系统的首选架构。但大型分布式系统的更新升级过程中的复杂性、耗时长以及新旧版本共存的问题,也给...
#资源达人分享计划#
分布式系统日志分析的主要技术难点包括:日志的收集与解析、日志的划分、日志特征的挖掘。日志的收集与解析需要面对日志数据量大、格式不统一、结构复杂等问题,需要高效的解析算法和存储策略。日志划分涉及到如何...
本文探讨了分布式系统在实时信号级仿真中的实现方法,涉及透明计算结构、信号特征提取与重构、以及系统性能提升等关键技术点。分布式系统由多个节点构成,各节点之间需要协同工作以实现复杂的功能。在实时仿真领域,...
为解决大规模系统中数据处理任务重,业务种类多的难点,文章给出一种基于Compact PCI(CPCI)的分布式系统设计,实现了系统板卡间的分工协作和跨总线远程内存访问。本文提出了基于“抽屉机制”的报文存储机制和地址...
从集中式系统向分布式系统的转变是复杂的过程,特别是对于银行核心交易系统来说,难点在于数据持久化层的分布式转型。核心交易系统需要从“有状态”的传统集中式架构向“无状态”特性转变,以支持分布式集群模式。...
从给定的文档标题、描述、标签以及部分内容中,我们可以提炼出关于分布式系统的基本概念、原理及相关的技术问题。以下是对这些知识点的详细解析: ### 分布式系统基础概念 #### 1. 中间件的角色 中间件在分布式...
大规模分布式系统由于其在国家安全、关键基础设施和社会生活中的日益重要性,其脆弱性分析问题已经成为当前的研究焦点。分布式系统的规模广泛部署、异质性、动态性以及无法实现集中控制等特点,使得结构脆弱性成为这...
随着不限量流量套餐的普及,4G网络的流量效益日益凸显,现有网络中的传统无源分布式系统(DAS)占比较大。因此,如何实现传统无源分布式系统面向5G的平滑演进,以适应未来通信需求的挑战,显得尤为重要。 首先,...
分布式系统是计算机科学中的核心领域,MIT的6.824课程是该领域的经典课程,旨在深入理解分布式系统的原理和实践。2020年的实验资料包含源码和运行说明书,为学生提供了一手的实践经验,帮助他们更好地掌握理论知识。...
分布式文件系统的技术难点: 1. 文件系统的可扩展性 2. 文件系统的安全性 3. 文件系统的性能 4. 文件系统的可靠性 分布式文件系统的应用前景: 1. 大规模数据存储 2. 高性能计算 3. 云计算 4. 大数据分析 分布式...