分布式设计与开发中有些疑难问题必须借助一些算法才能解决,好比分布式环境一致性问题,感受如下分布式算法是必须了解的(随着学习深刻有待添加): html
Paxos算法 ios
1)问题描述
算法
分布式中有这么一个疑难问题,客户端向一个分布式集群的服务端发出一系列更新数据的消息,因为分布式集群中的各个服务端节点是互为同步数据的,因此运行完客户端这系列消息指令后各服务端节点的数据应该是一致的,但因为网络或其余缘由,各个服务端节点接收到消息的序列可能不一致,最后致使各节点的数据不一致。举一个实例来讲明这个问题,下面是客户端与服务端的结构图: apache
当client一、client二、client3分别发出消息指令A、B、C时,Server1~4因为网络问题,接收到的消息序列就可能各不相同,这样就可能因为消息序列的不一样致使Server1~4上的数据不一致。对于这么一个问题,在分布式环境中很难经过像单机里处理同步问题那么简单,而Paxos算法就是一种处理相似于以上数据不一致问题的方案。 网络
2)算法自己 框架
算法自己我就不进行完整的描述和推导,网上有大量的资料作了这个事情,但我学习之后感受莱斯利·兰伯特(Leslie Lamport,paxos算法的奠定人,此人如今在微软研究院)的Paxos Made Simple 是学习paxos最好的文档,它并无像大多数算法文档那样搞一堆公式和数学符号在那里吓唬人,而是用人类语言让你搞清楚Paxos要解决什么问题,是如何解决的。这里也借机抨击一下那些学院派的研究者,要想让别人承认你的成果,首先要学会怎样让大多数人乐于阅读你的成果,而这个描述Paxos算法的文档就是咱们学习的榜样。 分布式
言归正传,透过Paxos算法的各个步骤和约束,其实它就是一个分布式的选举算法,其目的就是要在一堆消息中经过选举,使得消息的接收者或者执行者能达成一致,按照一致的消息顺序来执行。其实,以最简单的想法来看,为了达到大伙执行相同序列的指令,彻底能够经过串行来作,好比在分布式环境前加上一个FIFO队列来接收全部指令,而后全部服务节点按照队列里的顺序来执行。这个方法固然能够解决一致性问题,但它不符合分布式特性,若是这个队列down掉或是不堪重负这么办?而Paxos的高明之处就在于容许各个client互不影响地向服务端发指令,大伙按照选举的方式达成一致,这种方式具备分布式特性,容错性更好。 工具
说到这个选举算法自己,能够联想一下现实社会中的选举,通常说来都是得票者最多者获胜,而Paxos算法是序列号更高者获胜,而且当尝试提交指令者被拒绝时(说明它的指令所占有的序列号不是最高),它会从新以一个更好的序列参与再次选举,经过各个提交者不断参与选举的方式,达到选出大伙公认的一个序列的目的。也正是由于有这个不断参与选举的过程,因此Paxos规定了三种角色(proposer,acceptor,和 learner)和两个阶段(accept和learn),三种角色的具体职责和两个阶段的具体过程就见Paxos Made Simple ,另一个国内的哥们写了个不错的PPT ,还经过动画描述了paxos运行的过程。不过仍是那句话不要一开始就陷入算法的细节中,必定要多想一想设计这些游戏规则的初衷是什么。 oop
Paxos算法的最大优势在于它的限制比较少,它容许各个角色在各个阶段的失败和重复执行,这也是分布式环境下常有的事情,只要大伙按照规矩办事便可,算法的自己保障了在错误发生时仍然获得一致的结果。 学习
3)算法的实现
Paxos的实现有不少版本,最有名的就是google chubby ,不过看不了源码。开源的实现可见libpaxos 。另外,ZooKeeper 也基于paxos解决数据一致性问题,也能够看看它是若是实现paxos的。
4)适用场景
弄清楚paxos的前因后果后,会发现它的适用场景很是多,Tim有篇blog《Paxos在大型系统中常见的应用场景》 专门谈这个问题。我所见到的项目里,naming service是运用Paxos最广的领域,具体应用可参考ZooKeeper
一致性Hash算法
1)问题描述
分布式经常用Hash算法来分布数据,当数据节点不变化时是很是好的,但当数据节点有增长或减小时,因为须要调整Hash算法里的模,致使全部数据得从新按照新的模分布到各个节点中去。若是数据量庞大,这样的工做经常是很难完成的。一致性Hash算法是基于Hash算法的优化,经过一些映射规则解决以上问题
2)算法自己
对于一致性Hash算法自己我也不作完整的阐述,有篇blog《一致性hash算法 - consistent hashing》 描述这个算法很是到位,我就不重复造轮子了。
实际上,在其余设计和开发领域咱们也能够借鉴一致性Hash的思路,当一个映射或规则致使有难以维护的问题时,能够考虑更一步抽象这些映射或规则,经过规则的变化使得最终数据的不变。一致性hash实际就是把之前点映射改成区段映射,使得数据节点变动后其余数据节点变更尽量小。这个思路在操做系统对于存储问题上体现不少,好比操做系统为了更优化地利用存储空间,区分了段、页等不一样纬度,加了不少映射规则,目的就是要经过灵活的规则避免物理变更的代价
3)算法实现
一致性Hash算法自己比较简单,不过能够根据实际状况有不少改进的版本,其目的无非是两点:
实现这个算法就技术自己来讲没多少难度和工做量,须要作的是创建起你所设计的映射关系,无需借助什么框架或工具,sourceforge上却是有个项目libconhash ,能够参考一下
以上两个算法在我看来就算从不涉及算法的开发人员也须要了解的,算法其实就是一个策略,而在分布式环境经常须要咱们设计一个策略来解决不少没法经过单纯的技术搞定的难题,学习这些算法能够提供咱们一些思路。