一文入魂!聊透分布式系统一致性


一文入魂!聊透分布式系统一致性

文章插图
作者 | bdseeker
来源 | BigData之路(ID:bigdata3186)
头图 | CSDN 下载自视觉中国
 
前言上一篇《CAP》写完之后,我又反复回看了多次,发现最后的一部分表达CAP、ACID、BASE、“BACP(自造)”关系时有一些问题,并且不是很严谨,但是无奈已经发送过的内容,无法支持修改,并且有挺多小伙伴都在私聊我确认细节,这里我来重新更新下,直接上图!
一文入魂!聊透分布式系统一致性

文章插图
也有一部分小伙伴跟我说觉得CAP有点冷门,建议我换点大众能接受的,其实我也不得不承认,大家可能更喜欢具体的技术栈 。但我从个人视角来说,这些大数据的基础知识非常重要 。等我写完大数据基础系列,会逐渐开始转战具体技术栈,莫急!大数据之路很长,我们慢慢走 。就像我每篇文章里都会提到的,相信坚持总会有所收获 。
话不多说,进入正题,在很多小伙伴认知里或多或少都知道那么两三种一致性,比如强一致性、最终一致性等 。但是你以为一致性只有这些嘛?本篇带来一致性详解,讲透一致性 。欢迎大家指正~
 
强一致性一致性大家庭中,虽然细分种类很多,但是实际上只有两大类,其中之一就是上篇《CAP》中我们已经介绍过的强一致性,其具体包含了严格一致性(也叫原子一致性或者线性一致性)和顺序一致性 。
1、严格(原子/线性)一致性
严格一致性代表着,当数据更新后,所有Client的读写都是在数据更新的基础上 。如下图所示,我们假设每份数据有三个副本,分别落到三个节点上 。当Client1尝试将X的值置为1时,严格一致性要求当Client1完成更新操作以后,所有Client都要在最新值的基础上进行读写,这里的Client10读取到的值是x=1,在同一时刻Client100的更新操作也是在x=1的基础上进行x+=1操作,在下一个时刻Client1000读到的任意一个副本,X的值都会是2 。
一文入魂!聊透分布式系统一致性

文章插图
此时你会发现一切似乎都是很完美的 。但是仔细想想,严格一致性的背后有什么潜台词呢?
数据同步复制
严格一致性代表着,所有数据在写入操作的时候是同步复制的,即写多副本都成功,才算写入成功,HDFS是不是就是最好的例子 。并且具有原子性,对于写入操作来说,结果要么写成功,要么写失败,不存在中间状态 。这也是为什么称为原子一致性的原因 。
严格一致性不考虑客户端
在网上有很多人在解释一致性时,尝试从客户端和服务端分别解析;但是在上一篇我们分析CAP的时候,也有提到不要带Client玩,那么究竟谁对谁错呢?
这里我们再来看下,在考虑分布式系统的一致性时我们更关注什么?是多个Client发送读写请求到达后端的时间和先后顺序嘛?不,我们真正关注的是每个请求,对应服务端完成时间点的先后顺序 。还是参考上面的例子,Client1000读取到x=2这个结果,实际上是以Client100这个写操作完成为基础的,如果Client100写操作一直不完成,那么强一致性要求Client1000读取到的X是1而不是2 。因此我们更需要关注的是完成操作的具体时间点,而不是操作发起的时间点,对于一致性来说考虑Client的意义就不大了 。当然在同一时刻多个Client操作的幂等性还是一定要保证的 。
换个角度,Client才是一致性需求的甲方,不是嘛 。而分布式系统端作为乙方,只能满足甲方需求,或者拒绝甲方需求,而不是要求甲方作出任何改变!
基于严格的全局时钟
上面我们提到操作行为完成时间点的顺序是十分重要的 。再仔细看一下上面举例的内容,相信你会发现一切的行为都在时间这个维度上,行为顺序是:Client1更新x=1 -> Client10读取x=1/Client100在x=1的基础上更新x+=1 -> Client1000读取x=2 。所以每个操作都是在前一个操作完成的基础上进行的,在分布式服务中,需要有一个基准时间来衡量每个操作行为的顺序 。此时你会问了,机器上不是都有NTP做时间校准嘛?现在的问题就是无法保证每一台机器的时间都是绝对相同的 。
举个例子,数据D2所在的节点相比D1节点时间提前了几秒,当Client1的更新请求完成后(用时500ms),Client10的请求开始执行并完成,如果将机器时间作为基准就会发现Client10的读取操作竟然在Client1的更新操作之前,这显然是违背强一致性的 。
我们一般我们会如何保证全局时钟?这里简单聊聊三种种常见解法 。


推荐阅读