分布式Id生成方案

527 阅读2分钟

1.UUID

缺点:不能满足递增要求,作为数据库主键索引时会引起数据频繁移动

2.snowFlake方案:

第一位为未使用,接下来的41位为毫秒级时间(41位的长度可以使用69年),然后是5位datacenterId和5位workerId(10位的长度最多支持部署1024个节点) ,最后12位是毫秒内的计数(12位的计数顺序号支持每个节点每毫秒产生4096个ID序号

缺点:

  1. 强依赖时钟,如果主机时间回拨,则会造成重复ID,会产生
  2. ID虽然有序,但是不连续

3.基于数据库方案:

性能受限于数据库性能
不利于扩展,扩容需要停机

4.redis中间件

redis单线程的,所以操作为原子操作。利用incr/incrby命令实现原子性的自增可以生成唯一的递增ID

缺点:

  • 依赖于redis,水平扩容困难,配置复杂

  • 需要考虑持久化问题

5.美团的Leaf-segment方案

基于数据库方案改进;每次获取一个segment(step决定大小)号段的值。用完之后再去数据库获取新的号段,可以大大的减轻数据库的压力

好处:

  • Leaf服务可以很方便的线性扩展,性能完全能够支撑大多数业务场景(通过增加step提升性能)

  • ID号码是趋势递增的8byte的64位数字,满足上述数据库存储的主键要求

  • 容灾性高:Leaf服务内部有号段缓存,即使DB宕机,短时间内Leaf仍能正常对外提供服务

  • 可以自定义max_id的大小,非常方便业务从原有的ID方式上迁移过来

缺点:

  • ID号码不够随机,能够泄露发号数量的信息,不太安全

  • TP999数据波动大,当号段使用完之后还是会hang在更新数据库的I/O上,tg999数据会出现偶尔的尖刺

  • DB宕机会造成整个系统不可用

  • Leaf-segment方案可以生成趋势递增的ID,同时ID号是可计算的,但不适用于订单ID生成场景。比如竞对在两天中午12点分别下单,通过订单id号相减就能大致计算出公司一天的订单量,这个是不能忍受的

6.美团的Leaf-snowflake方案:

继承于snowflake,引入zookeeper的顺序节点的特性自动对snowflake节点配置wokerID,并解决时钟问题导致重复id,具体的方案是通过计算和各个机器的时钟的误差值,来确定当前节点的时钟是否可用。

美团的Leaf-snowflake