网站设计如何收费,wordpress手机端发布软件,杭州企业网站建设哪家好,海南网站设计前言zookeeper当初到底面临什么问题#xff1f;而zookeeper又是如何解决这些问题的#xff1f;实际上zookeeper主要就是解决分布式环境下的一致性问题。那么解决这个问题到底有哪些难点呢#xff1f;我们一步一步来阐述和推理这个过程。分布式事务我们首先考虑一致性的特殊情…前言zookeeper当初到底面临什么问题而zookeeper又是如何解决这些问题的实际上zookeeper主要就是解决分布式环境下的一致性问题。那么解决这个问题到底有哪些难点呢我们一步一步来阐述和推理这个过程。分布式事务我们首先考虑一致性的特殊情况即分布式事务的情况。分布式事务对于一致性的要求是强一致性因此对于我们后续讨论有一定的借鉴意义。这里我们用到一个经典的例子bob给smith转账强一致性的要求一定是需要对外来说bob减钱的同时smith加钱。单机环境下是这样的简单讲就是有关bob的减钱和smith的加钱都转同一个库来做可以采用数据库的事务特性轻松支持。保证bob给smith转账的安全性。而分布式环境就变这样了假设应用服务器是Abob端的数据库是Bsmith端的数据是C那么A做成一个转账需要B事务成功提交并且C事务成功提交。然而因为网络的影响可能出现两种情况如果bob扣款成功而网络通知smith失败了则会出现bob的钱减了smith的钱没加如果bob扣款不成功而smith加钱成功了则会出现smith钱增加了但是bob的钱也没减少2PC这种不一致的问题困扰着大家。任意一边出错想要回滚另一边都不是简单的数据库回滚的事情( 因为此时已经成功提交)而是需要做业务的逆向操作而不同业务的逆操作都不同导致复杂性增加。考虑数据库事务的执行实际上是先将执行操作写入binlog等到最后通过一个commit指令将binlog的内容一次更新到表中或者写到一半通过一个rollback指令将binlog中的内容回滚。于是乎可以想到使用2个阶段来执行这个过程第一阶段写入binlog第二阶段执行commit或者rollback。这就是著名的两阶段提交协议(2PC)。如果仔细考虑会发现两阶段协议并没有解决问题只不过降低了出错的概率而已因为第二阶段同样存在上面的两种情况。注意最终状态是多台机器的状态的 结果。以下是两阶段协议的时序图考虑prepare阶段的响应(因为请求阶段和执行阶段都可以在最后响应中体现出来)对于分布式环境中任意时刻考虑3种状态成功、失败、超时。a.成功。不必处理执行后续行为commit。b.失败。这是执行阶段出错执行后续行为rollback。c.超时。这可能是执行阶段太慢也可能是网络阶段太慢或丢包但是保守处理超时可以当做出错。可以看出prepare阶段的问题能够完全避免。考虑commit阶段同样考虑成功失败超时3种状态。a. 成功。整个事务成功执行b. 失败。提交出错假设此时前面的B已经提交成功了则同样面临需要回滚B却无法回滚的问题因为B已经提交成功了。c. 超时。同上。还有一种例外情况即prepare阶段完成后A挂了则B,C即进入不知所措的状态。可以看出在2PC中事务无法做到像单机一样安全只不过降低了出问题的概率。3PC针对如何解决2PC中的例外情况出现了3阶段提交协议。3阶段的主要改进是把2阶段的prepare再分为canCommit和preCommit两个阶段。考虑cancommit阶段的响应。a.成功。不必处理执行后续行为precommit。b.失败。说明无法执行无须后续提交或回滚行为。c.超时。保守处理超时可以当做失败。考虑precommit阶段的响应。a.成功。不必处理执行后续行为docommit。b.失败。执行阶段出错执行后续行为rollback。c.超时。执行阶段太慢也可能是网络阶段太慢或丢包但是保守处理超时可以当做出错。考虑cancommit阶段的响应。a.成功。整个事务成功执行。b.失败。提交出错假设此时前面的B已经提交成功了则同样面临无法回滚的问题。c.超时。保守处理超时可以当做失败。例外情况即自cancommit返回成功后的任意阶段A挂掉了那么BC同样能够知道这个事务正在发生(因为cancommit已经提交了足够信息让BC知晓此事)于是BC可以在无A的情况下继续执行后续的阶段(比如BC投票启动新的A’并提供A’足够信息)。于是3PC正好解决了2PC的例外情况。但是3PC仍然存在类似2PC的问题即最后阶段失败或超时同样有可能出现数据不一致的问题。所以3PC仍然只是降低了发生概率并没有真正解决问题。XTS工业界的对分布式事务的应用是如何呢可以参考某宝的知名分布式框架XTS。XTS本质上是2PC(实际上如果引入3PC会多2n次网络交互在量大时反而更加不安全)。XTS引入协调者A的server部分实际上是一个大集群以配置的方式接入各种需要分布式事务的业务集群由专门的团队维护保证其可用性和性能而协调者A的client部分则通过发起方调用prepare阶段时先通过client将本次事务信息发送到server落库然后即时推送prepare请求到B和C当收到B,C的响应时把他们状态入库如果正常则做commit提交否则会用定时任务去推送未完成的状态直到完成。上文提到的prepare之后协调者A挂了这种情况在server集群的保证下几乎很少会发生。而上文提到的所有超时的情况都可以通过定时任务推送拿到一个确定的状态而不是盲目的选择回滚或者提交。另外由于B和C都是集群很少会发生多次请求过去无响应的情况。直到最后一种情况就是commit时B成功了C失败了或者反过来B失败C成功这种情况成为悬挂事务最终等待人工来解决据说每天都有几笔到几十笔。无疑XTS作为2PC在工业界的应用是相当了不起的设计通过各种方式规避了各种可能的不一致性在性能效率等方面做到了平衡。TCC(Try/Confirm/Cancel)业务补偿类型其基本思想是对每一个业务操作做一个逆操作一旦成功了就做正向业务一旦失败了就做业务的逆操作。通常在业务逻辑简单并且正逆操作清晰的时候用比较好。查询补偿典型的场景是向银行发送了转账请求未得到明确的成功失败返回码此时先做业务结果的查询根据结果做相应处理比如查询结果成功则置状态为成功查询结果失败则做相应的业务补偿查询结果为未知则继续查询。消息事务及消息重试事务消息及消息重试本质上都是将一些通用的事务交给消息中间件通过消息中间件来保证消息的最终一致性。事实上消息事务解决了这类问题即本地事务和消息应当有一致性解决这个一致性比较麻烦比如消息中间件和业务同时实现XA或者采用一些更加复杂的方式比如将消息表与业务表放同库利用数据库的事务来保证一致性而消息系统只需要轮训该消息表即可当然也有消息的二阶段提交补偿的方式。消息事务解决了消息发起方即生产者与消息中间件之间的一致性问题。try{ //数据库操作 //消息投递 }catch(Exception e){ //回滚 }消息中间件与消费者之间的一致性问题则需要通过重试幂等来解决。消息重试中主要考虑重试次数以及重试时间的阈值变化。最后我这边整理了一份Zookeeper相关资料Java核心知识点(包括Spring全家桶系列、面试专题和20年最新的互联网真题、电子书等)有需要的朋友可以私信回复【面试题】即可获取。