• 关于共识算法Raft的常见误解


    Raft 共识算法

    最近翻了翻Raft相关的资料,同时也总结了日常工作的一些积累,就当做Raft技术笔记吧。

    由于工作的关系,Raft是所有组件共用的算法核心,包括RocketMQ、Consul、CubeFS等,所以对Raft也算脸熟了(当然它可能不怎么认识我,工作中这种情况挺常见的,不知道为什么:-)

    最终一致性与线性一致性

    最终一致性,常表述为弱一致性,这里的弱是较于强而言(后续会有个人基于现实场景中遇到的问题进行对比),而线性一致性常说的是强一致性,要求在相同的情况下还要符合全局时钟的先后顺序。

    此外还有顺序一致性和因果一致性。

    顺序一致性弱于线性一致性,强调进程间操作的执行顺序(而非全局时钟),极有可能在全局时钟看来结果是错误的但是仍然满足顺序一致性,总的来说顺序一致性要求顺序一致不管对错。

    因果一致性则是弱一致性,强调因果关系;如果A能推导出B,B能推导出C,那么A一定能推导出C;

    if A => B,B=>C;那么A=>C。
    
    • 1

    总的来说线性一致性>顺序一致性>因果一致性>最终一致性,当然实现难度也是同理;

    上述描述都比较晦涩,结合实际项目说明,比如Zookeeper实现的就是顺序一致性(严谨地说,写操作是线性一致性,读操作是顺序一致性),保证在所有节点上读请求一定在写入请求之后执行;而ETCD、RocketMQ都是借助Raft实现了线性一致性(当然Raft与Paxos亦有差别)。

    而最终一致性的代表就是Consul,简单介绍Consul的Gossip协议,相信对最终一致性就会有直观的了解。

    Gossip协议是当集群中某个节点收到消息时,随机选取集群中几个节点传播消息,收到消息的节点亦如此;按照这个设计,信息在集群中如同八卦一般,一传十,十传百,直到集群中所有节点都“知晓”。

    但是实际工程实践中我们发现速度远比想象的慢,比如网络会极大影响传播速度,集群拓扑的路径选择等;所以部署Consul时往往会选择几个Leader节点,读写都在Leader上,这样只要保证了有限几个leader节点之间的传播不受影响即可。

    想起刚接手Consul维护工作时,遇到的一个问题;

    业务将车辆下线服务注册到Consul成功后(某个Server节点,集群呈网状部署,都是单点,是的单点!!!),此时按照实际应该通过集群广播将信息扩散到其他节点(包括其他Leader节点和Follower节点),但是由于此时该节点所在百度云宿主机(额,是的,我们用的百度云BCC :-)网络异常,于是扩散终止了。

    但是其他Server依然在对外提供服务,于是其他服务完全没有感知到有新车下线的消息,整个车云链路就整体“宕机”了。
    后来排查发现了此问题,推动业务将服务之间的调用链路通过MQ进行结耦,全面清查单点问题,同时Consul的注册机制调整为多数成功才算成功。
    另外此事还有一个后续就是故障宿主机恢复后,由于该Server节点落后数据太多,于是其他Server上的信息如潮水般涌来,导致故障的Server节点在恢复后短时间内大量同步其他节点的数据,CPU持续拉高,而其自身的数据始终不能及时同步出去,变成“只吃不吐”(于是熬夜打补丁增加了限流逻辑,又是一个通宵:-).

    日志的覆盖与删除

    摘抄网上一篇文章的片段“由于从节点的最大日志数据二元组是<7,12>,与leader发送过来的日志数据<6,10>不匹配,索引11、12的数据将被删除”

    Raft 主从同步流程如下:
    索引6-10会从leader同步(Append Entries),但是由于leader的索引只是到10,follower上的committed index 会重置到10(与Leader保持一致,参考Raft 安全性原则),索引11、12不会做任何更改,当leader收到新的写请求后索引递增到11、12;那么follower会从leader同步数据,此时会覆盖(follower上索引11、12的内容会被leader上新写入的内容覆盖,由此leader、follower上索引11、12保持一致);

    上述流程中可以发现,并没有删除流程;Raft 的读写都从Leader上进行,同时Leader是Append-Only的,所以删除流程对于Raft来说是不存在的操作。

    Remove节点时需要skip

    回放时需要跳过remove自身节点的日志,否则当前节点无法加入集群;

    这点尤为重要,曾经线上遇到某个节点恢复上线时总是保持分钟级在线,然后就自动下线了,四处排查总是找不到原因,本地也无法复现,最后滤逻辑和日志发现,remove self了,哭笑不得。

    总结

    未完待续

    参考文档

    1、Raft wiki

  • 相关阅读:
    知识图谱1_2——下载neo4j客户端
    PHP项目搭建与启动
    【构建ML驱动的应用程序】第 6 章 :调试 ML 问题
    mvn: Downloading from pluginRepository
    小家具工厂是如何实现成本降低,收益提高的呢
    PyQt5中的分割线与spacer
    SpringBoot项目去除druid监控的底部广告
    Linux系统命令——用户及用户组管理命令
    【Jenkins】win 10 / win 11:Jenkins 服务登录凭据配置
    【计算机组成原理】乘法运算
  • 原文地址:https://blog.csdn.net/SchopenhauerZhang/article/details/132670206