介绍了在集群节点之间建立有效网络通信的技巧。
介绍了常用的分区方案,并深入研究两阶段提交协议的复杂性。
介绍了数据库中逻辑时间戳的使用,以帮助读者理解数据版本控制的基本概念。
阐述了Paxos和Raft等共识算法的构建块,以确保分布式系统中副本的一致性。
阐述了用于实现集群协调任务(如组成员资格、故障检测以及健壮的集群协调)的机制。
涵盖了数据复制模式、数据分区模式、分布式时间模式、集群管理模式以及节点间通信模式等内容。
本书深入剖析了主流开源分布式系统模式,包括模式中的常见问题和解决方案,并展示了Kafka和Kubernetes等系统的真实代码示例,以帮助企业架构师和开发人员更好地理解这些系统的工作原理,以及分布式系统的设计原则,为应对数据存储在多台服务器上时可能出现的各种问题做好准备。
通过阅读本书,读者将:
了解什么是分布式系统,以及为什么需要分布式系统。
更深入地理解分布式系统模式设计所面临的挑战,以选择合适的云服务和产品。
理解包括数据库、内存数据网格、消息代理,以及各种云服务在内的系统的实现原理。
自信地浏览开源代码库,并清晰地看到模式和解决方案如何映射到如Kafka和Kubernetes这样的真实世界系统中。
本书对于分布式架构工程师以及想要构建自己的分布式系统的开发者来说,是一本有价值的参考书。
译者序
推荐序
前言
致谢
第一部分 概述
第1章 分布式系统 2
1.1 单服务器的限制 3
1.2 业务逻辑和数据层分离 4
1.3 数据分区 4
1.4 故障观察 5
1.5 复制:屏蔽故障 6
1.5.1 进程终止甚至崩溃 6
1.5.2 网络延迟 6
1.5.3 进程暂停 6
1.5.4 时钟不同步 7
1.6 定义分布式系统 7
1.7 模式方法 7
第2章 模式概述 9
2.1 在单服务器上保持数据的弹性 10
2.2 竞争性更新 11
2.3 处理主节点失效 12
2.4 依托“世代时钟”解决多节点故障问题 14
2.5 符合仲裁机制方可提交日志记录 17
2.6 从节点基于高水位标记提交 19
2.7 主节点用消息队列来保持对众多客户端的响应 23
2.8 由从节点处理读请求以减轻主节点的负担 29
2.9 把大量数据分散到多节点分区 30
2.10 通过复制分区提高集群弹性 32
2.11 跨分区维持一致性至少需要两个阶段 33
2.12 分布式系统的顺序不能依赖于系统时间戳 35
2.13 一致性核心负责管理数据集群的成员资格 42
2.14 使用Gossip传播机制来管理分布式集群 45
第二部分 数据复制模式
第3章 预写日志 53
3.1 问题的提出 54
3.2 解决方案 54
3.2.1 实现考虑 56
3.2.2 在事务存储中的使用 56
3.2.3 与事件溯源对比 57
3.3 示例 58
第4章 日志分段 59
4.1 问题的提出 60
4.2 解决方案 60
4.3 示例 61
第5章 低水位标记 62
5.1 问题的提出 63
5.2 解决方案 63
5.2.1 基于快照的低水位标记 63
5.2.2 基于时间的低水位标记 64
5.3 示例 65
第6章 主节点与从节点 66
6.1 问题的提出 67
6.2 解决方案 67
6.2.1 主节点选举 67
6.2.2 仅有多数读/写不足以提供强一致性保证 72
6.3 示例 72
第7章 心跳机制 73
7.1 问题的提出 74
7.2 解决方案 74
7.2.1 小型集群:基于共识算法的系统 75
7.2.2 技术考虑 76
7.2.3 大型集群:基于Gossip协议 76
7.3 示例 77
第8章 多数法定节点数 78
8.1 问题的提出 79
8.2 解决方案 79
8.2.1 决定集群中服务器的数量 79
8.2.2 灵活的多数法定节点数 80
8.3 示例 81
第9章 世代时钟 82
9.1 问题的提出 83
9.2 解决方案 83
9.3 示例 86
第10章 高水位标记 87
10.1 问题的提出 88
10.2 解决方案 88
10.3 示例 92
第11章 Paxos 93
11.1 问题的提出 94
11.2 解决方案 94
11.2.1 协议流程 94
11.2.2 键值存储示例 101
11.2.3 弹性Paxos 105
11.3 示例 105
第12章 复制日志 106
12.1 问题的提出 107
12.2 解决方案 107
12.2.1 Multi-Paxos和Raft 107
12.2.2 复制客户端请求 108
12.2.3 主节点选举 113
12.2.4 技术考虑 118
12.2.5 推送与拉取 120
12.2.6 日志中有什么 120
12.3 示例 125
第13章 单一更新队列 126
13.1 问题的提出 127
13.2 解决方案 127
13.2.1 队列的选择 130
13.2.2 使用通道和轻量级线程 131
13.2.3 限流 131
13.2.4 其他考虑 132
13.3 示例 132
第14章 请求等待列表 133
14.1 问题的提出 134
14.2 解决方案 134
14.3 示例 139
第15章 幂等接收器 140
15.1 问题的提出 141
15.2 解决方案 141
15.2.1 使已保存的客户端请求过期 144
15.2.2 移除已注册的客户端 145
15.2.3 最多一次、至少一次和恰好一次操作 145
15.3 示例 146
第16章 由从节点处理读请求 147
16.1 问题的提出 148
16.2 解决方案 148
16.2.1 寻找最近的副本 148
16.2.2 连接断开或慢速从节点 151
16.2.3 读写一致性 151
16.2.4 线性化读 154
16.3 示例 154
第17章 版本化值 155
17.1 问题的提出 156
17.2 解决方案 156
17.2.1 版本化键的排序 156
17.2.2 读多个版本 159
17.2.3 MVCC和事务隔离性 160
17.2.4 使用类似RocksDB的存储引擎 161
17.3 示例 162
第18章 版本向量 163
18.1 问题的提出 164
18.2 解决方案 164
18.2.1 版本向量比较 165
18.2.2 在键值存储中使用版本向量 167
18.3 示例 174
第三部分 数据分区模式
第19章 固定分区 177
19.1 问题的提出 178
19.2 解决方案 178
19.2.1 选择哈希函数 179
19.2.2 将分区映射到集群节点 179
19.2.3 替代方案:分区数量与节点数量成比例 190
19.3 示例 195
第20章 键范围分区 196
20.1 问题的提出 197
20.2 解决方案 197
20.2.1 预定义键范围 197
20.2.2 示例场景 200
20.2.3 自动分割范围 201
20.3 示例 206
第21章 两阶段提交 207
21.1 问题的提出 208
21.2 解决方案 208
21.2.1 锁和事务隔离性 210
21.2.2 提交和回滚 216
21.2.3 示例场景 220
21.2.4 使用版本化值 225
21.2.5 使用复制日志 234
21.2.6 故障处理 234
21.2.7 异构系统中的事务 238
21.3 示例 239
第四部分 分布式时间的模式
第22章 Lamport时钟 243
22.1 问题的提出 244
22.2 解决方案 244
22.2.1 因果关系、时间和先后关系 245
22.2.2 键值存储示例 245
22.2.3 部分有序 247
22.2.4 单个主节点更新值 247
22.3 示例 248
第23章 混合时钟 249
23.1 问题的提出 250
23.2 解决方案 250
23.2.1 使用混合时钟的多版本存储 252
23.2.2 使用时间戳读取值 254
23.2.3 为分布式事务分配时间戳 254
23.3 示例 256
第24章 时钟约束等待 257
24.1 问题的提出 258
24.2 解决方案 259
24.2.1 读请求重启 261
24.2.2 使用时钟约束API 263
24.3 示例 268
第五部分 集群管理模式
第25章 一致性核心 271
25.1 问题的提出 272
25.2 解决方案 272
25.2.1 元数据存储 273
25.2.2 处理客户端交互 274
25.3 示例 276
第26章 租约 277
26.1 问题的提出 278
26.2 解决方案 278
26.2.1 将租约附加到键值存储中的键上 282
26.2.2 处理主节点失效 284
26.3 示例 285
第27章 状态监控 286
27.1 问题的提出 287
27.2 解决方案 287
27.2.1 客户端实现 287
27.2.2 服务器端实现 288
27.2.3 处理连接失败 290
27.3 示例 292
第28章 Gossip传播 293
28.1 问题的提出 294
28.2 解决方案 294
28.2.1 避免不必要的状态交换 298
28.2.2 选择Gossip节点的标准 300
28.2.3 群组成员资格和故障检测 300
28.2.4 处理节点重启 301
28.3 示例 301
第29章 应急主节点 302
29.1 问题的提出 303
29.2 解决方案 303
29.2.1 向所有现有成员发送成员资格更新 306
29.2.2 示例场景 308
29.2.3 处理缺失的成员资格更新 310
29.2.4 故障检测 311
29.2.5 与主从模式的比较 316
29.3 示例 316
第六部分 节点间通信模式
第30章 单套接字通道 319
30.1 问题的提出 320
30.2 解决方案 320
30.3 示例 322
第31章 请求批处理 323
31.1 问题的提出 324
31.2 解决方案 324
31.3 示例 328
第32章 请求管道 329
32.1 问题的提出 330
32.2 解决方案 330
32.3 示例 332
参考文献 333