关于Paxos 幽灵复现问题的看法

由于郁白之前写的关于Multi-Paxos 的文章流传非常广, 原文提出了一个叫"幽灵复现" 的问题, 认为这个是一个很诡异的问题, 后续和很多人交流关于一致性协议的时候, 也经常会提起这个问题, 但是其实这个问题我认为就是常见的"第三态"问题加了一层包装而已.

幽灵复现问题

来自郁白的博客:

使用Paxos协议处理日志的备份与恢复,可以保证确认形成多数派的日志不丢失,但是无法避免一种被称为“幽灵复现”的现象,如下图所示:

 LeaderABC
第一轮A1-101-51-5
第二轮B宕机1-6,201-6,20
第三轮A1-201-201-20
  1. 第一轮中A被选为Leader,写下了1-10号日志,其中1-5号日志形成了多数派,并且已给客户端应答,而对于6-10号日志,客户端超时未能得到应答。
  2. 第二轮,A宕机,B被选为Leader,由于B和C的最大的logID都是5,因此B不会去重确认6-10号日志,而是从6开始写新的日志,此时如果客户端来查询的话,是查询不到6-10号日志内容的,此后第二轮又写入了6-20号日志,但是只有6号和20号日志在多数派上持久化成功。
  3. 第三轮,A又被选为Leader,从多数派中可以得到最大logID为20,因此要将7-20号日志执行重确认,其中就包括了A上的7-10号日志,之后客户端再来查询的话,会发现上次查询不到的7-10号日志又像幽灵一样重新出现了。

对于将Paxos协议应用在数据库日志同步场景的情况,幽灵复现问题是不可接受,一个简单的例子就是转账场景,用户转账时如果返回结果超时,那么往往会查询一下转账是否成功,来决定是否重试一下。如果第一次查询转账结果时,发现未生效而重试,而转账事务日志作为幽灵复现日志重新出现的话,就造成了用户重复转账。

为了处理“幽灵复现”问题,我们在每条日志的内容中保存一个generateID,leader在生成这条日志时以当前的leader ProposalID作为generateID。按logID顺序回放日志时,因为leader在开始服务之前一定会写一条StartWorking日志,所以如果出现generateID相对前一条日志变小的情况,说明这是一条“幽灵复现”日志(它的generateID会小于StartWorking日志),要忽略掉这条日志。

第三态问题

第三态问题也是我们之前经常讲的问题, 其实在网络系统里面, 对于一个请求都有三种返回结果

  1. 成功
  2. 失败
  3. 超时未知

前面两种状态由于服务端都有明确的返回结果, 所以非常好处理, 但是如果是第三种状态的返回, 由于是超时状态, 所以服务端可能对于这个命令是请求是执行成功, 也有可能是执行失败的, 所以如果这个请求是一个写入操作, 那么下一次的读取请求可能读到这个结果, 也可能读到的结果是空的

就像在 raft phd 那个论文里面说的, 这个问题其实是和 raft/multi-paxos 协议无关的内容, 只要在分布式系统里面都会存在这个问题, 所以大部分的解决方法是两个

  1. 对于每一个请求都加上一个唯一的序列号的标识, 然后server的状态机会记录之前已经执行过序列号. 当一个请求超时的时候, 默认的client 的逻辑会重试这个逻辑, 在收到重试的逻辑以后, 由于server 的状态机记录了之前已经执行过的序列号信息, 因此不会再次执行这条指令, 而是直接返回给客户端
  2. 由于上述方法需要在server 端维护序列号的信息, 这个序列号是随着请求的多少递增的, 大小可想而知(当然也可以做一些只维护最近的多少条序列号个数的优化). 常见的工程实现是让client 的操作是幂等的, 直接重试即可, 比如floyd 里面的具体实现

那么对应于raft 中的第三态问题是, 当最后log Index 为4 的请求超时的时候, 状态机中出现的两种场景都是可能的

所以下一次读取的时候有可能读到log Index 4 的内容, 也有可能读不到, 所以如果在发生了超时请求以后, 默认client 需要进行重试直到这个操作成功以后, 接下来才可以保证读到的写入结果. 这也是工程实现里面常见的做法

对应于幽灵问题, 其实是由于6-10 的操作产生了超时操作, 由于产生了超时操作以后, client 并没有对这些操作进行确认, 而是接下来去读取这个结果, 那么读取不到这个里面的内容, 由于后续的写入和切主操作有重新能够读取到这个6-10 的内容了, 造成了幽灵复现, 导致这个问题的原因还是因为没有进行对超时操作的重确认.

回到幽灵复现问题

那么Raft 有没有可能出现这个幽灵复现问题呢?

其实在早期Raft 没有引入新的Leader 需要写入一个包含自己的空的Entry 的时候也一样会出现这个问题

Log Index 4,5 客户端超时未给用户返回, 存在以下日志场景

然后 (a) 节点宕机, 这个时候client 是查询不到 Log entry 4, 5 里面的内容

在(b)或(c) 成为Leader 期间, 没有写入任何内容, 然后(a) 又恢复, 并且又重新选主, 那么就存在一下日志, 这个时候client 再查询就查询到Log entry 4,5 里面的内容了

那么Raft 里面加入了新Leader 必须写入一条当前Term 的Log Entry 就可以解决这个问题, 其实和之前郁白提到的写入一个StartWorking 日志是一样的做法, 由于(b), (c) 有一个Term 3的日志, 就算(a) 节点恢复过来, 也无法成了Leader, 那么后续的读也就不会读到Log Entry 4, 5 里面的内容

那么这个问题的本质是什么呢?

其实这个问题的本质是对于一致性协议在recovery 的不同做法产生的. 

也就是说对于一个在多副本里面未达成一致的Log entry, 在Recovery 需要如何处理这一部分未达成一致的log entry.

对于这一部分log entry 其实可以是提交, 也可以是不提交, 因为会产生这样的log entry, 一定是之前对于这个client 的请求超时返回了.

常见的Multi-Paxos 在对这一部分日志进行重确认的时候, 默认是将这部分的内容提交的, 也就是通过重确认的过程默认去提交这些内容

而Raft 的实现是默认对这部分的内容是不提交的, 也就是增加了一个当前Term 的空的Entry, 来把之前leader 多余的log 默认不提交了, 幽灵复现里面其实也是通过增加一个空的当前Leader 的Proposal ID 来把之前的Log Entry 默认不提交

所以这个问题只是对于返回超时, 未达成一致的Log entry 的不同的处理方法造成的.

在默认去提交这些日志的场景, 在写入超时以后读取不到内容, 但是通过recovery 以后又能够读取到这个内容, 就产生了幽灵复现的问题

但是其实之所以会出现幽灵复现的问题是因为在有了一个超时的第三态的请求以后, 在没有处理好这个第三态请求之前, 出现成功和失败都是有可能的.

所以本质是在Multi-Paxos 实现中, 在recovery 阶段, 将未达成一致的Log entry 提交造成的幽灵复现的问题, 本质是没有处理好这个第三态的请求.

 

一站式开发者服务,海量学习资源0元起!
阿里热门开源项目、机器学习干货、开发者课程/工具、小微项目、移动研发等海量资源;更有开发者福利Kindle、技术图书幸运抽奖,100%中--》https://www.aliyun.com/acts/product-section-2019/developer?utm_content=g_1000047140

原文链接
本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/519455.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

idea spring boot 修改 html,js 等不用重启即时生效

1、【File】-【Settings】-【Build,Execution,Deplyment】-【Compiler】,选中打勾 Build project automatically 2、 组合键:ShiftCtrlAlt/,选择 Registry ,选中打勾 compiler.automake.allow.when.app.running” 3、找到你要运…

阿里巴巴微服务开源项目盘点(持续更新)

大前端、微服务、数据库、更多精彩,尽在开发者分会场 【Apache Dubbo】 Apache Dubbo 是一款高性能、轻量级的开源Java RPC框架,是国内影响力最大、使用最广泛的开源服务框架之一,它提供了三大核心能力:面向接口的远程方法调用&…

100行Python代码理解深度学习关键概念:从头构建恶性肿瘤检测网络

在构建乳腺癌预测神经网络过程中,我们主要分为3大部分: 1.用Python从零开始创建一个神经网络,并使用梯度下降算法训练模型。 2.在该神经网络中使用威斯康星乳腺癌数据集,根据9种不同的特征,预测肿瘤是良性还是恶性的…

开发者在行动!中国防疫开源项目登上 GitHub TOP 榜

用开发者们的方式支援这场没有硝烟的战争!整理 | 唐小引出品 | CSDN(ID:CSDNnews)截止北京时间 1 月 28 日下午 15:47,全国确诊新型冠状病毒的数字已经到达了 4586 例,疑似高达 6973 例,医护人员…

自动化测试|录制回放效果差异检测

概述 回归测试是指修改了旧代码后,重新进行测试以确认修改没有引入新的错误或导致其他的代码出现错误。传统的自动化回归测试需要手动编写脚本获得页面元素的视图树,与原有的元素视图树进行比对。当功能进行频繁迭代时,测试同学维护这些视图…

为什么我学了6个月Python,还是找不到工作?

在知乎上有一个特别火的问题:为什么学了Python,我还是找不到工作?有人说Python语言不行,有人说中国Python根本就没公司用。在大家群嘲的背后,我们来分析一下:为什么大家都不看好Python?学Python…

阿里工程师养了只“二哈”,专治讨厌的骚扰电话

前几天的3.15晚会上曝光了利用智能机器人,一天打4万个骚扰电话,从而赚取利润的黑色产业链。 阿里的工程师恼了,技术是用来让人们生活变美好的,不是被利用来走向阴暗的。 机器人的问题交给机器人! 工程师们用业余时间…

excel按条件查询mysql_Excel中实现多条件查找的15种方法

如下图所示,根据第9行的产品和型号,从上面表中查找“销售数量”,结果如C10所示1、SUM函数公式{SUM((A2:A6A9)*(B2:B6B9)*C2:C6)}公式简介:使用(条件)*(条件)因为每行符合条件的为0,不符合的为1,所以只有条件…

JVM调优_堆内存溢出和非堆内存溢出

文章目录1. pom2. MemoryController3. User 对象4. 动态生成class文件工具类5. 启动项目6. 测试连接7. 异常信息1. pom <!--动态生成class文件--><dependency><groupId>asm</groupId><artifactId>asm</artifactId><version>3.3.1<…

使用split_size优化的ODPS SQL的场景

使用split_size优化的ODPS SQL的场景 首先有两个大背景需要说明如下&#xff1a; 说明1&#xff1a;split_size&#xff0c;设定一个map的最大数据输入量&#xff0c;单位M&#xff0c;默认256M。用户可以通过控制这个变量&#xff0c;从而达到对map端输入的控制。设置语句&am…

「今天沾一口野味,明天地府相会!」AI如何抗击「野味肺炎」

河南信阳七星鹏社区宣&#xff08;来源&#xff1a;微博-在信阳&#xff09;整理 | 阿司匹林出品 | CSDN云计算「今天沾一口野味&#xff0c;明天地府相会&#xff01;」这是本次在抗战「野味肺炎」一线中表现突出的河南人民打出的标语。为什么本次疫情被称为「野味肺炎」&…

如何自动导出内存映像文件?

内存溢出自动导出&#xff1a; -XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath./测试&#xff1a; http://localhost/heap-Xmx32M -Xms32M -XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath./

为了30分钟配送,盒马工程师都有哪些“神操作”?

阿里妹导读&#xff1a;提到盒马鲜生&#xff0c;除了新鲜的大龙虾以外&#xff0c;大家印象最深的就是快速配送&#xff1a;门店附近3公里范围内&#xff0c;30分钟送货上门。 盒马是基于规模化和业务复杂度两个交织&#xff0c;从IT到DT&#xff0c;从原产地到消费者而形成的…

滴滴章文嵩:一个人的20年开源热情和国内互联网开源运动

作者 | Just来源 | AI科技大本营&#xff08;ID:rgznai100&#xff09;开源热情就是好玩儿。说起他在22年前的第一款开源软件LVS&#xff08;Linux Virtual Server&#xff09;&#xff0c;章文嵩这样描述彼时心态。从一开始做这个后来名噪一时的Linux集群项目他就没想着赚钱&a…

数据清理的终极指南

我花了几个月的时间分析来自传感器、调查及日志等相关数据。无论我用多少图表&#xff0c;设计多么复杂的算法&#xff0c;结果总是会与预期不同。更糟糕的是&#xff0c;当你向首席执行官展示你的新发现时&#xff0c;他/她总会发现缺陷&#xff0c;你的发现与他们的理解完全不…

使用jmap命令手动导出映像文件?

jmap -helpjps -ljmap -dump:formatb,fileheap.hprof 16240注释&#xff1a;16240 进程号

重磅发布:阿里开源 OpenJDK 长期支持版本 Alibaba Dragonwell

3 月 21 日北京阿里云峰会&#xff0c;阿里巴巴正式宣布对外开源 OpenJDK 长期支持版本 Alibaba Dragonwell。作为 Java 全球管理组织 Java Community Process (JCP) 的最高执行委员会的唯一中国代表&#xff0c;以及 Oracle 之外的 Java 生态中为数不多的 OpenJDK 定制者&…

AI程序员的远方是诗和梦想的美好?还是骨感无望的现实?

人工智能真的玩大了吗&#xff1f;人工智能行业的人才真的“爆发了&#xff1f;”AI程序员究竟怎么样&#xff1f;A与B 薪酬与前景程序员与远方2017年~2018年&#xff0c;是人工智能大火的时候。你会发现&#xff0c;跟朋友聊天不谈人工智能&#xff0c;聊天的bigger都上不去。…

十年再出发:阿里云智能战略加速的“四级火箭”

3月21日&#xff0c;在2019阿里云峰会北京站上&#xff0c;阿里云智能总裁张建锋首次对外阐述了阿里云战略加速的“四级火箭”&#xff1a;达摩院加持的云、数据智能的云、最佳实践的云和被集成的云&#xff0c;从技术、产品、商业和生态层面开启阿里云的下一个十年。 达摩院加…

使用MAT工具分析内存溢出

https://www.eclipse.org/mat/downloads.php对象数量 对象占用的大小 熟练掌握着2个工具栏