Twitter-Snowflake算法产生的背景相当简单,为了满足Twitter每秒上万条消息的请求,每条消息都必须分配一条唯一的id,这些id还需要一些大致的顺序(方便客户端排序),并且在分布式系统中不同机器产生的id必须不同。各种主键ID生成策略对比,见 常见分布式主键ID生成策略
把41位的时间前缀,10位的节点标识,12位的sequence组合在一起。
除了最高位bit标记为不可用以外,其余三组bit占位均可浮动,看具体的业务需求而定。默认情况下41bit的时间戳,1970年算起可以支持该算法使用到2038年,10bit的工作机器id可以支持1024台机器,序列号支持1毫秒产生4096个自增序列id。
snowflake-64bit.jpg
Snowflake是Twitter在2010年用Scala语言写的一套主键生成策略,用Thrift对外发布主键生成服务,其中依赖了Twitter内部的Infrastructure,后来Twitter用Twitter-server代替了Snowflake,自2012年起就未更新。见Twitter-Snowflake项目地址(Tags:snowflake-2010)
之前写了一个Java的实现,改自网上一个版本:Twitter的分布式自增ID算法Snowflake实现分析及其Java、Php和Python版。后来看到当当网的Sharding-JDBC分库分表中间件已实现了此算法。就直接在其中添加了一些新特性,已merge。(具体实现,说明文档)
添加3种IdGenerator实现。
ZkIdGenerator:通过zookeeper维护workerId。使用时需要添加zookeeper客户端curator(curator-framework与curator-recipes)依赖,并设置zkNodes与appName。(将向zookeeper中/snowflake/appName下注册并节点,并通过zookeeper动态维护workerId。)
IPIdGenerator:获取机器的二进制表示的后10位,设置成workerId。(列如机器的IP为192.168.1.108,设置workerId为364。)
HostNameIdGenerator:根据机器名最后的数字编号获取workerId,如果线上机器命名有统一规范,建议使用此种方式(列如机器的HostName为dangdang-db-sharding-dev-12,会截取最后的编号12作为workerId。)
性能
用笔记本(i7-3632QM 2.2GHz 四核八线程)测试了下,每秒生成409万(理论上的峰值),CPU占用率18.5%。
参考:
Twitter-Snowflake,64位自增ID算法详解
Twitter-Snowflake项目地址(Tags:snowflake-2010)
常见分布式主键ID生成策略
当当网的Snowflake(Java)实现使用说明
转载注明出处,我就不和你计较。
by Donney Young
http://www.jianshu.com/p/80e68ae9e3a4
作者:DonneyYoung
链接:http://www.jianshu.com/p/80e68ae9e3a4
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。al-and-quick-reference