12 | Quorum NWR算法:想要灵活地自定义一致性,没问题!
12 | Quorum NWR算法:想要灵活地自定义一致性,没问题!
讲述:于航
时长09:29大小8.69M
Quorum NWR 的三要素
如何实现 Quorum NWR?
内容小结
课堂思考
赞 16
提建议
精选留言(38)
- 沈伟敏2020-04-03AP系统之上通过Quorum NWR实现了强一致性,这个是不是违背了“CAP不可能三角”。这个要怎么理解呢?
作者回复: 加一颗星:),不违背,这么理解,尽管通过N、W、R组合,可以实现不同的一致性级别,但对于同一份数据而言,CP和AP是不可兼得。
共 7 条评论19 - 姜川2020-03-26如果我们用raft协议的最终一致性来做整个系统的核心协议,这时出现了要强一致的需求,我们就可以不改变raft协议的前提下,引入NWR,raft协议已经保证了W是超过半数以上的,那我们就让R也超过半数以上,就能保证基于raft协议还能做出强一致性的需求了,或者改动raft协议,让其可以拥有配置写ALL的能力也可以
作者回复: 加一颗星:),理论上是可以的,但在实际中,没必要,因为我们在领导者节点上执行读操作,就能实现强一致性了。
共 2 条评论15 - 竹马彦四郎的好朋友影...2020-05-05"当 W + R > N 的时候,对于客户端来讲,整个系统能保证强一致性,一定能返回更新后的那份数据。" 顿时明白了韩老师在本文开头说的 "Werner Vogels 提出的客户端侧一致性模型,不是指线性一致性" 确实,图1中的AP系统其实并没有实现线性一致性,但是该AP系统实现了客户端侧一致性模型。展开
作者回复: 加一颗星:),最最大部分场景,都不需要“eactly once”的线性一致性,只要能保证写操作完成后,就能一直和持续读取到新数据,就可以了。
9 - 右耳听海2020-03-14老师能讲下为什么w+r>n时是强一致性的吗
作者回复: 本质上是因为这是不管怎么读,都能读取到已更新的那个副本,比如你这么想,三节点集群(n为3),写一致性级别(w)为3,读一致性级别(r)为1,也就是说,只要写成功了,所有的副本都是成功更新过的,这时不管读取哪个节点,都能读取到最新的数据。
共 5 条评论8 - Michael Tesla2020-05-31老师,写入 W 个节点失败,有可能有脏数据残留,是不是需要使用分布式事务呢?
作者回复: 加一颗星:),不需要的,实现操作的冥等性和状态机,就可以了,比如,“SET X = 1”,因为重试,最终提交了2次,那么,经过状态机的运算后,最终的X值还是1。
共 3 条评论8 - kylexy_08172020-04-26联想起另一门视频课程,MongoDB,好像也是采取Quorum NWR算法实现数据强一致性^_^
作者回复: 加一颗星:),writeConcern/readConcern原理与这个类似。
6 - 每天晒白牙2020-03-09关于思考题,老师在文中提到的资料有一些参考点: 在需要提供高性能和高可用性的分布式存储系统中,副本的数量即 n 通常超过 2 个。 只关注容错的系统通常使用 n=3 (W=2和R=2配置)。 需要提供非常高读取负载的系统通常会复制超出容错要求的数据
作者回复: 加一颗星:)
5 - 小晏子2020-03-09我理解课后思考的问题是”为什么只需要备份数据到部分节点,不需要备份到所有节点“,因为是AP系统,所以为了提升效率,备份数据到N个副本就可以认为是数据写入成功了,整个系统因为是最终一致性,系统内部会异步同步节点之间的数据,所以最终所有节点上的数据肯定会一致的,另外工程实践里N>=3, 是因为冗余数据是保证可靠性的手段,如果N=2,那么损失一个节点就退化为单节点了。
作者回复: 加一颗星:),一般2副本或3副本,就可以了。
4 - fy2020-09-03问个问题,假设322配置,第一次写入只成功了一个节点,返回客户端错误,这时候有个读取操作,刚好获取到了上一次写入成功的那一个副本,然后返回了这份数据,那不是和之前的操作结果矛盾了么
作者回复: 加一颗星:),是存在这个现象,此时能保证“写成功后,一定能读取到更新后的值”,但不能保证“写失败,只能读取到之前的值”,如果需要实现这一点,咱们需要实现事务,也就是说,当咱们在实现系统时,需要根据场景特点选择适合的技术。
共 3 条评论3 - longyi2020-03-09老师,你在文中提到”读取指定数据时,要读 R 副本,然后返回 R 个副本中最新的那份数据” ,问题是我们怎么去判断那个副本是最新的呢?
作者回复: 加一颗星:),比如版本号、时间戳等。
共 3 条评论3 - 约书亚2020-03-09每次写入数据都要产生对应版本号是吧
作者回复: 加一颗星:),取决于场景,比如,KV数据就需要,而时序数据不需要,因为一条时序数据记录是没有“新旧”之说的。
3 - 侧耳倾听2020-04-15明白老师的意思了,系统已经在运行,副本数和写入数都是已定的,理论上不能动态调整的,所以我们只能调整R来实现强一致性,实时读取最新数据,所以我们只需要在新的功能里计算好R的数目,然后接入存储系统读取数据,然后在本地通过版本号或者日期取最新数据即可。
作者回复: 加一颗星:),赞。我再补充下,W也是可以动态调整的,为什么呢?因为W表示的是,完成一个写操作,需要同时成功更新多少个副本,比如N为3,W为1,3副本,肯定是需要更新3个副本的,但W为1,也就是说,只要我们完成了一个副本的更新,就可以返回写成功给客户端。另外,如果此时R为1,则实现的是最终一致性,会读到旧数据,但最终会读到新数据。
2 - 艾瑞克小霸王2020-03-09这里的一个节点的意思是不是一个raft集群? 采用多个raft集群做数据分片和多副本?
作者回复: 加一颗星:),节点指的就是服务器节点,这是个新算法,和Raft没有关系呢。
2 - Bryant.C2020-09-04我理解Kafka是不是也不支持读一致性级别,通过ack为-1设置强一致
作者回复: 加一颗星:),这个机制类似写一致性级别。
共 2 条评论1 - 月迷津渡2020-03-23这篇核心写的很清晰,我有个小问题,关于W和R的平衡当中提到要写优化就要R=N,W=1 这样就满足W+R>N,对于这个W=1是会变吗就是不同数据可以写到不同节点 但是还是满足W=1,因为我在考虑当这个持有数据的唯一节点挂了,那节点所持有数据就不可修复了吧。所以后面提到读大多数和写大多数节点是一种满足容错的配置。 另外我想到如果集群中某个节点挂了的话N会动态变化吗?因为节点挂了就意味着数据不可用在机器网络或硬件坏掉的情况下数据也无法恢复到其他新启动节点?我记得mongo里就是配置readConcern和WriteConcern就是用的majortiy 这种感觉就是应对节点变化的一种策略(动态大多数而并非指定指定一个固定的值)吧。展开
作者回复: 加一颗星:),一般而言,N不需要动态的,故障只是偶尔发生的,而且能很快修复的,我们需要考虑的是,如果在故障发生时,保证系统的稳定运行,“读大多数、写大多数”是能实现这点的。
共 3 条评论1 - 吴小智2020-03-19按需求配置,再好不过了
作者回复: 加一颗星:)
1 - 彦2020-03-18进行R操作时,R>2,读出的数据怎么知道哪个数据是最新的呢?时序数据库里面本来带了时间戳,可以靠这个判断,但还是需要保障整个系统时序一致,其他非时序系统怎么办?
作者回复: 加一颗星:),加个时间戳。
共 3 条评论1 - 一步2020-03-15influxdb 不是国产的开源时序数据库吗? 为什么没有找中文文档呢?
作者回复: 美国的,可考虑科学上网,培养阅读英文文档的习惯:),坚持下来,会收获很大。
1 - iron_man2020-03-10any:任何一个节点写入成功后,或者接收节点已将数据写入 Hinted-handoff 缓存(也就是写其他节点失败后,本地节点上缓存写失败数据的队列)后,就会返回成功给客户端。 这里“本地节点上缓存写失败数据的队列“是什么意思,不太明白,是指缓存备份吗?本地缓存写失败了再写到这个缓存里面?
作者回复: 加一颗星:),是的,用于失败重传的缓存备份,也就是,如果写远程节点失败了,将数据缓存下来,然后再重传。
共 3 条评论1 - qinsi2020-03-09W+R=N时应该也是最终一致吧
作者回复: 是的
共 5 条评论1