ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

第八章:分布式系统的挑战

第八章:分布式系统的挑战 第八章分布式系统的挑战这一章是全书的一个转折点。前七章讨论的是如何让分布式系统正常工作第八章则揭示一个残酷现实分布式系统里没有什么是可靠的——网络会延迟、时钟会漂移、进程会暂停、节点会假死。Kleppmann 的核心论点是在分布式系统中你无法区分节点挂了和节点很慢也无法依赖时钟和网络来建立全局秩序。所有分布式算法都必须在这种不确定性之上建立。本章结构先讲网络不可靠再讲时钟不可靠然后讲进程暂停最后讨论这些不确定性带来的根本性知识问题。一、本章的核心命题分布式系统的根本困难不在于机器会坏而在于你无法确定它到底坏没坏。在单机系统中一个进程崩溃是明确的。但在分布式系统中一个节点没响应可能是挂了可能是网络慢可能是 GC 停顿可能是对方在处理但没回你无法区分这些情况这就是所谓的部分失效Partial FailureKleppmann 的比喻单机编程像在自家房子里走动你知道每个房间在哪分布式编程像在异国他乡你连方向都不确定还要跟一群说着不同语言、可能随时消失的人合作。二、不可靠的网络1. 网络的基本事实数据包可能丢失、延迟、重复、乱序发送方无法知道对方是否收到超时是唯一的手段但超时无法区分慢和死2. 网络故障的常见误解误解一网络是可靠的实际上数据中心网络也会有丢包、延迟抖动大规模系统中网络故障是常态误解二延迟是固定的实际上延迟波动极大从微秒到秒级原因排队、拥塞、路由变化、GC误解三TCP 能保证可靠TCP 只保证最终送达或明确失败无法保证延迟上限应用层超时后TCP 可能还在重传3. 网络分区Network Partition定义网络被分成多个部分部分之间无法通信。后果节点之间无法达成一致可能出现脑裂Split-brain多个节点都认为自己是主节点这是分布式系统中最棘手的问题之一Kleppmann 的提醒网络分区不是会不会发生而是什么时候发生。设计系统时必须假设分区会发生。4. 超时的困境超时设置的两难太短误判慢节点为故障触发不必要的切换可能造成脑裂太长故障节点迟迟不被发现服务中断时间长没有完美答案网络延迟是动态的无法用固定超时适应所有情况自适应超时如 Phi Accrual 故障检测器是一种改进但仍不完美实践建议用实验测量网络延迟分布如 AWS 的混沌工程超时设置为 p99.9 延迟的若干倍接受误判是必然的设计容错机制三、不可靠的时钟1. 时钟的两种类型1墙上时钟Time-of-Day Clock返回当前日期时间与 NTP 同步问题可能跳变NTP 校正、闰秒不同机器可能不同步精度有限2单调时钟Monotonic Clock返回自某起点以来的时间保证单调递增适合测量时间间隔不适合比较不同机器的时间关键区分墙上时钟用于现在几点单调时钟用于过了多久。跨机器比较必须用墙上时钟但墙上时钟不可靠。2. 时钟同步的问题NTP 同步有误差毫秒到秒级网络延迟导致同步不准闰秒导致时间跳变虚拟机时钟可能被暂停Kleppmann 的警告不要用时间戳来决定分布式系统中的事件顺序。时钟不可靠时间戳不能作为全局顺序的依据。3. 依赖时钟的陷阱1最后写入胜出LWW用时间戳解决冲突问题时钟不同步可能丢掉更晚的写入代表Cassandra2时间戳作为事务 ID问题时钟回拨导致 ID 重复或乱序解决混合逻辑时钟HLC3租约Lease用时间保证我在这段时间内是主节点问题时钟漂移导致租约失效可能脑裂4. 时钟的合理使用测量时间间隔用单调时钟跨机器排序用逻辑时钟Lamport 时钟、版本向量需要时间戳时用 HLC或接受不精确四、进程暂停1. 进程可能随时暂停原因GC 停顿Java 等语言的 GC 可能停顿数秒虚拟机暂停迁移、快照、宿主机资源紧张CPU 调度操作系统可能抢占磁盘 I/O 阻塞慢磁盘导致进程挂起后果进程在暂停期间对外界来说像是挂了恢复后可能发现世界已经变了租约过期、锁被释放、主节点被切换2. 进程暂停的经典场景场景租约续期节点 A 持有租约需要定期续期A 发生 GC 停顿错过续期节点 B 认为 A 挂了接管A 恢复后仍以为自己持有租约脑裂场景分布式锁节点 A 获取锁正在操作A 停顿锁超时释放节点 B 获取锁开始操作A 恢复继续操作数据损坏Kleppmann 的结论进程暂停是分布式系统中最容易被忽视的问题。任何依赖进程会在预期时间内响应的设计都是脆弱的。3. 应对进程暂停Fencing Token给每个锁请求一个递增编号存储层拒绝旧编号的写入租约 心跳但仍有窗口减少依赖尽量设计无状态服务GC 调优减少停顿时间五、知识、真相与谎言1. 分布式系统的根本问题你无法知道另一个节点在想什么。它可能挂了它可能活着但网络不通它可能活着但被暂停它可能活着但状态错误这就是分布式系统的知识问题在一个分布式系统中每个节点只能根据自己的局部信息做判断而这些信息可能是不完整、不准确的。2. 主节点与真相问题谁来决定谁是主节点主节点自己认为自己是主节点从节点可能认为主节点挂了没有全局的真相解决共识算法Paxos、Raft通过多数派投票决定但多数派也可能被网络分区分裂3. 拜占庭故障Byzantine Fault定义节点可能发送错误、矛盾、恶意的消息。普通故障节点崩溃或停止响应拜占庭故障节点继续运行但行为异常应对拜占庭容错算法PBFT、PoW区块链场景常用但代价高大多数系统假设无拜占庭故障Kleppmann 的提醒大多数分布式系统假设节点是诚实的但可能崩溃只有少数场景如区块链需要处理拜占庭故障。4. 系统模型为了讨论分布式算法需要定义系统模型1网络模型可靠网络消息不丢但有延迟公平丢失网络消息可能丢但最终送达不可靠网络消息可能丢不保证送达2节点模型崩溃-停止节点崩溃后永久停止崩溃-恢复节点可能崩溃后恢复拜占庭节点可能任意行为3时间模型同步系统网络延迟和时钟有上限异步系统无时间假设部分同步大部分时间同步偶尔异步Kleppmann 的实践观点真实系统大多是部分同步的。算法设计要在异步模型下正确在同步模型下高效。六、本章的核心思想总结主题核心观点网络不可靠无法区分慢和死超时是唯一手段网络分区必然发生脑裂是最大风险时钟墙上时钟不可靠不能用于全局排序进程暂停GC、虚拟机、调度都可能暂停进程导致租约失效知识问题节点只能基于局部信息判断没有全局真相系统模型网络、节点、时间模型是讨论分布式算法的前提三个贯穿全书的判断分布式系统的根本困难是不确定性你无法确定另一个节点的状态也无法确定自己的判断是否正确。时钟和网络不可靠是设计约束而非 bug任何依赖它们建立全局秩序的设计都是脆弱的。进程暂停是最隐蔽的敌人它让看起来正常的节点实际上已经失去同步。七、这一章在全书中地位第八章是从能用到可靠的转折点第五章数据复制复制滞后和冲突根源是网络和时钟不可靠第六章数据分区再平衡和路由依赖网络和协调服务第七章事务分布式事务面临网络分区和进程暂停第九章一致性与共识在第八章的不确定性之上建立一致性和共识第十章批处理、第十一章流处理大规模数据处理同样面临这些问题一句话概括本章分布式系统没有全局真相。网络不可靠、时钟不可靠、进程可能暂停节点只能基于局部信息做判断。理解这些根本性挑战才能理解为什么分布式算法如此复杂以及为什么简单的分布式系统往往不可靠。这一章为第九章的一致性与共识奠定了问题基础。
返回列表