本文主要來聊聊分佈式id的生成方案。html
業務系統須要什麼樣的ID生成器中提出了幾點目標:java
對於每一個標識,都須要有一個命名空間(namespace),來保證其相對惟一性。
分佈式的ID生成,以Twitter Snowflake爲表明的, Flake 系列算法採用的就是劃分命名空間並行生成的思路。git
UUID(Universally Unique Identifier)的標準型式包含32個16進制數字(每一個字符0-F的字符表明4bit,共128bit
),以連字號分爲五段,形式爲8-4-4-4-12的32+4個字符。
好比bc96c351-bea3-4e53-b0a8-d9806763dd69。
主要的格式以下:github
version 4 基於隨機數的算法,也是JDK裏的算法,無論原來各個位的含義了,除了少數幾個位必須按規範填,其他所有用隨機數表達。算法
經過「時間+機器碼+pid+inc」共12個字節,經過4+3+2+3的方式最終標識成一個24長度的十六進制字符。ObjectId是一個12字節 BSON 類型數據,有如下格式:spring
個64 bits的惟一long型的ID,使用其中41bit做爲毫秒數,10bit做爲機器編號,12bit做爲毫秒內序列號。IdWorkermongodb
+---------------+----------------+----------------+ |timestamp(ms)42 | worker id(10) | sequence(12) | +---------------+----------------+----------------+ id = timestamp | workerid | sequence (eg. 1451063443347648410)
默認採用上圖字節分配方式:數據庫
snowflake生成的ID總體上按照時間自增排序,而且整個分佈式系統內不會產生ID碰撞(由datacenter和workerId做區分),而且效率較高。這個算法單機每秒內理論上最多能夠生成1000*(2^12),也就是400W的ID。springboot
Boundary flakeID 長度擴展到 128 bits:架構
+---------------+----------------+----------------+ |timestamp(ms)64 | worker id(48) | sequence(16) | +---------------+----------------+----------------+ id = timestamp | workerid | sequence
因爲它用 48 bits 做爲 Worker ID, 和 Mac 地址的長度同樣, 這樣啓動時不須要和 Zookeeper 通信獲取 Worker ID. 作到了徹底的去中心化
它這樣作的目的是用更多的 bits 實現更小的衝突機率, 這樣就支持更多的 Worker 同時工做. 同時, 每毫秒能分配出更多的 ID
simpleflake取消 Worker 號, 保留 41 bits 的 Timestamp, 同時把 sequence number 擴展到 22 bits
+---------------+----------------+ |timestamp(ms)42 | sequence(22) +---------------+----------------+ id = timestamp | sequence
Simpleflake 的特色:
+---------------+----------------+----------------+ |timestamp(ms)29 | worker id(22) | sequence(13) | +---------------+----------------+----------------+ id = sign + delta seconds | workerid | sequence
delta seconds (28 bits)前時間,相對於時間基點"2016-05-20"的增量值,單位:秒,最多可支持約8.7年