一致性权衡
强一致与最终一致间的 CAP/PACELC 选择,及如何按数据类型选。
为什么
强一致(线性读)易推理但分区下限可用和延迟。最终一致快且总可用但让读到旧数据,若你假设了新就是 bug。权衡非全局——按数据类型:银行余额需强一致(透支是法律问题),浏览计数容最终(2 秒旧计数行)。按数据类型显式选防两种失败:过度要强一致(慢、不可用)和不足要(过时 bug)。
何时使用
数据建模时,按数据类型。每类 30 分钟。过时 bug 或可用问题出现时重访。
如何做
1. 每数据类型问:"读到 2 秒旧数据有何害?" - 无害(浏览计数、排行榜)→ 最终一致行 - 烦人(资料更新)→ 短滞后(1 秒)最终行 - 有害(余额、库存、权限)→ 需强一致 2. 强一致数据用单写者(DB 主)和线性读 3. 最终数据用读副本/异步复制配文档化的过时界 4. 若混,每读标一致级别让调用者知所得 5. 测最终路径:注入 2 秒复制滞后确认应用仍正确
示例
数据类型及一致:
account_balance → 强(透支 = 法律问题)——读主
product_inventory → 强(超卖 = 退单)——读主,写锁
user_profile → 最终,<1 秒滞后——读副本
view_count → 最终,<5 秒滞后——读副本,批量增
search_index → 最终,<30 秒滞后——异步重索引,可接受
混读端点:
GET /v1/account → { balance(强),profile(最终,~0.5 秒旧)}常见问题
- ⚠一切默认强一致——副本滞后时系统慢且不可用,为不需新的数据。
最佳实践
- ✓为每个最终一致读文档化过时界——"最终"不是规格;"<2 秒"是。
- ✓把一致选择放数据模型文档,防未来工程师"修"强一致要求加缓存。