美團發號器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時間間隔