太上老君的炼丹炉之分布式 Quorum NWR

太白金星:听闻老君最近在练神丹妙药,能否与我一讲?web

太上老君:老白啊,我最近在练六颗丹药:两颗延年丹、两颗健步丹、两颗恢复丹算法

太白金星:那这三个八卦炉定是练这三件法宝的?数据库

太上老君:正是正是。并且对于相同的丹药,功效和大小还得彻底同样。小程序

三种丹药

1、三个炼丹炉怎么分配的

太白金星:老君,你的八卦炉怎么分配的啊?数组

让咱们揭开老君的炼丹炉,看看六颗丹药是怎么分配的。浏览器

首先咱们是很容易猜到丹炉是怎么分配炼丹的:缓存

  • 一号丹炉炼两颗 延年丹
  • 二号丹炉炼两颗 健步丹
  • 三号丹炉炼两颗 恢复丹
太白金星认为的丹炉状况

那如此分配会有什么问题呢?性能优化

咱们试想一下,若是一号丹炉由于炉火过高炸裂了,那么两颗延年丹定会失败。这和把鸡蛋放到一个篮子里面是一个道理。假如篮子不慎被打翻,里面的鸡蛋都掉出来,就都碎了。服务器

太上老君:老白,我把锅炉的盖子揭开给你看看你就知道了。微信

  • 一号丹炉炼一颗 延年丹和一颗 健步丹
  • 二号丹炉炼一颗 延年丹和一颗 恢复丹
  • 三号丹炉炼一颗 健步丹和一颗 恢复丹
丹炉实际分配状况

太白金星:老君,为什么要如此分配,每一个丹药的火候可不那么好把控啊?

太上老君:老白,我但是炼丹大师,火候难不倒我。

太白金星:不愧是老君啊,这样即便有一个丹炉有问题,至少能保证一颗能炼成,而不是两颗都毁了。

映射到咱们互联网系统中:丹炉相似于服务器节点或数据库节点,经过多个节点来相互备份数据来保证系统的高可用性(High Availability)。

2、如何保证丹药品质同样

2.1 一致性

太白金星:老君,你刚提到,两颗延年丹须要保证功效同样,大小同样?

太上老君:确实如此,丹药品质必须保持一致,我炼的都是九品丹药,药效差一点则是千差万别。

太上老君说的品质保持一致到底怎么回事?

一号丹炉里面的延年丹和二号丹炉的延年丹如何保证品质一致呢?

这不就是咱们经常说的分布式一致性吗?两颗丹药分布在不一样的丹炉中,须要保证品质一致。

以下图所示,这两颗延年丹的一大一小,颜色也有不一样,这就是品质不同。

品质不同

而在架构设计中,好比请求访问到不一样的数据库,查到的数据都是同样的,这就是一致性。

以下图所示:浏览器访问数据库 1 和数据库 2 中的数据 A,结果返回的都是 A = 1。

分布式系统中的一致性

2.2 最终一致性和强一致性

分布式中的一致性又分为最终一致性强一致性

所谓强一致性就是写操做完成后,任何后续访问都能读到更新后的值。这就是CP系统所要求的一致性和分区容错性。。

那放到炼丹中怎么理解?

好比老君给一号丹炉的延年丹加入了莲花这种药材,给二号丹炉的延年丹也这么操做,那么老白揭开炉盖看到的两颗延年丹的成分是同样的。

最终一致性就是不保证后续访问都能读到更新后的值,可是通过一段时间后,再去读,就能获得相同的值。也就是说,在这段时间内,可能读到旧的数据。这就是AP系统所要求的可用性和分区容错性。

放到炼丹中怎么理解?

好比老君给一号丹炉的延年丹加入了莲花,而通过了一个时辰后,才给二号丹炉加雪莲,那么在这个时辰内,看到的两颗延年丹的成分就不同了。但通过一个时辰后,最终成分同样。

3、可控的品质:Quorum NWR 协议

假如延年丹必须保证品质的强一致性,而健步丹只须要保证品质的最终一致性,这个该怎么控制呢?

这个可没有难倒老君,由于老君懂得分布式协议:Quorum NWR

Quorum 这个单词的意思:(会议的)法定人数。主要是看后面三个大写字母:NWR。由 NWR 来控制一致性。

3.1 参数 N

咱们仍是来看下丹炉中的状况,两颗延年丹是互为备份的,至关于有两个副本。

N 称做副本数,又叫作复制因子(Replication Factor)。表示同一份数据有多少个副本,因此:延年丹的 N = 2。依次类推:健步丹的 N = 2,恢复丹的 N = 2。以下图所示:

丹药的副本数同样

那 N 能够变吗?

以下图所示:好比我想炼 3 颗延年丹,也就是每一个丹炉都有延年丹,那就把 N 改为 3 就能够了。而健步丹只须要炼一颗足以,那一号丹炉炼就能够了,因此N = 1。

多个丹药的副本数不同

3.2 参数 W

指定了副本数 N 以后,就能够对副本数据进行读写操做。

  • 读操做:查看所在丹炉内丹药的状况。
  • 写操做:给丹药添加药材、提升温度。

那多个丹药该如何执行读写操做呢?对于写操做,咱们有 W 参数,对于读操做,咱们有 R 参数。

W 称为写一致性级别(Write Consistency Level),表示成功完成 W 个副本更新,才完成写操做。

好比设置延年丹的 W = 2,表示对延年丹执行写操做时,完成了 2 个副本的更新时,才完成写操做。

以下图所示:一号丹炉和二号丹炉中的延年丹都加入了莲花,而三号丹炉中的延年丹未加入莲花。也就是只完成了两个副本的更新,符合 W = 2 这个条件,即写操做完成。

两个延年丹加入了莲花

可是你们发现问题没,三号丹炉的延年丹未加入莲花,那怎么保证太上老君查看丹药状况时,得知是已加入莲花呢?也就是如何保证读写的强一致性,这就要用到第三个参数了:R。

3.3 参数 R

R 称为读一致性级别(Read Consistency Level),表示读取一个数据对象时,须要读 R 个副本,而后返回 R 个副本中最新的那份数据。

回到炼丹的问题中,设置延年丹的 R = 2,也就是查看延年丹的状况时,只须要查看两个丹炉内的延年丹的状况,而后返回最新的延年丹的状况就能够了。

  • 假设查看的是一号和二号丹炉内的延年丹,返回的状况都是:已加入莲花。这种场景是一致性的。

  • 假设查看的是一号和三号丹炉内的延年丹,一号丹炉的延年丹是已加入莲花,三号丹炉是未加入莲花,可是三号丹炉内的延年丹最后一次操做时间是早于一号丹炉的,因此返回一号丹炉内延年丹的状况:已加入莲花。这种场景也是一致性的。

经过上面的两种场景,咱们知道,经过设置 R = 2,即便读到第三份未更新的数据,也能返回更新后的数据,实现强一致性

3.4 参数组合

参数 N、W、R 的不一样组合将会带来不一样的一致性效果。

  • 好比上面的例子,N = 3,W = 2,R = 2,W + R > N,对于客户端来说,整个系统能保证强一致性,必定能返回更新后的那份数据。

  • 当 W + R <= N 时,对于客户端来说,整个系统只能保证最终一致性,访问数据期间可能会返回旧数据。

参数不一样,效果不一样,分布式系统须要根据不一样场景来配置。

4、应用

InfluxDB 企业版是时序数据库,它有四种写一致性级别:

  • any:W + R < N,W = 1,任何一个节点写入成功后,或者写入 Hinted-handoff 缓存(等下次重传),返回成功给客户端。
  • one:W + R < N,W = 1,任何一个节点写入成功后,当即返回成功给客户端,不包括写入 Hinted-handoff 缓存
  • quorum:W + R > N,大多数节点写入成功后,就返回成功给客户端。(要求 N 大于2)
  • all:W = N,全部节点都写入成功后,返回成功。

另外对于 时序数据库 InfluxDB 来讲,读操做须要读取大量数据,为了保证读取的高效,它不支持读一致性级别(R = N),可是能够经过设置写一致性级别为 all,来实现强一致性。

InfluxDb 实现了 Quorum NWR,当线上业务须要临时作些一致性调整时,设置不一样的写一致性级别便可完成快速切换。

5、总结

本文经过太上老君和太白金星关于炼丹的对话,引伸出自定义一致性的分布式协议:Quorum NWR 协议。

  • 丹炉比喻节点,丹药比做数据,多个丹药称做副本。

  • N 表明副本数,W 表明写多少个副本数,R 表明读多少个副本数。

  • 当 N 大于节点数时,就会出现一个节点存在多个副本的状况,这个节点故障时,多个副本会受到影响。

  • W + R > N 时,表明强一致性。

  • W = N 时,读性能好。R = N,写性能好。

  • W = R = (N+1)/2,容错能力好,能容忍 少数节点(也就是(N-1)/2) 个节点故障。

  • 如何设置 N、W、R 值,取决于咱们的系统该往哪方面优化。

  • Quorum NWR 分布式算法给业务提供了按需选择一致性级别的灵活度,弥补了 AP 型系统缺少强一致性的缺点。

太白金星:预祝你炼丹成功!我要去分享留言了!

- END -

做者简介:悟空,8年一线互联网开发和架构经验,用故事讲解分布式、架构设计。《JVM性能优化实战》专栏做者,开源了《Spring Cloud 实战 PassJava》项目,自主开发了一个 PMP 刷题小程序。关注可免费刷题。

我是悟空,努力变强,变身超级赛亚人!

本文分享自微信公众号 - 悟空聊架构(PassJava666)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索