SnowFlake 雪花算法(Java實現)

SnowFlake 雪花算法

SnowFlake算法生成的ID大致上是按照時間遞增的,用在分佈式系統中時,需要注意數據中心標識和機器標識必須唯一,這樣就能保證每個節點生成的ID都是唯一的。它可以滿足Twitter每秒上萬條消息ID分配的請求,這些消息ID是唯一的且有大致的遞增順序,且是一個64位整形,即8字節,可以展示為一個Long類型的整數。結構如下(每一部分用“-”符號分隔):

SnowFlake 雪花算法(Java實現)

  • 1位標識部分,在java中由於long的最高位是符號位,正數是0,負數是1,一般生成的ID為正數,所以為0;
  • 41位時間戳部分,這個是毫秒級的時間,一般實現上不會存儲當前的時間戳,而是時間戳的差值(當前時間-固定的開始時間),這樣可以使產生的ID從更小值開始;41位的時間戳可以使用69年,(1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69年;
  • 10位節點部分,Twitter實現中使用前5位作為數據中心標識(Data Center ID),後5位作為機器標識(Worker ID),可以部署1024個節點;
  • 12位序列號部分,支持同一毫秒內同一個節點可以生成4096個ID;

Snowflake算法核心

把時間戳,工作機器id,序列號組合在一起。

SnowFlake 的優點如下:

  • 比UUID 短,一般為9-17位。
  • 生成的ID是數字,可以做到單調遞增。由於無法統一分佈式環境中每臺服務器的時鐘,它只能做到單臺機器單調遞增,無法做到全局遞增。
  • 性能非常出色,吞吐量達到幾十萬TPS。

應用場景

參考上面的SnowFlake的優點,對應的應用場景如下。

1、數據庫表主鍵:很多DBA在大型生產應用禁用auto_increment的ID,這時可以選SnowFlake替代。

2、TraceId:分佈式系統追蹤,希望用一個ID貫穿所有子系統來追蹤分佈式交互過程。如果系統產生一個Exception,我們需要對Exception編號等。

3、短時間內訪問特別大,需要生成大量的唯一ID。

SnowFlake算法,Java版源代碼

Github 源碼地址:

https://github.com/rickiechina/CloudNative/blob/master/common/src/main/java/com/cloudnative/common/SnowflakeIdWorker.java

在具體的業務場景中,可以將上述代碼進一步封裝。

如想基於不同的table name,或者業務創建,實例化不同SnowflakeIdWorker 對象,然後存放在HashMap,在調用時,取出對應SnowflakeIdWorker對象,調用nextId() 方法。

Twitter 官方code:

https://github.com/twitter-archive/snowflake

SnowFlake 雪花算法(Java實現)


分享到:


相關文章: