單機資料庫的 auto_increment 在分散式環境不管用。難點在於跨多台機器、以最小延遲產生唯一且可排序的 ID。
📋 Requirements
- ID 唯一、只含數值、符合 64-bit。
- ID 按日期排序(隨時間遞增,但不必每次只加 1)。
- 能每秒產生超過 10,000 個唯一 ID。
🧠 Core Ideas
TIP
有多種方案,但唯一能同時滿足「64-bit + 數值 + 時間排序 + 無需協調」的是 snowflake 式做法:分而治之,把 ID 切成幾個區段各自負責。
先估算(見回中信封估算):需求是每秒 >10,000 個 ID,這決定了序號區段要留多少位元。
⚖️ Reference Design
四種方案比較
- 多主複製 (Multi-master replication):用 auto_increment,但每次加 k(k = 伺服器數)。可隨伺服器數擴展,但跨資料中心難擴展、ID 不隨時間遞增、增減伺服器時擴展性差。
- UUID:128-bit,各 web 伺服器獨立產生、無需協調、易擴展、衝突機率極低。但長度 128-bit(需求是 64-bit)、不隨時間遞增、可能非數值。
- Ticket server:單一資料庫集中做 auto_increment(Flickr 用過)。數值 ID、易實作、適合中小規模。缺點是單點故障;設多台可緩解但引入資料同步問題。
- Twitter snowflake:把 ID 切區段,符合全部需求,分散式下可擴展。採用此方案。
Snowflake 64-bit 位元組成
- Sign bit:1 bit,永遠為 0,保留未來使用。
- Timestamp:41 bits,自訂 epoch 起的毫秒數。最重要的區段——因隨時間遞增,ID 才能按時間排序。41 bits 約可撐 69 年,之後需換 epoch 或遷移。
- Datacenter ID:5 bits → 32 個資料中心。
- Machine ID:5 bits → 每個資料中心 32 台機器。
- Sequence number:12 bits → 4096。同一機器同一毫秒內每產生一個 ID 就加 1,每毫秒歸零。理論上單機每毫秒最多 4096 個 ID。
IMPORTANT
Datacenter ID 與 machine ID 在啟動時選定、運作後通常固定。意外變更這些值可能導致 ID 衝突。
🔑 Takeaways
- 四方案各有取捨:多主複製難跨機房、UUID 太長且不排序、ticket server 有單點故障——都不完全符合需求。
- Snowflake 靠切區段(timestamp + datacenter + machine + sequence)同時滿足 64-bit、數值、時間排序與可擴展。
- 額外考量:時鐘同步(假設各機器時鐘一致,實務靠 NTP)、區段長度調整(低並行可少序號、多 timestamp)、以及 ID 產生器需高可用。
No notes yet — jot your takeaways or Q&A here.