第七章 设计分布式系统中的唯一标识符生成器
传统单机数据库中往往使用auto_increment属性的主键作为ID,但由于不同机器的重复性,该方案在分布式环境中不生效。
总体设计流程
- 了解问题并且确定设计范围,假定具有以下特性
- 唯一标识符具有唯一性
- 按日期排序
- 只包含数字
- 64位
- 每秒可生成10000个
- 提出设计并且获得批准
- 多主复制
- 通用唯一标识符(UUID)
- 票务服务器
- Twitter雪花方法
多主复制
针对单机各自生成自增ID会重复的缺陷,将其改进为每个机器的ID增加为总的机器数N。
但是其具有一些缺点:
- 难以扩展到大数量服务器的情况
- 多服务器之间的ID不能比较时间
- 不能服务器数量变化的情况
通用唯一标识符
通用唯一标识符(UUID)是另一种获取唯一ID的简单方法,UUID为128位的数字。由维基百科可知每秒生成10亿个UUID持续生成100年才有50%概率获取到一个重复的。
UUID在分布式系统上的应用就是给每个web服务器配置一个ID服务器,让其独立生成ID。
优点:
- 生成简单,不需要协调,不会出现同步问题
- 容易扩展,只需要配置新的生成器
缺点:
- ID长度为128位
- ID不随时间变化
- ID可能为非数字
票务生成器
票务生成器是Flocker开发用于生成分布式主键的应用。其思想史使用单个数据库服务器(TicketServer)中的集中式自增功能。
优点:
- 数字ID
- 单机控制ID易于实现,适合中小规模应用程序
缺点:
- 不抗单点故障,单个票务服务器如果崩溃,所有服务都会瘫痪,但引入多个票务服务器又会出现同步问题
可参考flicker的工程博客
雪花方法
Twitter独特的ID生成系统“雪花”使用了分而治之的思想。其将64位ID分解为多个部分,常见示例为:
- 1bit:符号位,始终为0,保留使用
- 41bit:自特定纪元以来的毫秒数,默认为2010 年 11 月 04 日,01:42:54
- 5bit:数据中心ID,此处为32个
- 5bit:机器ID,此处为32个
- 12bit:序号ID,对于在机器/进程上生成的每个ID,序号增加1,每毫秒重置为0,此处为4096个
雪花方法是目前所有方法中最满足需求的。如果深挖该方法还有几个可以探索的方向:
- 时钟同步:本章假设所有服务器时钟相同,实际上在多服务器的时间并不同步,解决该问题最流行的方案是时间时钟协议
- 各段部分的长度调整:例如较少序列号但更多时间戳对于低并发的长期应用更有效
- 高可用性:关注其实际的可用性
2025年7月16日阅读随笔
浙公网安备 33010602011771号