Appearance
第1章:系统模型、故障与 RPC
独立状态与局部观察
单机函数调用通常能直接判断调用是否返回;远程调用超时只能说明未在期限内收到响应。服务器可能没收到请求、正在执行、已执行但响应丢失,或已经崩溃。
网络与服务端故障无法只凭一次超时区分。故障检测器给出的“怀疑”需要协议容忍误判,不能直接当作关于远端永久死亡的事实。
| 机制 | 保存的状态 | 主要问题 |
|---|---|---|
| RPC | 请求 ID、重试、结果 | 一次远端操作如何被识别 |
| 复制 | 日志、版本、提交位置 | 多份状态怎样保持关系 |
| 共识 | 任期或轮次、投票 | 对某项决定形成一致结果 |
| 事务 | 读写集、锁、准备状态 | 跨操作原子性与隔离 |
| 分片 | 所有权、配置版本 | 数据由谁负责,如何迁移 |
时间模型
同步模型对消息延迟和处理速度给出已知上界;异步模型不提供这种上界;部分同步允许系统最终进入足够稳定的时期,或上界存在但事先未知。
很多协议的安全性不依赖正常时间界,活性却需要最终能够通信和有足够稳定的领导者。把这两种保证分开,可以解释系统为何在分区时停止服务却没有返回矛盾数据。
重试与去重
客户端给请求附上稳定 ID,重试时使用同一 ID。服务器持久保存“ID 对应的结果”,重复请求直接返回旧结果。但去重记录必须与业务修改原子关联。
若先扣款、再保存 ID,中间崩溃后重试会再次扣款;若先保存成功 ID、再扣款,中间崩溃又可能返回成功却未执行。
“至多一次”通常意味着不重复执行,不保证一定执行;“至少一次”通常意味着在通信与重试条件满足时最终执行,可能重复。端到端恰好一次效果需要具体存储、原子性和身份假设,不是网络自动提供的选项。
练习
- 列出一次 RPC 超时后服务端可能处于的状态。
- 请求 ID 为什么在重试时不能重新生成?
- 去重记录何时能安全删除?说明必须知道哪些客户端进度或时间边界。