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

766 阅读7分钟

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

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

一、课程概述

  1. 一致性协议的定义
  2. Raft举例一致性协议如何工作
  3. 如何使用一致性协议构建KV系统
  4. 一致性协议发展方向

二、详细内容

1. 分布式系统的挑战

1.1 为何需要分布式系统

  • 数据规模越来越大
  • 服务的可用性要求越来越高:服务器宕机分布式系统能正常运行
  • 快速迭代的业务要求系统足够易用:运用人员不需要感知下层细节;希望系统自动化完成修复扩容

1.2 分布式系统要求

  • 高性能:可拓展、低时延、高吞吐
  • 正确:一致性、易用、易于理解和修复系统
  • 可靠:容错高、高可用

1.3 HDFS分布式系统

  • DataNode:无状态,负责HDFS replication,实现高性能
  • NameNode:存储元信息 重要的部分

1.4 KV案例

  • 最简单机KV
    • 接口:Get(key)->value; BatchPut([k1,k2,...], [v1,v2,...])
    • client向服务器发送请求 服务器存储然后返回
    • 可靠性:低容错低可用
    • 正确性高:单进程,操作顺序执行

2. 一致性与共识算法

  • 从复制开始
    • Client RPC -> DBEngine RPC <-> DBEngine RPC
    • 两台DBEngine完全状态一致
    • 如果两个副本都能接受请求:可能发生交叉复制,顺序混乱
    • 主副本定期拷贝全量数据到从副本/主副本拷贝操作到从副本
      • state transfer
      • transformation state machine
    • 写操作
      • 主副本把所有的操作打包成log,log写入持久化保存在磁盘
      • 应用包装成状态机,只接受log为input
      • 主副本确认log写入到副本机,状态机apply后返回客户端
    • 读操作
      • 直接读状态机要求写操作进入状态机后返回client
      • 写操作复制完后直接返回,读操作block等待所有pending log进入状态机
      • 若不遵循方案可能存在写入值读取不到

2.1 一致性

  • KV像操作一台机器一样读到最近写入的值
  • 一种模型/语义
  • 约定一个分布式系统如何向外界应用提供服务
  • 常见一致性模型
    • 最终一致性:读取暂时读不到但最终会读到
    • 线性一致性:最严格,一直一致,线性执行
  • 分类:经常与应用本身有关,linarizability是最理想的
  • 复制协议-当失效发生时
    • 主副本失效
      • 手动切换
        • 容错低:服务停止
        • 高可用:取决于发现切换人工速度
        • 正确:操作从一台机器发起,返回前复制到另一个机器
      • 当主副本失效时为了算法简单人工可以切换,保证较高可用性
      • 如何保证主副本失效?若切换过程中主副本又接收client端请求,两个主副本不正确(复写log)
      • 多个节点下少数节点宕机后仍然可以工作?
        • fault-tolerance

2.2 共识算法

  • 当一个值一旦确定后,所有人都认同
  • 错误总是发生:non-Byzantine fault
  • 错误类型多:网络断开、分区、缓慢、重传、乱序;CPU、IO停止
  • 容错 fault-tolerance
  • 共识协议不等于一致性
    • 应用层面不同一致性可以使用共识协议实现(故意返回旧值)
    • 简单的复制协议也可以提供线性一致性
    • 讨论时提到一致性至线性一致性
      • 弱一致性可以使用简单复制算法实现

3. Raft

3.1 Paxos与Raft

  • Paxos
    • 一致性协议、正确;非liveness
    • 没有完全解决问题,有可能不能达成一致(not terminate)

3.2 Raft原理

  • 易于理解
    • 使用RSM、Log、RPc概念
    • 直接使用RPC对算法进行描述
    • Strong leader-based:所有操作由leader发起
    • 使用随机方法减少约束
  • 正确性
    • 形式化验证
    • 拥有大量成熟系统

3.3 复制状态机RSM

  • replicated state machine
    • raft中所有consensus直接使用log作为载体
  • commit index
    • 一旦raft更新committed index,意味着index前所有log可以提交给状态机
    • committed index不持久化,状态机volatile,重启后从第一条log开始

3.4 Raft角色

  • leader:发现server有更高term
  • follower发现leader有更高term
  • candidate投票,leader获得更高的

3.5 Raft 复制

  • 主节点向从节点复制,半数以上达成一致commit

3.6 从节点失效

  • 主节点向从节点复制,半数以上达成一致commit,失效节点不一致后,主节点向前迭代寻找一致点,发送后面全部log

3.7 Raft Term

  • leader只服务于一个term
  • 每个term只有一个leader
  • 每个节点存储当前的term
  • 每个节点term从一开始只增不减
  • 所有rpc的request response携带term
  • 只commit本term内的log

3.8 Raft主节点失效

  • leader定期发送appendEntries RPCs给其余所有节点
  • 如果follower有一段时间没收到AE,则转换成为candidate
  • candidate自增自己term,同时使用request试图成为leader
  • 其他follower只投票给term比自己高的candidate

3.9 Raft安全性

  • 同term
    • term内安全性,对于所有已经committed的<term,index>位置上至多只有一条log
    • 由于Raft的多数派选举,保证一个term中只有一个leader
    • 在任何<term,index>上至多只有一条log:leader写入
  • 跨term
    • 目标:如果一个log被标记committed,那这个log一定会在未来所有的leader中出现 (leader completeness)
    • raft选举检查log是否过期,最新才能当选leader
    • 选举需要多数派投票,committed log在多数派中(有overlap)
    • 新leader一定持有committed log,且leader永远不会overwrite log

3.10 安全性验证

  • TLA+验证
  • 形式验证;以数学的形式对算法进行表达,由计算机程序对算法所有状态进行遍历

4. 实现细节与未来

4.1 Raft构建KV系统

  • client -> RPC -log-> Raft -commit-> DBEngine
  • 需要状态机applied之后才能返回RPC
  • 一致性读写
    • 写log被commit返回客户端成功;读操作写入log,状态机apply时返回1client 增加log量
    • 写log被commit返回客户端成功;读操作先等待所有committed log apply再读取状态机 优化写时延
    • 写log被状态机apply,返回给client;读操作直接读状态机 优化读时延
  • Raft不能保证一直有一个leader,只保证一个term至多有一个leader;可能存在多个term的leader
  • 确定合法的Leadership
    • 通过一轮heartbeat确认leadership
    • 通过上一次heartbeat时间来保证接下来的有段时间内follower不会timeout;同时follower在这段时间内不进行投票;如果多数follower满足条件那么这段时间内则保证不会有新leader产生
    • 取决于Raft实现程度及读写情况决定方案
  • 多个副本只有单个可以提供服务:服务无法水平扩展
    • 按key分配raft组 分别当不同key range的leader
  • 增加更多raft组:如果操作跨raft组

4.2 共识算法研究方向

  • Raft关于log
    • 当过多log占用后启动snapshot替换掉log
    • 对于持久化状态机快速产生snapshot
    • 多组raft应用log如何合流
  • configuration change
    • joint-consensus以及单一节点变更两种方案
  • 真实世界中不是所有错误都fail-stop
    • cloudflare etcd在partial network下outage很久

4.3 共识算法的未来

  • 高性能
    • us级别共识,us级别容错
    • HovercRaft:P4 programable switch
    • Mu:one-side RDMA 不通过RPC直接写follower内存
  • 多节点提交 Leaderless
    • 节点跨地域
    • EPaxos使用冲突图方式允许并行commit
  • Raft Paxos相互移植
    • 关联两种算法
  • 共识算法作为系统
    • 多数分布式系统选择共识算法作为底座
    • 不同一致性协议有不同特性
    • virtual consensus in delos
      • 对外暴露一致性log作为接口
      • 内部对于log可以选择不同实现

三、个人总结

本节课我学习了分布式一致性协议的相关内容,以及其通过Raft的实现;Paxos算法是非常复杂的算法,在课后学习中还需要加强对此方面的深入理解。