分佈式id生成方案概述

本文主要來聊聊分佈式id的生成方案。html

目標

業務系統須要什麼樣的ID生成器中提出了幾點目標:java

  • 惟一性
  • 時間相關
  • 粗略有序
  • 可反解
  • 可製造

主要思路

對於每一個標識,都須要有一個命名空間(namespace),來保證其相對惟一性。
分佈式的ID生成,以Twitter Snowflake爲表明的, Flake 系列算法採用的就是劃分命名空間並行生成的思路。git

UUID

UUID(Universally Unique Identifier)的標準型式包含32個16進制數字(每一個字符0-F的字符表明4bit,共128bit),以連字號分爲五段,形式爲8-4-4-4-12的32+4個字符。
好比bc96c351-bea3-4e53-b0a8-d9806763dd69。
主要的格式以下:github

  • 時間戳+UUID版本號,分三段佔16個字符(60bit+4bit),
  • Clock Sequence號與保留字段,佔4個字符(13bit+3bit),
  • 節點標識佔12個字符(48bit),

version 4 基於隨機數的算法,也是JDK裏的算法,無論原來各個位的含義了,除了少數幾個位必須按規範填,其他所有用隨機數表達。算法

mongo object id

經過「時間+機器碼+pid+inc」共12個字節,經過4+3+2+3的方式最終標識成一個24長度的十六進制字符。ObjectId是一個12字節 BSON 類型數據,有如下格式:spring

  • 4個字節表示的Unix timestamp
  • 3個字節表示的機器的ID
  • 2個字節表示的進程ID
  • 3個字節表示的計數器

snow flake算法

個64 bits的惟一long型的ID,使用其中41bit做爲毫秒數,10bit做爲機器編號,12bit做爲毫秒內序列號。IdWorkermongodb

+---------------+----------------+----------------+
|timestamp(ms)42  | worker id(10) | sequence(12)  |
+---------------+----------------+----------------+

id  = timestamp | workerid | sequence (eg. 1451063443347648410)

默認採用上圖字節分配方式:數據庫

  • 第一位爲未使用,接下來的41位爲毫秒級時間(41位的長度可使用69年)
  • 5位datacenterId和5位workerId(10位的長度最多支持部署1024個節點)
  • 12位是毫秒內的計數(12位的計數順序號支持每一個節點每毫秒產生4096個ID序號)

snowflake生成的ID總體上按照時間自增排序,而且整個分佈式系統內不會產生ID碰撞(由datacenter和workerId做區分),而且效率較高。這個算法單機每秒內理論上最多能夠生成1000*(2^12),也就是400W的ID。springboot

snow flake算法變種

Boundary flake

Boundary flakeID 長度擴展到 128 bits:架構

+---------------+----------------+----------------+
|timestamp(ms)64  | worker id(48) | sequence(16)  |
+---------------+----------------+----------------+
id  = timestamp | workerid | sequence
  • 最高 64 bits 時間戳;
  • 而後是 48 bits 的 Worker 號 (和 Mac 地址同樣長);
  • 最後是 16 bits 的 Seq Number

因爲它用 48 bits 做爲 Worker ID, 和 Mac 地址的長度同樣, 這樣啓動時不須要和 Zookeeper 通信獲取 Worker ID. 作到了徹底的去中心化
它這樣作的目的是用更多的 bits 實現更小的衝突機率, 這樣就支持更多的 Worker 同時工做. 同時, 每毫秒能分配出更多的 ID

Simple flake

simpleflake取消 Worker 號, 保留 41 bits 的 Timestamp, 同時把 sequence number 擴展到 22 bits

+---------------+----------------+
|timestamp(ms)42  | sequence(22) 
+---------------+----------------+
id  = timestamp | sequence

Simpleflake 的特色:

  • sequence number 徹底靠隨機產生 (這樣也致使了生成的 ID 可能出現重複)
  • 沒有 Worker 號, 也就不須要和 Zookeeper 通信, 實現了徹底去中心化
  • Timestamp 保持和 Snowflake 一致, 從此能夠無縫升級到 Snowflake
    缺點:
  • 生成的 ID 重複的可能. 這個生成 ID 重複的機率隨着每秒生成的 ID 數的增加而增加。
  • 每秒生成的 ID 不能太多 (最好小於 100次/秒, 若是大於 100次/秒的場景, Simpleflake 就不適用

百度惟一id

UidGenerator

+---------------+----------------+----------------+
|timestamp(ms)29  | worker id(22) | sequence(13)  |
+---------------+----------------+----------------+
id  = sign + delta seconds | workerid | sequence
  • timestap
    sign(1bit)固定1bit符號標識,即生成的UID爲正數。

delta seconds (28 bits)前時間,相對於時間基點"2016-05-20"的增量值,單位:秒,最多可支持約8.7年

  • worker id (22 bits)
    機器id,最多可支持約420w次機器啓動。內置實現爲在啓動時由數據庫分配,默認分配策略爲用後即棄,後續可提供複用策略。
  • sequence (13 bits)
    每秒下的併發序列,13 bits可支持每秒8192個併發。

doc

相關文章
相關標籤/搜索