csdn 太上老君的炼丹炉之分布式 Quorum NWR
NOTE:
一般叫做NRW
一、三个炼丹炉怎么分配的
映射到我们互联网系统中:丹炉类似于服务器节点或数据库节点,通过多个节点来相互备份数据来保证系统的高可用性
(High Availability)。
二、如何保证丹药品质一样
2.1 一致性
太上老君说的品质保持一致到底怎么回事?
一号丹炉里面的延年丹和二号丹炉的延年丹如何保证品质一致呢?
这不就是我们常常说的分布式一致性
吗?两颗丹药分布在不同的丹炉中,需要保证品质一致。
如下图所示,这两颗延年丹的一大一小,颜色也有不同,这就是品质不一样。
2.2 最终一致性和强一致性
分布式中的一致性又分为最终一致性
和强一致性
。
所谓强一致性
就是写操作完成后,任何后续访问都能读到更新后的值。这就是CP
系统所要求的一致性和分区容错性。
而最终一致性
就是不保证后续访问都能读到更新后的值,但是经过一段时间后,再去读,就能得到相同的值。也就是说,在这段时间内,可能读到旧的数据。这就是AP
系统所要求的可用性和分区容错性。
三、可控的品质:Quorum NWR 协议
Quorum NWR
假如延年丹必须保证品质的强一致性,而健步丹只需要保证品质的最终一致性,这个该怎么控制呢?
这个可没有难倒老君,因为老君懂得分布式协议:Quorum NWR
。
Quorum 这个单词的意思:(会议的)法定人数。主要是看后面三个大写字母:N
、W
、R
。由 NWR 来控制一致性。
3.1 参数 N
我们还是来看下丹炉中的情况,两颗延年丹是互为备份的,相当于有两个副本。
N 称作副本数,又叫做复制因子(Replication Factor)。表示同一份数据有多少个副本,所以:延年丹的 N = 2。依次类推:健步丹的 N = 2,恢复丹的 N = 2。如下图所示:
那 N 可以变吗?
如下图所示:比如我想炼 3 颗延年丹,也就是每个丹炉都有延年丹,那就把 N 改成 3 就可以了。而健步丹只需要炼一颗足以,那一号丹炉炼就可以了,所以N = 1。
3.2 参数 W
指定了副本数 N 之后,就可以对副本数据进行读写操作。
1、读操作:查看所在丹炉内丹药的情况。
2、写操作:给丹药添加药材、提高温度。
那多个丹药该如何执行读写操作呢?对于写操作,我们有 W 参数,对于读操作,我们有 R 参数。
W 称为写一致性级别(Write Consistency Level),表示成功完成 W 个副本更新,才完成写操作。
比如设置延年丹的 W = 2,表示对延年丹执行写操作时,完成了 2 个副本的更新时,才完成写操作。
如下图所示:一号丹炉和二号丹炉中的延年丹都加入了莲花,而三号丹炉中的延年丹未加入莲花。也就是只完成了两个副本的更新,符合 W = 2 这个条件,即写操作完成。
但是大家发现问题没,三号丹炉的延年丹未加入莲花,那怎么保证太上老君查看丹药情况时,得知是已加入莲花呢?也就是如何保证**读写的强一致性**,这就要用到第三个参数了:R。
3.3 参数 R
R 称为读一致性级别(Read Consistency Level),表示读取一个数据对象时,需要读 R 个副本,然后返回 R 个副本中最新的那份数据。
回到炼丹的问题中,设置延年丹的 R = 2,也就是查看延年丹的情况时,只需要查看两个丹炉内的延年丹的情况,然后返回最新的延年丹的情况就可以了。
1、假设查看的是一号和二号丹炉内的延年丹,返回的情况都是:已加入莲花。这种场景是一致性的。
2、假设查看的是一号和三号丹炉内的延年丹,一号丹炉的延年丹是已加入莲花,三号丹炉是未加入莲花,但是三号丹炉内的延年丹最后一次操作时间是早于一号丹炉的,所以返回一号丹炉内延年丹的情况:已加入莲花。这种场景也是一致性的。
3.4 参数组合
参数 N、W、R 的不同组合将会带来不同的一致性效果。
1、比如上面的例子,N = 3,W = 2,R = 2,W + R > N,对于客户端来讲,整个系统能保证强一致性,一定能返回更新后的那份数据。
2、当 W + R <= N 时,对于客户端来讲,整个系统只能保证最终一致性,访问数据期间可能会返回旧数据。
参数不同,效果不同,分布式系统需要场景来配置。
四、应用
InfluxDB 企业版是时序数据库,它有四种写一致性级别:
1、any:W + R < N,W = 1,任何一个节点写入成功后,或者写入 Hinted-handoff 缓存(等下次重传),返回成功给客户端。
2、one:W + R < N,W = 1,任何一个节点写入成功后,立即返回成功给客户端,不包括写入 Hinted-handoff 缓存
3、quorum:W + R > N,大多数节点写入成功后,就返回成功给客户端。(要求 N 大于2)
4、all:W = N,所有节点都写入成功后,返回成功。
另外对于 时序数据库 InfluxDB 来说,读操作需要读取大量数据,为了保证读取的高效,它不支持读一致性级别(R = N),但是可以通过设置写一致性级别为 all,来实现强一致性。
InfluxDb 实现了 Quorum NWR,当线上业务需要临时做些一致性调整时,设置不同的写一致性级别即可完成快速切换。
五、总结
本文通过太上老君和太白金星关于炼丹的对话,引申出自定义一致性的分布式协议:Quorum NWR 协议。
1、丹炉比喻节点,丹药比作数据,多个丹药称作副本。
2、N 代表副本数,W 代表写多少个副本数,R 代表读多少个副本数。
3、当 N 大于节点数时,就会出现一个节点存在多个副本的情况,这个节点故障时,多个副本会受到影响。
4、W + R > N 时,代表强一致性。
5、W = N 时,读性能好。R = N,写性能好。
NOTE:
read、write tradeoff
6、W = R = (N+1)/2,容错能力好,能容忍 少数节点(也就是(N-1)/2) 个节点故障。
NOTE:
此时W+R>N,显然能够保证strong consistency
7、如何设置 N、W、R 值,取决于我们的系统该往哪方面优化。
8、Quorum NWR 分布式算法给业务提供了按需选择一致性级别的灵活度,弥补了 AP 型系统缺乏强一致性的缺点。