美团发号器Leaf-snowflake方案node
Leaf-snowflake方案彻底沿用snowflake方案的bit位设计,便是“1+41+10+12”的方式组装ID号。对于workerID的分配,当服务集群数量较小的状况下,彻底能够手动配置。Leaf服务规模较大,动手配置成本过高。因此使用Zookeeper持久顺序节点的特性自动对snowflake节点配置wokerID。Leaf-snowflake是按照下面几个步骤启动的:git
除了每次会去ZK拿数据之外,也会在本机文件系统上缓存一个workerID文件。当ZooKeeper出现问题,刚好机器出现问题须要重启时,能保证服务可以正常启动。这样作到了对三方组件的弱依赖。必定程度上提升了SLAgithub
由于这种方案依赖时间,若是机器的时钟发生了回拨,那么就会有可能生成重复的ID号,须要解决时钟回退的问题。算法
参见上图整个启动流程图,服务启动时首先检查本身是否写过ZooKeeper leaf_forever节点:docker
因为强依赖时钟,对时间的要求比较敏感,在机器工做时NTP同步也会形成秒级别的回退,建议能够直接关闭NTP同步。要么在时钟回拨的时候直接不提供服务直接返回ERROR_CODE,等时钟追上便可。或者作一层重试,而后上报报警系统,更或者是发现有时钟回拨以后自动摘除自己节点并报警数组
京东到家发号器方案缓存
百度发号器方案
UidGenerator是Java实现的, 基于Snowflake算法的惟一ID生成器。UidGenerator以组件形式工做在应用项目中, 支持自定义workerId位数和初始化策略, 从而适用于docker等虚拟化环境下实例自动重启、漂移等场景。 在实现上, UidGenerator经过借用将来时间来解决sequence自然存在的并发限制; 采用RingBuffer来缓存已生成的UID, 并行化UID的生产和消费, 同时对CacheLine补齐,避免了由RingBuffer带来的硬件级「伪共享」问题. 最终单机QPS可达600万。
RingBuffer环形数组,数组每一个元素成为一个slot。RingBuffer容量,默认为Snowflake算法中sequence最大值,且为2^N。可经过boostPower
配置进行扩容,以提升RingBuffer 读写吞吐量。并发
Tail指针、Cursor指针用于环形数组上读写slot:性能
rejectedPutBufferHandler
指定PutRejectPolicyrejectedTakeBufferHandler
指定TakeRejectPolicyCachedUidGenerator采用了双RingBuffer,Uid-RingBuffer用于存储Uid、Flag-RingBuffer用于存储Uid状态(是否可填充、是否可消费)ui
因为数组元素在内存中是连续分配的,可最大程度利用CPU cache以提高性能。但同时会带来「伪共享」FalseSharing问题,为此在Tail、Cursor指针、Flag-RingBuffer中采用了CacheLine 补齐方式。
tail
-cursor
),如小于设定阈值,则补全空闲slots。阈值可经过paddingFactor
来进行配置,请参考Quick Start中CachedUidGenerator配置scheduleInterval
配置,以应用定时填充功能,并指定Schedule时间间隔