ID生成服务

业务系统对ID的要求

  1. 全局唯一性
  2. 趋势递增,保证有序
  3. 单调递增,保证下一个ID一定大于上个ID,满足排序等
  4. 无规则不规则,保证信息安全,不能连续,防止扒取,比如订单号可以计算单量
  5. 高可用性,一崩全崩
  6. 低延迟,高性能(QPS)

常见方法

UUID(Universally Unique Identifier)

标准型式包含32个16进制数字,以连字号分为五段,形式为8-4-4-4-12的36个字符,示例:550e8400-e29b-41d4-a716-446655440000,到目前为止业界一共有5种方式生成UUID

  • 优点:性能高,本地生成,无网络消耗
  • 缺点
    • 不易于存储:UUID太长
    • 不安全:基于MAC地址生成UUID的算法可能会导致MAC地址泄露
    • ID作为主键时在特定的环境会存在一些问题,比如做DB主键的场景下,UUID就非常不适用。MYSQL官方建议主键越短越好

类snowflake方案

以划分命名空间来生成ID的一种算法,这种方案把64-bit分别划分成多段,分开来标示机器、时间 0 - 00000000 00000000 00000000 00000000 0 - 00000000 00 - 00000000 0000 41-bit的时间可以表示(1L<<41)/(1000L360024*365)=69年的时间,10-bit机器可以分别表示1024台机器。如果我们对IDC划分有需求,还可以将10-bit分5-bit给IDC,分5-bit给工作机器。这样就可以表示32个IDC,每个IDC下可以有32台机器,可以根据自身需求定义。12个自增序列号可以表示2^12个ID,理论上snowflake方案的QPS约为409.6w/s,这种分配方式可以保证在任何一个IDC的任何一台机器在任意毫秒内生成的ID都是不同的

  • 优点
    • 毫秒在高位,自增序列在低位,ID趋势递增
    • 不依赖数据库等第三方系统,以服务方式部署,稳定性高,性能也高
    • 可以根据自身业务分配bit位,灵活
  • 缺点
    • 强依赖机器时钟,如果机器时钟回拨,导致发号重复或服务不可用

数据库生成

  • 优点

    • 非常简单,利用现有数据库系统的功能实现,成本小,有DBA专业维护。
    • ID号单调自增,可以实现一些对ID有特殊要求的业务。
  • 缺点

    • 强依赖DB,当DB异常时整个系统不可用,属于致命问题。配置主从复制可以尽可能的增加可用性,但是数据一致性在特殊情况下难以保证。主从切换时的不一致可能会导致重复发号。
    • ID发号性能瓶颈限制在单台MySQL读写性能

    对于MySQL性能问题,可用如下方案解决:在分布式系统中我们可以多部署几台机器,每台机器设置不同的初始值,且步长和机器数相等。比如有两台机器。设置步长step为2,TicketServer1的初始值为1(1,3,5,7,9,11...)、TicketServer2的初始值为2(2,4,6,8,10...)。

    这种架构貌似能够满足性能的需求,但有以下几个缺点:

    1. 系统水平扩展比较困难,比如定义好了步长和机器台数之后,如果要添加机器该怎么做
    2. ID没有了单调递增的特性,只能趋势递增,这个缺点对于一般业务需求不是很重要,可以容忍
    3. 数据库压力还是很大,每次获取ID都得读写一次数据库,只能靠堆机器来提高性能。

Leaf方案实现

Leaf-segment数据库方案

    • 原方案每次获取ID都得读写一次数据库,造成数据库压力大。改为利用proxy server批量获取,每次获取一个segment(step决定大小)号段的值。用完之后再去数据库获取新的号段,可以大大的减轻数据库的压力。
    • 各个业务不同的发号需求用biz_tag字段来区分,每个biz-tag的ID获取相互隔离,互不影响。如果以后有性能需求需要对数据库扩容,不需要上述描述的复杂的扩容操作,只需要对biz_tag分库分表就行。
  • 数据库表设计如下:
Field
Type
biz_tag varchar(128)
max_id bigint(20)
step int(11)
desc varchar(256)
update_time timestamp

重要字段说明:biz_tag用来区分业务,max_id表示该biz_tag目前所被分配的ID号段的最大值,step表示每次分配的号段长度。原来获取ID每次都需要写数据库,现在只需要把step设置得足够大,比如1000。那么只有当1000个号被消耗完了之后才会去重新读写一次数据库。读写数据库的频率从1减小到了1/step

  • 优点:
    • Leaf服务可以很方便的线性扩展,性能完全能够支撑大多数业务场景。 ID号码是趋势递增的8byte的64位数字,满足上述数据库存储的主键要求。
    • 容灾性高:Leaf服务内部有号段缓存,即使DB宕机,短时间内Leaf仍能正常对外提供服务。
    • 可以自定义max_id的大小,非常方便业务从原有的ID方式上迁移过来。
  • 缺点:
    • ID号码不够随机,能够泄露发号数量的信息,不太安全。
    • TP999数据波动大,当号段使用完之后还是会hang在更新数据库的I/O上,tg999数据会出现偶尔的尖刺。
    • DB宕机会造成整个系统不可用。

原文 Leaf—美团点评分布式ID生成系统

同类文章:分布式ID生成器

猜你喜欢

转载自www.cnblogs.com/chen-qiang/p/10139081.html