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

97 阅读9分钟

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

一、分布式系统。

1.分布式系统面临的挑战:
  • 数据规模越来越大
  • 服务的可用性要求越来越高
  • 快速迭代的业务要求系统足够易用
2.理想中的分布式系统:
  • 高性能:可拓展、低时延、高吞吐
  • 正确:一致性、易于理解
  • 可靠:容错、高可用
3.从HDFS开始:

59b53c891f72f8a2fe4dff3016d2b06.jpg

4.案例-KV
  • 从最简单机KV开始
  • 接口:
    • Get(key)-> value
    • BatchPut((k1, K2,..].v1, v2,..])
  • 第一次实现
    • RPC
    • DB Engine

e89218d387a01e8d9083235ef382b15.jpg

二、一致性与共识算法。

1.从复制开始:
  • 既然一台机器会挂 2906d009d8b2a654550e1de8bb492c4.jpg
  • 如果两个副本都能接收请求

d69f308a40475b0f4ef6a359b177591.jpg

2.如何复制:
  • 主副本定期拷贝全量数据到从副本
  • 主副本拷贝操作到从副本

48e1d11e398c3b8b3bc29332ad40b36.jpg

3.如何复制操作?
  • 主副本把所有的操作打包成Log
    • 所有的Log写入都是持久化的,保存在磁盘上
  • 应用包装成状态机,只接收Log作为input
  • 主副本确认LOg已经成功写入到副本机器上 当状态机apply后,返回客户端

34d2be55df94ea25dcf5c844dedcfa9.jpg

4.关于读操作:
  • 读操作
    • 方案一:直接读状态机,要求写操作进入状态机后两返回 client
    • 方案二:写操作复制完成后直接返回,读操作Block 等待所有pending log进入状态机
  • 如果不遵循上述两周方案呢?
    • 可能存在刚刚写入的值读不到的情况(在Log中)

c9231c4c4cf11295c14df788ae40793.jpg

5.什么是一致性-1:
  • 对于我们的KV
    • 像操作一台机器一样
      • 要读到最近写入的值
  • 一致性是一种模型(或语义)
    • 来约定一个分布式系统如何向外界(应用)提供服务
    • KV中常见的一致性模型
      • 最终一致性:读取可能暂时读不到但是总会读到
      • 线性一致性:最严格,线性执行
什么是一致性-2:
  • 一致性的分类
    • 经常与应用本身有关
  • Linearizability是最理想的

6967cdc27dc94d0f9d654e3d0b7d8e7.jpg

6.复制协议-当失效发生:

当主副本失效

  • 手动切换
  • 容错?
    • 不,我们的服务还是停了
  • 高可用?
    • 也许,取决于我们从发现到切换的过程的有多快
  • 正确?
    • 操作只从一台机器上发起
    • 所有操作返回前都已经复制到另一台机器了

复制协议-小结:

当主副本失效时,为了使得算法简单

  • 我们人肉切换,只要足够快
    • 我们还是可以保证较高的可用性。

但是如何保证主副本是真的失效了呢?

  • 在切换的过程中,主副本又开始接收client端的请求
  • 两个主副本显然是不正确的,log会被覆盖写掉
  • 我们希望算法能在这种场景下仍然保持正确

要是增加到三个节点呢?

  • 能不能允许少数节点挂了的情况下,仍然可以工作
    • falut-tolerance
7.共识算法:
  • 什么是共识算法

    • "The consensus problem requires agreement among a number of processes (or agents) for a single data value. Some of the processes (agents) may fall or be unreliable in other ways, so consensus protocols must be fault tolerant or resilient"
  • 简而言之一个值一旦确定,所有人都认同.

  • 错误总是发生

    • Non-Byzantine fault
  • 错误类型很多

    • 网络断开,分区,缓慢,重传,乱序
    • CPU、IO 都机会停住
  • 容错(falute-tolerance )

  • 有文章证明是一个不可能的任务(FLP impossibility)

"In this paper. we show the surprising result that no completely asynchronous consensus protocol can tolerate even a single unannounced process deal h. We do not consider Byzantine failures, and we assume that the message system is reliableit d elivers all messages correctly and exactly once."

-JACM 85

  • 共识协议不等于一致性
    • 应用层面不同的一致性,都可以用共识协议来实现
      • 比如可以故意返回旧的值
    • 简单的复制协议也可以提供线性一致性
  • 股讨论共识协议时提到的一致性 都指线性一致性
    • 因为弱一致性往往可以使用相对简单的复制算法实现

三、共识算法案例:Raft。

1.Paxos:
  • The Part-Time Parliamen by Lamport 1989
    • 也就是人们提到的Paxos
    • 基本上就是一致性协议的的同义词
    • 该算法的正确性是经过证明的
  • 那么问题解决了吗?
    • Paxos 是出了名的难以理解,Lamport 本人在01年又写了一篇Paxos Made Simple
      • "The Paxos Algorighm, when presented in plain English, is very simple."
    • 算法整体是以比较抽象的形式描述 工程实现时需要做一些修改
    • Google 在实现Chubby的时候是这样描述的
      • here are significant gaps between the descrip tion of the Paxos algorithm and the needs of a real-world system....the final system will be based on an unproven protocol.
2.Raft:
  • 2014年发表
  • 易于理解作为算法的设计目标
    • 使用了RSM、Log、RPC 的概念
    • 直接使用RPC对算法进行了描述
    • Strong Leader-based
    • 使用了随机的方法减少约束
  • 正确性
    • 形式化验证
    • 拥有大量成熟系统
3.复制状态机(RSM):
  • RSM( replicated state machine )
    • Raft 中所有的 consensus都是直接使用Log作为载体
  • Commited Index
    • 一旦Rat 更新 Commited Index,意味着这个Index前的所有Log都可以提交给状态了
    • Commiled Index 是不持久化的,状态机也是volatile 的,重启后从第一条Log开始

ae8353739a31c03aac3ccc1c0256d81.jpg

4.Raft 角色:

8d216620008d9c4aa9c31c0f397b9b1.jpg

5.Raft日志复制:

2382c4644ccb5c98181eb391ae11e6d.jpg

6.Raft从节点失效:

0954511f03976022616bb21785f550e.jpg

7.Raft Term:
  • 每个Leader 服务于一个term
  • 每个term 至多只有一个leader
  • 每个节点存储当前的term
  • 每个节点term 从一开始,只增不减
  • 所有rpc的request reponse 都携带term
  • 只commit本 term 内的log

fcf63b8fd567427d977ee245ce6d70f.jpg

8.Raft 主节点失效:
  • Leader 定期的发送AppendEntries RPCS给其余所有节点
  • 如果Follower 有一段时间没有收到Leader 的AppendEntries,则转换身份成为Candidate
  • Candidate 自增自己的term,同时使用RequestVote RPCs向剩余节点请求投票
    • rat 在检查是否可以投票时,会检查log是否outdated 至少不比本身旧才会投给对应的Candidate
  • 如果多数派节点投给它,则成为该term 的leader
9.Raft Leader failure:

bb55c2aeb6fc1cb5b854852da984cb2.jpg

10.Raft安全性-同Term:

对于Term 内的安全性

  • 目标:
    • 对于所有已经的 commited的<term,inde位置上至多只有一条log

由于Rat 的多数派选举,我们可以保证在一个term 中只有一个leader

  • 我们可以证明一条更严格的声明:在任何term,index位置上,至多只有一条log

  • 对于跨Term的安全性

    • 目标:
      • 如果一个1og被标记 commited,那这个10g一定会在未来所有的leader 中出现 Leader completeness
  • 可以证明这个property

    • Rat 选举时会检查Log的是否 outdated,只有最新的才能当选Leader
    • 选举需要多数派投票,而 commited log也已经在多数派中(必有overlap)
    • 新Leader一定持有 commited log,且 Leader 永远不会 overwrite log

Raft安全性验证:

  • 真的安全吗
    • Rat 使用 TLA+进行了验证
      • 形式验证(Formal Method)

以数学的形式对算法进行表达,由计算机程序对算法所有的状态进行遍历。

83926bcbf46174b454e3227d2d29139.jpg以穷举的方法对算法进行验证。

四、回到KV。

1.案例-KV:
  • 利用Raft算法,重新打造我们的KV。

3c50d38d846c2425fc0d05ad0fbee5b.jpg

  • 回顾一下一致性读写的定义

    • 方案一:
      • 写log被 commit了,返回客户端成功
      • 读操作也写入一条log,状态机apply 时返回 client
      • 增加Log量
    • 方案二:
      • 写log被 commit了 返回客户端成功
      • 读操作先等待所有 commited log apply,再读取状态机
      • 优化写时延
    • 方案三:
      • 写Log被状态机 apply,返回给client
      • 读操作直接读状态机
      • 优化读时延
  • Rat 不保证一直有一个leader

    • 只保证一个term 至多有一个leader
    • 可能存在多个term的leader
  • Split-brain

e03cced44503d65fbbf914173a2766b.jpg

  • 确定合法的Leadership
    • 方案一:
      • 通过一轮Heartbeat确认Leadership (获取多数派的响应)
    • 方案二:
      • 通过上一次 Heartbeat时间来保证接下来的有段时间内 follower 不会imeout
      • 同时 follower 在这段时间内不进行投票
      • 如果多数 follower满足条件,那么在这段时间内则保证不会有新的Leader产生
  • 结合实际情况选择方案二或方案三
    • 取决于rat 的实现程度以及读写的情况 4813c359ba63f5c0037b28562d823b0.jpg
  • 多个副本只有单个副本可以提供服务
    • 服务无法水平拓展
  • 增加更多Rat组
    • 如果操作跨Raft组

fc1796fb37a1d672a63a4875f4f76e0.jpg

2.回到共识算法:
  • Rat :关于Log
    • 论文中就给出的方案,当过多的Log占用后,启动snapshot 替换掉Log
    • 如果对于持久化的状态机,如何快速的产生 Snapshot
    • 多组Raft的应用中 Log 如何合流
  • 关于configuration change
    • 论文中给出的 joint-consensus 以及单一节点变更两种方案

a354f44eb0c48ac7875deabba1a5bb4.jpg

  • Rat 是正确的 但是在工程世界呢?
    • 真实世界中不是所有的精误都是完美fll-stop的
    • cloudflare 的 case,etcd 在 partial network 下, outage了6个小时

f16d7195681920a5343bfc6ab857e34.jpg

3.共识算法的未来:
  • 高性能
    • 数据中心网络100G,时延约为几个uS
    • RDMA 网卡以及programable switch 的应用
    • 我们想要的是:us级别的共识,以及uS级别的容错
    • HovercRaft
      • P4 programable switch: IP multicast
    • Mu
      • Use one-sided RDMA
      • pull based heartbeat instead of push-based.

98c8b61008e440aa1ce88c59883c798.jpg

  • 多节点提交(Leaderless)
    • 节点跨地域,导致节点间的RTT(Round Tnp Time)很大
    • EPaxos
      • 使用了冲突图的方式来允许并行Commit
      • 不冲突的情况下1RTT 提交时间

b31fb18022b33219976538912998005.jpg

  • Raft Paxos 相互移植

    • Raft 有很多成熟的实现
    • 研究主要关注在Paxos上
    • 如何关联两种算法
      • On the Parallels between Paxos and Raft, and how to Port Optimizations
      • Paxos vs Raft: Have we reached con sensus on distnibuted consensus?
  • 共识算法作为一个系统

    • 多数分布式系统都选择共识算法作为底座
    • 不同一致性协议有不同的特性
    • Virtual consensus in delos
      • 对外暴露一致性的LOG 作为借口
      • 内部对于LOG 可以选择不同的实现

总结

经过本次课程的学习,我了解了一致性的定义,一致性其实就是模型;了解了什么是共识算法、Raft的基本工作原理、一致性协议的未来方向等。其中一致性协议存在限制:

  • 对于分布式系统
    • 拓展性:写入性能不能水平拓展
    • 性能:强 Leader 的一致性协议跨地域部署时带来的额外网络开销
  • 对于 KV 系统,解决方案一般是通过分片的方式水平拆组
    • 引入了事务的概念
    • 常见二阶段提交