这是我参与「第四届青训营 」笔记创作活动的第14天
Lecture15. 浅谈分布式一致性协议
01. 分布式系统
1.1 分布式系统面临的挑战
- 数据规模越来越大
- 服务的可用性要求越来越高
- 快速迭代的业务要求系统足够易用
1.2 理想中的分布式系统
- 高性能:可拓展、低时延、高吞吐
- 正确:一致性、易于理解
- 可靠:容错(架构上的概念,一种高可用)、高可用
1.3 从 HDFS 开始
1.4案例 - KV
-
从最简单机KV开始
-
接口:
- Get(key) -> value
- BatchPut([k1,k2,..….],[v1,v2,.…])
-
第一次实现
- RPC(抽象网络 接口)
- DB Engine
可靠性:
- 容错?
- 高可用?
正确性:
- 单进程,所有操作顺序执行
01.小结
- 背景:数据规模的不断增加,我们需要大规模分布式系统
- 维度:对于一个分布式系统,希望能有哪些特征
- 从KV入手,看看我们如何满足分布式系统的要求
02. 一致性与共识算法
升级KV......
2.1 从复制开始
既然一台机器会挂
如何保持两份副本?
如果两个副本都能接受请求(太难了!很难保持一致性)
解决:一主一从复制
2.2 如何复制
- 主副本定期拷贝全量数据到从副本
- 主副本拷贝操作到从副本
2.3 如何复制操作
主副本把所有的操作打包成Log(operation)
- 所有的Log 写入都是持久化的,保存在磁盘上
应用包装成状态机,只接收Log作为Input
主副本确认Log已经成功写入到副本机器上,当状态机apply后,返回客户端
2.4 关于读操作
读操作
- 方案一:直接读状态机,要求写操作进入状态机后再返回client
- 方案二:写操作复制完成后直接返回,读操作Block等待所有pending log进入状态机
如果不遵循上述两周方案呢?
- 可能存在刚刚写入的值读不到的情况(在Log中
2.5 什么是一致性
-
对于我们的KV
- 像操作一台机器一样
- 要读到最近写入的值
-
一致性是一种模型(或语义)
-
来约定一个分布式系统如何向外界(应用)提供服务
-
KV中常见的一致性模型
- 最终一致性:读取可能暂时读不到但是总会读到
- 线性一致性:最严格,线性执行
-
一致性的分类
- 经常与应用本身有关
Linearizability线性一致性是最理想的
2.6 复制协议-当失效发生
当主副本失效时
-
手动切换
-
容错?
- 不,我们的服务还是停了
-
高可用?
- 也许,取决于我们从发现到切换的过程的有多快
-
正确?
- 操作只从一台机器上发起
- 所有操作返回前都已经复制到另一台机器了
2.6 小结
-
当主副本失效时,为了使得算法简单
- 我们人肉切换,只要足够快
- 我们还是可以保证较高的可用性。
-
但是如何保证主副本是真的失效了呢?
- 在切换的过程中,主副本又开始接收client端的请求
- 两个主副本显然是不正确的,log 会被覆盖写掉
- 我们希望算法能在这种场景下仍然保持正确
-
要是增加到三个节点呢?
- 能不能允许少数节点挂了的情况下,仍然可以工作
- falut-tolerance容错的
2.7 共识算法
什么是共识算法
- "The consensus problem requires agreement among a number of processes (or agents) for a single data value. Some of the processes (agents) may fail or be unreliable in other ways,so consensus protocols must be fault tolerant or resilient"
- 简而言之一个值一旦确定,所有人都认同。
-
有文章证明是一个不可能的任务(FLP impossibility)
-
" In this paper, we show the surprising result that no completely asynchronous consensus protocol can tolerate even asingle unannounced process death.We do not consider Byzantine failures, and we assume that the message systemis reliableit delivers all messages correctly and exactly once." --JACM 85[1]
-
错误总是发生(导致这个算法很难)
- Non-Byzantine fault非拜占庭
-
错误类型很多
- 网络断开,分区,缓慢,重传,乱序
- CPU、IO都机会停住
-
容错(falute-tolerance)
共识协议不等于一致性
- 应用层面不同的一致性,都可以用共识协议来实现
- 比如可以故意返回旧的值
- 简单的复制协议也可以提供线性一致性
一般讨论共识协议时提到的一致性,都指线性一致性
- 因为弱一致性往往可以使用相对简单的复制算法实现