前言

之前的两篇文章更多的是在描述Raft算法的正常流程,没有过多的去讨论异常场景。

而实际在分布式系统中,我们更多的都是在应对网络不可用、机器故障等异常场景,所以本篇来讨论一下Raft协议的安全性,即在异常场景下是否会导致数据丢失、数据不一致等情况。

选举限制

在Raft协议中,所有的日志条目都只会从Leader节点往Follower节点写入,且Leader节点上的日志只会增加,绝对不会删除或者覆盖。

这意味着Leader节点必须包含所有已经提交的日志,即能被选举为Leader的节点一定需要包含所有的已经提交的日志。因为日志只会从Leader向Follower传输,所以如果被选举出的Leader缺少已经Commit的日志,那么这些已经提交的日志就会丢失,显然这是不符合要求的。

这就是Leader选举的限制:能被选举成为Leader的节点,一定包含了所有已经提交的日志条目。

回看算法基础中的RequestVote RPC:

参数 解释
term Candidate的任期
candidateId Candidate的ID
lastLogIndex Candidate最后一条日志的索引
lastLogTerm Candidate最后一条日志的任期
参数 解释
term 当前任期,用于Candidate更新自己的任期
voteGranted true表示给Candidate投票

请求中的lastLogIndex和lastLogTerm即用于保证Follower投票选出的Leader一定包含了已经被提交的所有日志条目。

  1. Candidate需要收到超过版本的节点的选票来成为Leader
  2. 已经提交的日志条目至少存在于超过半数的节点上
  3. 那么这两个集合一定存在交集(至少一个节点),且Follower只会投票给日志条目比自己的“新”的Candidate,那么被选出的节点的日志一定包含了交集中的节点已经Commit的日志

日志比较规则(即上面“新”的含义):Raft 通过比较两份日志中最后一条日志条目的索引值和任期号定义谁的日志比较新。如果两份日志最后的条目的任期号不同,那么任期号大的日志更加新。如果两份日志最后的条目任期号相同,那么日志比较长的那个就更加新。

日志提交限制

上图按时间序列展示了Leader在提交日志时可能会遇到的问题。

  1. 在 (a) 中,S1 是领导者,部分的复制了索引位置 2 的日志条目。
  2. 在 (b) 中,S1 崩溃了,然后 S5 在任期 3 里通过 S3、S4 和自己的选票赢得选举,然后从客户端接收了一条不一样的日志条目放在了索引 2 处。
  3. 然后到 (c),S5 又崩溃了;S1 重新启动,选举成功,开始复制日志。在这时,来自任期 2 的那条日志已经被复制到了集群中的大多数机器上,但是还没有被提交。
  4. 如果 S1 在 (d) 中又崩溃了,S5 可以重新被选举成功(通过来自 S2,S3 和 S4 的选票),然后覆盖了他们在索引 2 处的日志。反之,如果在崩溃之前,S1 把自己主导的新任期里产生的日志条目复制到了大多数机器上,就如 (e) 中那样,那么在后面任期里面这些新的日志条目就会被提交(因为S5 就不可能选举成功)。 这样在同一时刻就同时保证了,之前的所有老的日志条目就会被提交。

任期2内产生的日志可能在(d)的情况下被覆盖,所以在出现(c)的状态下,Leader节点是不能commit任期2的日志条目的,即不能更新commitIndex。

在上图最终状态是(e)的情况下,commitIndex的变化应该是1->3,即在(c)的情况下,任期4在索引3的位置commit了一条消息,commitIndex直接被修改成3。

而任期2的那条日志会通过Log Matching Property最终被复制到大多数节点企且被应用。

Raft算法保证了以下特性:

  • 如果两个日志条目有相同的index和term,那么他们存储了相同的指令(即index和term相同,那么可定是同一条指令,就是同一个日志条目)
  • 如果不同的日志中有两个日志条目,他们的index和term相同,那么这个条目之前的所有日志都相同

两条规则合并起来的含义:两个日志LogA、LogB,如果LogA[i].index=Log[i]B.index且LogA[i].term=Log[i].term,那么LogA[i]=Log[i]B,且对于任何n < i的日志条目,LogA[n]=LogB[n]都成立。(这个结论显而易见的可以从日志复制规则中推导出来)

解读Raft(三 安全性)的更多相关文章

  1. 解读Raft(一 算法基础)

    最近工作中讨论到了Raft协议相关的一些问题,正好之前读过多次Raft协议的那paper,所以趁着讨论做一次总结整理. 我会将Raft协议拆成四个部分去总结: 算法基础 选举和日志复制 安全性 节点变 ...

  2. Java RMI学习与解读(三)

    Java RMI学习与解读(三) 写在前面 接下来这篇就是最感兴趣的Attack RMI部分了. 前面也说过,RMI的通信过程会用到反序列化,那么针对于RMI的三个角色: Server/Regisrt ...

  3. raft协议安全性保证

    分布式系统中主要的问题就是如何保持节点状态的一致性,不论发生任何failure,只要集群中大部分的节点可以正常工作,则这些节点具有相同的状态,保持一致,在client看来相当于一台机器. 一致性问题本 ...

  4. AFNetworking 3.0 源码解读(三)之 AFURLRequestSerialization

    这篇就讲到了跟请求相关的类了 关于AFNetworking 3.0 源码解读 的文章篇幅都会很长,因为不仅仅要把代码进行详细的的解释,还会大概讲解和代码相关的知识点. 上半篇: URI编码的知识 关于 ...

  5. 七字真言解读TCP三次握手

    三次握手所谓的"三次握手"即对每次发送的数据量是怎样跟踪进行协商使的发送和接收同步,根据所接收到的数据量而确定的数据确认数及数据发送.接收完毕后何时撤消联系,并建立虚连接. 一.七 ...

  6. 解读Raft(四 成员变更)

    将成员变更纳入到算法中是Raft易于应用到实践中的关键,相对于Paxos,它给出了明确的变更过程(实践的基础,任何现实的系统中都会遇到因为硬件故障等原因引起的节点变更的操作). 显然,我们可以通过sh ...

  7. Node.js API 初解读(三)

    目录 Node.JS API 初解读三 Node.JS API 初解读三 Version: NodeJs v6.2.0 一. DNS (Domain Name Server) [域名服务器] 1.简介 ...

  8. Alamofire源码解读系列(三)之通知处理(Notification)

    本篇讲解swift中通知的用法 前言 通知作为传递事件和数据的载体,在使用中是不受限制的.由于忘记移除某个通知的监听,会造成很多潜在的问题,这些问题在测试中是很难被发现的.但这不是我们这篇文章探讨的主 ...

  9. 解读Raft(二 选举和日志复制)

    Leader election Raft采用心跳机制来触发Leader选举.Leader周期性的发送心跳(如果有正常的RPC的请求情况下可以不发心跳)包保持自己Leader的角色(避免集群中其他节点认 ...

随机推荐

  1. Android 深入理解Loader机制 让APP轻装上阵

    本文简书同步发布,谢谢关注. http://blog.csdn.net/sk719887916/article/details/51540610 Android开发者都经历过APP UI开发不当 会造 ...

  2. Android多点触摸缩放图片-android学习之旅(四)

    获取多触摸点 核心代码: 获取触摸点的个数和位置 public boolean onTouch(View v, MotionEvent event) { switch (event.getAction ...

  3. PLSQL解析XML文件

     参考网上资料学习汇总 在PL/SQL中利用XML ,Oracle提供了几个组件,让开发人员能轻松地利用XML技术.这些组件包括: 1.  XML 分析程序.即用来分析.构造和验证XML文档.. ...

  4. UNIX网络编程——TCP长连接与短连接的区别

    一.TCP短连接 我们模拟一下TCP短连接的情况,client向server发起连接请求,server接到请求,然后双方建立连接.client向server发送消息,server回应client,然后 ...

  5. java中public与private还有protect的区别

    java中public与private还有protect的区别 总是忘记.

  6. Spark SQL官方文档阅读--待完善

    1,DataFrame是一个将数据格式化为列形式的分布式容器,类似于一个关系型数据库表. 编程入口:SQLContext 2,SQLContext由SparkContext对象创建 也可创建一个功能更 ...

  7. javascript setinterval 正确的语法

    前几天我用setinterval 写了一个小程序,这个setinterval是用来干什么的我就不解释了. 写的方法在其它的浏览器里都能用,后来测试组的同事拿去一测就出了问题.因为她们爱用360,还有I ...

  8. hibernate 关于主键

    本文为北京尚学堂hibernate视频的学习笔记 1在xml中定义单个主键生成策略 1.1通过xml <id name="id" type="long" ...

  9. 分布式进阶(五)之JSVC配置

    应用场景:在linux系统上进行项目开发,在部署java项目时,常用方法就是写一个shell脚本,但当服务器重启了,经常会忘了启动shell脚本了.所以我们需要把自己的应用变成linux的服务,当服务 ...

  10. Chapter 3 Protecting the Data(2):分配列级权限

    原文出处:http://blog.csdn.net/dba_huangzj/article/details/39577861,专题目录:http://blog.csdn.net/dba_huangzj ...