浅谈一致性协议|青训营笔记

113 阅读4分钟

这是我参与「第四届青训营 」笔记创作活动的的第15天

  • 分布式系统
    • 挑战
      • 数据规模越来越大
      • 服务的可用性要求越来越高
      • 快速迭代的业务要求系统足够易用
    • 目标
      • 高性能
        • 可拓展、低时延、高吞吐
      • 正确
        • 一致性、易于理解
      • 可靠
        • 容错、高可用
  • 一致性与共识算法
    • 从复制开始
      • 主副本定期拷贝全量数据到从副本
        • 代价太高
      • 主副本拷贝操作到从副本
        • 主副本把所有的操作打包成Log
        • 应用包装成状态机,只接收Log作为Input
        • 主副本确认Log已经成功写入到副本机器上,当状态机apply后,返回客户端
      • 读操作
        • 方案一
          • 直接读状态机,要求写操作进入状态机后再返回client
        • 方案二
          • 写操作复制完成后直接返回,读操作block等待所有pending log进入状态机
    • 什么是一致性
      • 对于KV
        • 要读到最近写入的值
      • 一致性是一种模型(语义)
        • 来约定一个分布式系统如何向外界(应用)提供服务
        • KV中常见的一致性模型
          • 最终一致性
            • 读取可能暂时读不到但是总会读到
          • 线性一致性
            • 最严格、线性执行
    • 共识算法
      • 一个值一旦确定,所有人都认同
      • 共识协议不等于一致性
        • 应用层面不同的一致性,都可以用共识协议来实现
          • 比如可以故意返回旧的值
        • 简单的复制协议也可以提供线性一致性
      • 一般讨论共识协议时提到的一致性,都指线性一致性
        • 因为弱一致性往往可以使用相对简单的复制算法实现
  • Raft入手
    • Paxos
      • 难以理解
    • Raft
      • 易于理解作为算法的设计目标
        • 使用了RSM、Log、RPC的概念
        • 直接使用RPC对算法进行了描述
        • Strong Leader-based
        • 使用了随机的方法来减少约束
      • 正确性
        • 形式化验证
        • 拥有大量成熟系统
    • 复制状态机RSM
      • RSM(replicated state machine)
        • raft中所有的consensus都是直接使用Log作为载体的
      • Commited Index
        • 一旦raft更新commited index,意味着这个index前的所有log都可以提交给状态机了
        • commited index是不持久化的,状态机也是volatile的,重启后从第一条log开始
    • raft角色
      • leader
        • 所有操作的发起者
      • candidate
        • 参与竞选leader
      • follower
        • 不接收用户的请求,无主时成为candidate发起选主请求
    • raft term
      • 逻辑时钟
      • 特点
        • 每个leader服务于一个term
        • 每个term至多只有一个leader
        • 每个节点存储当前的term
        • 每个节点term从一开始,只增不减
        • 所有rpcrequest response都携带term
        • committerm内的log
    • raft主节点失效
      • leader定期的发送AppendEntries RPCs给其余所有节点
      • 如果follower有一段时间没有收到leaderAppendEntries,则转换身份成为candidate
      • candidate自增自己的term,同时使用requestVote RPCs向剩余节点请求投票
        • raft在检查自己是否可以投票时,会检查log是否outdated,至少不比本身旧才会投给对应的candidate
      • 如果多数派节点投给它,则成为该termleader
    • raft安全性
      • term
        • 对于term内的安全性
          • 目标
            • 对于所有已经commited的<term,index>位置上至多只有一条log
        • 由于raft的多数派选举,我们可以保证在一个term中只有一个leader
          • 在任何<term,index>位置上,至多只有一条log
      • term
        • 目标
          • 如果一个log被标记commited,那这个log一定会在未来所有的leader中出现leader completeness
        • 证明
          • raft选举时会检查log是否outdated,只有最新的才能当选leader
          • 选举需要多数派投票,而commited log也已经在多数派中(必有overlap)
          • leader一定持有commited log,且leader永远不会overwrite log
  • 实现细节以及未来
    • 一致性读写
      • 方案一
        • logcommit了,返回客户端成功
        • 读操作也写入一条log,状态机apply时返回client
        • 增加log
      • 方案二
        • logcommit了,返回客户端成功
        • 读操作先等待所有commited log apply,再读状态机
        • 优化写时延
      • 方案三
        • log被状态机apply,返回给client
        • 读操作直接读状态机
        • 优化读时延
    • 确定合法的leader
      • 方案一
        • 通过一轮心跳确认leadership
      • 方案二
        • 通过上一次心跳时间来保证接下来的有段时间内follower不会timeout
        • 同时follower在这段时间内不进行投票
        • 如果多数follower满足条件,那么在这段时间内则保证不会有新leader产生
    • 水平扩展
      • 增加raft组,通过key分区,一个raft负责一段key
    • 未来展望
      • 高性能
      • 多节点提交
      • RaftPaxos相互移植