雪花ID
雪花ID
在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识。如在美团点评支付系统中,数据日渐增长,对数据分库分表后需要有一个唯一 ID 来标识一条数据或消息,数据库的自增 ID 显然不能满足需求;特别一点的如订单、骑手、优惠券也都需要有唯一 ID 做标识。
全局唯一 ID 应当具备什么样的属性,才能够满足上述的场景呢? 美团技术团队列出的 4 点属性我觉得很准确,它们是:
- 全局唯一性:不能出现重复的 ID 号,既然是唯一标识,这是最基本的要求;
- 趋势递增:在 MySQL InnoDB 引擎中使用的是聚集索引,由于多数 RDBMS 使用 B-tree 的数据结构来存储索引数据,在主键的选择上面我们应该尽量使用有序的主键保证写入性能;
- 单调递增:保证下一个 ID 一定大于上一个 ID,例如事务版本号、IM 增量消息、排序等特殊需求;
- 信息安全:如果 ID 是连续的,恶意用户的爬取工作就非常容易做了,直接按照顺序下载指定 URL 即可;如果是订单号就更危险了,竞争对手可以直接知道我们一天的单量。所以在一些应用场景下,会需要 ID 无规则、不规则。
除了以上列举的 ID 属性外,基于这个生成算法构建的服务还需要买足高 QPS、高可用性和低延迟的几个要求。
Twitter开源方案 Snowflake
Twitter 于 2010 年开源了内部团队在用的一款全局唯一 ID 生成算法 Snowflake,翻译过来叫做雪花算法。Snowflake 不借助数据库,可直接由编程语言生成。Snowflake组成如下:
- 最高位占1 bit,值固定为 0,以保证生成的 ID 为正数;
- 中位占 41 bit,值为毫秒级时间戳;
- 中下位占 10 bit,值为工作机器的 ID,值的上限为 1024;
- 末位占 12 bit,值为当前毫秒内生成的不同 ID,值的上限为 4096;
snowflake 不依赖数据库,也不依赖内存存储,随时可生成 ID,这也是它如此受欢迎的原因。但因为它在设计时通过时间戳来避免对内存和数据库的依赖,所以它依赖于服务器的时间。
但如果服务器的时间发生了错乱或者回拨,这就直接影响到生成的 ID,有很大概率生成重复的 ID 且一定会打破递增属性。
美团技术方案 Leaf
暂时没有理解,先放着
License:
CC BY 4.0