第七章 设计分布式系统中的唯一标识符生成器

传统单机数据库中往往使用auto_increment属性的主键作为ID,但由于不同机器的重复性,该方案在分布式环境中不生效。

总体设计流程

  1. 了解问题并且确定设计范围,假定具有以下特性
    • 唯一标识符具有唯一性
    • 按日期排序
    • 只包含数字
    • 64位
    • 每秒可生成10000个
  2. 提出设计并且获得批准
    • 多主复制
    • 通用唯一标识符(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日阅读随笔

posted @ 2025-07-17 00:19  tanch25  阅读(12)  评论(0)    收藏  举报