知识卡片

非因果序列号生成器的三种方法及问题

普通读书笔记卡

内容

当没有单一主库(多主或无主复制、或分区数据库)时,要给操作分配一个近似递增的全局序列号并不简单,常见有三种非因果方案:一是节点各自独立生成序列号区间(如一个节点只发奇数、另一个只发偶数,或在序列号里预留节点标识位),保证不同节点永不冲突但各自计数器推进速度不同;二是给操作附加日历时钟时间戳,分辨率足够高时能凑出一个近似全序([[写冲突的检测时机与收敛策略最后写入胜利的数据丢失代价]]中的最后写入胜利正是依赖这种方式);三是预先分配序列号区块(如节点A认领1-1000,节点B认领1001-2000),各自在区块内独立分配。这三种都比单主自增计数器更具伸缩性,但都有同一个致命缺陷:生成出的序列号与因果关系不一致——不同节点处理速度不同导致奇偶计数器交错、时钟偏移导致后发生的操作反而拿到更早时间戳、区块划分导致因果更晚的操作被分进了更早的区块。发散:可伸缩性和因果一致性在这里是直接对立的,选哪种方案本质是在问”这个场景到底需不需要保真的因果顺序”。

参考来源

- 位置:《数据密集型应用系统设计》第九章《一致性与共识》"非因果序列号生成器"(源文件:_epub-src/ch9_split_000.html) - 结论依据:原文列举奇偶节点计数器、日历时钟时间戳、预分配序列号区块三种非因果序列号生成方式,并分别说明各自为何与因果关系不一致,直接支撑本卡片的分类总结。 - 原始内容:每个节点都可以生成自己独立的一组序列号……可以将日历时钟的时间戳附加到每个操作上……可以预先分配序列号区块……然而它们都有同一个问题:生成的序列号与因果不一致。