leaf是美团 推出的一个分布式ID生成服务,名字取自德国哲学家、数学家莱布尼茨的一句话:“There are no two identical leaves in the world.”Leaf具备高可靠、低延迟、全局唯一等特点在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识,对数据分库分表后需要有一个唯一ID来标识一条数据或消息

重写getid方法

QQ截图20230703233118

1
2
3
4
5
6
7
8
<bean id="idGen" class="com.dianping.pigeon.remoting.invoker.config.spring.ReferenceBean" init-method="init"> 
<property name="url" value="com.sankuai.inf.leaf.thrift.IDGen" />
<property name="interfaceName" value="com.sankuai.inf.leaf.thrift.IDGen$Iface" />
<property name="remoteAppKey" value="${leaf集群appkey}"/>
<property name="timeout" value="1000" />
<property name="callType" value="sync" />
<property name="serialize" value="thrift" />
</bean>

leaf每台服务器会缓存步长号段,如果设置步长是1000,那么每台机器都会缓存1000个ID,如下图。

步长也就是服务器每次回去加载的号段长度,并缓存到leaf服务中。(目前,leaf实现了动态调整步长的功能,会根据号段消费速度动态调整步长大小。)

所以业务得到的id号并不是严格递增的,但是不会出现重复。

drawio(2).svg)

假设路由采用轮询的方式,你的服务得到的id序列如下:

1,1001,2001,2,1002,2002,3,1003,2003,4,1004,2004…………

UUID

  • 优点:生成速度比较快、简单易用
  • 缺点:存储消耗空间大(32 个字符串,128 位)、 不安全(基于 MAC 地址生成 UUID 的算法会造成 MAC 地址泄露)、无序(非自增)、没有具体业务含义、需要解决重复 ID 问题(当机器时间不对的情况下,可能导致会产生重复 ID)

Snowflake(雪花算法)

snowflake算法是一种划分命名空间来生成ID的一种算法,这种方案把64-bit分别划分成多段,分开来标示时间戳、机器、序列号等。

第 0 位:符号位(标识正负),始终为 0,没有用,不用管。

41bit为时间戳,可以表示的时间范围为(1L<<41)/(1000L360024*365)=69年的时间;

10bit为机器id,可用于表示1024台机器;

12bit为自增序列号,可以表示2^12个ID。

64bit的二进制转为long就是snowflake生成的Id。

  • 当通过NTP进行时钟同步时可能会出现重复ID