北京响应式网站建设推荐,北京装修公司口碑最好的是哪家,百科网站推广,青岛官网优化收费标准前言一致性#xff1a;很多时候表现在IT系统中#xff0c;通常在分布式系统中#xff0c;必须#xff08;或最终#xff09;为多个节点的数据保持一致。世间万物#xff0c;也有存在相同的特征或相似#xff0c;比如儿时的双胞胎#xff0c;一批工厂流水线的产品#… 前言一致性很多时候表现在IT系统中通常在分布式系统中必须或最终为多个节点的数据保持一致。世间万物也有存在相同的特征或相似比如儿时的双胞胎一批工厂流水线的产品当然我们不去讨论非IT以外的知识点。注我们一定要明白一个词叫“信息不对称”不论是人、事、物信息不对称是永远都存在的要知道在IT系统中能引起信息不对称的因素有很多比如网络上有丢包、有延迟。硬件上有不同性能的计算能力和处理能力。在传统的IT时代一致性通常是指强一致性比如一个单体的WEB程序中从数据库到缓存再到呈现出来的界面数据均是相同的而在现在的互联网时代特别是分布式架构下一致性的含义远远超出她原有的含义由于互联网的特点信息量巨大每个人或者不同的每个业务获取到的信息不对称最终都会造成不一致。换句话说传统的单体应用无法满足巨大的信息量而转向为多节点、多服务的分布式架构模型正如CPU从单核变为多核来支撑更多的计算能力多个服务多节点必然会产生数据不一致的问题正如虽然人多力量大可如果每个人都往不同方向使劲这个力量就是分散的不一致的没有任何作用的所以我们需要管理需要告诉每个人使劲的方向告诉每个人的排列顺序等等一系列有效的分配和管理于是乎我们将这个话题转化为互联网思维就是“拆”非拆迁办。我们很多时候都在讨论这个程序如何拆分比如拆成业务层、数据层、提供层、UI层、缓存层等等而每一层的部署大部分情况下都不会存在于一个相同的宿主中否者怎么还叫拆这样称为水平拆分或横向拆分将这些不同的层部署成多个节点多个节点如果具有相同的一致性功能那么再组成一个服务域这样把这个服务域作为一个处理中心在处理能力和计算能力上远远会超过单体程序的整体性能。这样的优势显而易见但是最大的问题不能说是缺点是由于拆分后的系统或者服务化的系统存在多个元功能模块或者一个服务域中的多个节点如何去保证她们数据的一致呢提出问题直接用A,B,C等等常规化表述形式去描述不一致问题网上文章很多我们尝试换一种方式以实际的、你我都会接触到的现实场景来理解不同情况下所产生的不一致问题。Q1.生活案例意愿假如别假如了就拿笔者来说吧。当初跟妻子去买婚戒的时候只想买个一般的对戒便可因为日后的日子里用钱的地方太多相信任何一个已婚男士都有这种体会可妻子喜欢那种布灵布灵的要知道这种布灵布灵的可比一般的要贵出许多许多那么这个不一致就开始形成了你的意愿和她的意愿并没保持一致日后生活问题会越来越大。当然这只是一个几年前的例子显然我妻子已经接受了我当初的观点。Q2.银行案例转账转账是不一致案例中最经典的例子。这么来说假如你想通过某个平台比如支付宝、微信、银行进行转账这个平台的流程是这样的首先减去你账户上的余额然后加到你指定账户上去。如果平台减去你的账户余额成功了而增加其他账户的的余额失败了那么你将损失这笔钱如果减去你的账户余额失败而增加其他账户的余额成功那么银行将损失这笔钱这种资金上的不一致是绝不允许存在否则这个平台将面临破产和倒闭。Q3.常见案例下单和扣库存不管是电商还是企业仓库都会存在一个经典案例。比如你在某个界面上进行了下单比如她显示的库存是100件而你订购了1件并支付了应该的费用可是这个库存数量并未任何变化那么如果有101个人前来购买那么会出现超卖的情况也就是这多出来的1个人将买不到这件商品这就是下单和库存不一致所导致的。反之永远下单不成功而库存却在减少这对企业来说都是增加运营成本的。Q4.常见案例掉单掉单一般常见于协作工作的系统的流程中分别对彼此的上游和下游。比如上面的案例你已成功下单并支付按照流程平台应该告诉物流我有物品需要配送过来取单可物流终究收不到这个收单请求导致物品配送失败严重会导致赔付这样的不一致性通常是一个系统中的两个请求不一致而造成的。Q5.系统案例系统状态这个案例跟上面的掉单案例类似只是需要区分引起这个掉单的原因其实就是两个系统的状态不一致所造成。比如上游及时收到请求并响应而下游却因为某个状态原因而没响应这个请求最终导致不一致形成。Q6.系统案例本地缓存和数据库现在存储都依赖于数据库而关系型数据库都具备ACID特性但是在大规模高并发的互联网系统里一些特殊的场景对读的性能要求极高为止服务在这个上面的数据库将难以抗住大规模的读流量为了应对这样的问题一般都会在数据库前增加缓存那么缓存和数据库之间的数据是如何保持一致是需要强一致还是若一致Q7.系统案例节点缓存一个服务域上的多个节点为了满足较高的性能要求需要使用到本地缓存使用了本地缓存每个节点都会有一份缓存数据的拷贝如果这些数据是静态的、不变的那永远都不会有任何问题。但如果这些数据是动态的、经常更新的。那么问题就来了当被更新的时候各个节点的更新都会存在先后顺序而正是这先后顺序的一瞬间各个节点的数据将会不一致。想象一个高流量读的场景中一个请求拿到的数据是1而另一个请求拿到的是0这将导致灾难性的后果。Q8.系统案例超时服务化的系统间调用常常因为网络问题导致系统间调用超时这是在即便在网络最好的机房下、在上亿次的前提下同步调用超时也是必然会存在的正如上面提到的不同状态类似假如当下单和物流存在极高请求的情况下物流并未及时反馈响应而下单却并不知道物流是否已经接到订单或者定已收到订单只是掉包了等现象这样的不一致也是会导致灾难性后果的。解决模型对于Q1问题我们可以有两套方案一是不结了不过显然这是行不通的二是慢慢的补偿先买个一般的等手头资金充裕了或者某天中了500万或者天上掉个金块再给她个惊喜于是这个问题解决了大家的意愿都一致了都开心了。可见这样的解决模式会存在一个现象---过渡时期当这个过渡时期到最终双方都达成一致时问题就解决了。因此我们不能要求在买对戒的时候双方都达到强一致的要求生活是必须要过下去的不可能说散就散那么我们要考虑去补偿她尽最大的努力达到最终一致。在化学单词中“ACID”是酸我想这绝对不是巧合原文可参考百科image form Wilfred Springer,因此数据库会从一个明确的状态到另外一个明确的状态中间的临时状态是不会出现的EF的追踪功能也正是遵循这个原则进行设计任何一个操作状态在中途是不会存在改变如果出现改变将会给你提示错误当然你可以关掉它不过这样EF的核心点就不存在了。A: Atomicity原子性C: Consistency一致性I: Isolation隔离性D: Durability持久性回到Q2和Q3的问题上使用关系型数据库可以解决这样的强一致性需求然而单纯通过强一致性的数据库去面对不断拆分的元组是难以满足互联网高流量的需求的或许你会说使用服务器固态硬盘和读写分离的模式去应对但这绝对只是一个应对方案而已。因此在拆分的时候尽量把转账的相关账户放入一个数据库分片而Q3上把订单和存库放入一个分片因为中途不会存在任何改变从0到100必须保证任何状态都是原始的初始状态。但是我们就Q2假设另外一个场景假设账户的数量巨大对账户存储进行了拆分关系型数据库分为8个实例每个实例8个库每个库8张表共512张表假如转账的账户正好在一个库里这个问题依赖关系型数据库的事务来保持强一致性但是如果两个账户在不同的库里这个事务就无法封装在同一个数据库中的这样就会发生一个账户扣款成功而另外一个库的账户增加失败的情况。帽子理论证明任何分布式系统同时只可满足两点没法三者兼顾。CConsistency一致性, 数据一致更新所有数据变动都是同步的AAvailability可用性, 好的响应性能完全的可用性指的是在任何故障模型下服务都会在有限的时间处理响应PPartition tolerance分区容错性可靠性关系型数据库由于关系型数据库是单节点的因此不具有分区容错性但是具有一致性和可用性而分布式的服务化系统都需要满足分区容错性那么我们必须在一致性和可用性中进行权衡具体表现在服务化系统处理的异常请求在某一个时间段内可能是不完全的但是经过自动的或者手工的补偿后达到了最终的一致性。 而BASE理论的提出解决了CAP在分布式系统中的一致性和可用性不可兼得的问题。“BASE”在化学单词中是指碱因此我们可以想到一个词语叫“酸碱平衡”而在实际的场景中我们可以分别使用ACID和BASE来解决分布式服务化系统的一致性问题。BASE理论与ACID理论完全不同她满足CAP理论通过牺牲强一致性而获得可用性一般应用在服务化系统的应用层通过达到最终一致性来尽量满足不同业务上的需求。BABasically Available基本可用SSoft State软状态状态可以有一段时间不同步EEventually Consistent最终一致最终数据是一致的就可以了而不是时时保持强一致按照BASE模型实现的系统由于不保证强一致性系统在处理请求的过程中可以存在短暂的不一致状态。系统在做每一步操作的时候通过记录每一个临时状态在系统出现故障的时候可以从这些临时状态中继续完成未完成的请求处理或者回退到原始状态最后达到一致的状态。例如Q1的转账状态为例我们把两个账户的转账情况粗分为四个状态第一个状态为准备状态用户准备向另外一个进行用户转账第二个状态为扣额状态系统将从转账用户中扣去相应余额第三个状态为加额状态系统将从收款用户中增加相应余额第四个状态为完成状态系统转账完成后的确认在这过程中系统需要将每一步的操作状态都进行记录一旦某个环节出现故障系统能够发现故障环节并继续完成未完成的任务最终完成任务达到一致的最终状态。在实际的业务生产环境中通常每个阶段的状态都是通过持久化的执行任务一旦出现了问题定时任务会检查未完成的任务继续执行未完成的任务直到执行完成为止再或者该状态是属于取消状态跟数据库事务执行方式一样那么这个过程中已经完成的状态应该回滚到原始状态整个过程还可以细化到如下更加详细实际转账流程不过由于这种方法在每个状态执行的时候都需要记录下来而且需要更新数据库中的状态信息一旦在大规模高并发下性能将会是一个严重的瓶颈。总结如果钱不是问题那么最最简单的方式是使用向上扩展利用强悍的硬件性能来运行专业的关系数据库能否保证强一致性比如Orcele和DB2这样符合工业标准的数据库。如果钱是个问题那么相关的数据分到数据库的同一个分片能够保证使用关系型数据库实现强一致性比如Mysql。如果是业务限制无法将相关的数据分到同一个片就需要实现最终一致性通过记录事务的状态来判断一旦处理不一致可通过自动化如定时或者人工干预来继续执行并修复不一致的情况。下一篇我们再多介绍一下一致性的更多具体实现方案。参考《浅析分布式一致性模型》http://loopjump.com/distributed_consistency_model/原文地址https://www.cnblogs.com/SteveLee/p/About_The_Distributed_Consistency.html.NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com