スノーフレークID生成器 - ユニークな分散IDを作成
このスノーフレークID生成器は、タイムスタンプ、マシンID、データセンターID、シーケンス番号の4つの要素から64ビットのユニークなIDを組み立てる無料オンラインツール。既存のIDを入力して解析し、各構成要素をビット単位の内訳として表示することもでき、分散システムやマイクロサービスの開発に使える。
スノーフレークID生成器
オプション: ミリ秒単位のUnixタイムスタンプ(デフォルトは現在の時刻)
マシンID(0-31)
データセンターID(0-31)
シーケンス番号(0-4095)
ドキュメンテーション
Snowflake IDジェネレーターとは?
Snowflake IDジェネレーターは、タイムスタンプ、マシン識別子、シーケンス番号から、一意の64ビットの数値を作ります。Twitterは2010年に、IDを生成するマシン同士が調整し合う必要がないように、この形式を考案しました。多数のサーバーが、「この番号はすでに使われたか」と確認せずに、同時にIDを生成できます。このツールは、入力した値から一つのSnowflake IDを組み立て、その値が64ビットをどのように埋めるかを示します。
このSnowflake IDジェネレーターの仕組み
ジェネレーターは4つの入力値を受け取ります。
- タイムスタンプ:ミリ秒単位のUnixタイムスタンプ。空欄にすると現在時刻が使われます。
- マシンID:0から31までの整数(5ビット)。これはTwitterが最初に用いた「ワーカーID」です。
- データセンターID:0から31までの整数(5ビット)。
- シーケンス番号:0から4095までの整数(12ビット)。同じミリ秒に生成されたIDを区別するために使われます。
このツールは四つの値を一つの64ビットのIDにまとめ、結果をタイムスタンプ、マシン、シーケンスの各部分に分けて表示します。
タイムスタンプは、Twitterエポックと呼ばれる固定の起点から測ります。それは2010年11月4日、1:42:54.657 UTC、つまりUnixエポックから1,288,834,974,657ミリ秒後の時点です。このジェネレーターでは起点を変更できず、生成されるすべてのIDがこの一つの固定日から測られます。
Snowflake IDの構造
Snowflake IDは4つの部分に分割された64ビット整数で、最上位ビットから順に読み取ります。
| ビット数 | フィールド | 範囲 |
|---|---|---|
| 1 | 符号ビット | 常に0 |
| 41 | タイムスタンプ | Twitterエポックからの経過ミリ秒 |
| 5 | データセンターID | 0–31 |
| 5 | マシン(ワーカー)ID | 0–31 |
| 12 | シーケンス番号 | 0–4095 |
先頭ビットは常に0なので、Snowflake IDは常に正の数です。41ビットのタイムスタンプフィールドと12ビットのシーケンスフィールドが、Snowflake IDを並べ替えに適したものにする2つの部分です。後に作られたIDほどタイムスタンプ部分の値が大きいため、先に作られたIDの後に並びます。
Snowflake IDの計算式
ジェネレーターは次の式でIDを生成します。
1delta = timestamp - 1288834974657
2id = (delta << 22) | (dataCenterId << 17) | (machineId << 12) | sequence
3<<は左ビットシフトです。数値を22ビット左にシフトすることは、2²²、つまり4,194,304を掛けることと同じです。シフト量(22、17、12)は各フィールドの幅から直接決まります。シーケンスフィールドの幅は12ビットなので、マシンIDは12ビット上に配置されます。マシンフィールドの幅は5ビットなので、データセンターIDは17ビット上に配置されます(12 + 5)。以下も同様です。
Snowflake IDの計算方法:計算例
たとえば、次の値を入力したとします。
- タイムスタンプ:1,288,834,975,657(Twitterエポックからちょうど1,000ミリ秒後)
- データセンターID:1
- マシンID:1
- シーケンス番号:0
手順1 — 差分を求める。 タイムスタンプからエポックを引きます。1,288,834,975,657 − 1,288,834,974,657 = 1,000。
手順2 — 各フィールドを所定の位置にシフトする。
- タイムスタンプ:1,000 << 22 = 4,194,304,000
- データセンターID:1 << 17 = 131,072
- マシンID:1 << 12 = 4,096
- シーケンス:0
手順3 — ビット単位のORで結合する。 シフトしたフィールドは重ならないため、加算してもOR演算しても結果は同じです。
4,194,304,000 + 131,072 + 4,096 + 0 = 4,194,439,168
これが今回の入力に対するSnowflake IDです。ツールの結果画面では、同じ64ビットの二進文字列が、41ビットのタイムスタンプ部、10ビットのマシン部、12ビットのシーケンス部に分けて表示されるため、数値の構造が見て取れます。
Snowflake IDの用途
Twitterがこの形式を作ったのは、すべてのサーバーが確認しなければならない中央のカウンターなしに、多数のマシンにわたって一意で、おおよそ時間順になるIDを得るためです。他のプラットフォームもこの考え方を取り入れました。たとえばDiscordは、IDにTwitterのsnowflake形式を使っていると明記しています。同じ考え方は、データベースのシャーディング、電子商取引システムの注文ID、分散アプリケーションのイベントログにも見られます。多数のマシンが互いに独立してIDを払い出しながら、おおよその時間順を保つ必要がある場面ならどこでも使われます。
Snowflake IDの制限
実運用のSnowflakeジェネレーターは通常、独自のクロックを保持しています。同じミリ秒内に作るIDごとにシーケンス番号を増やし、シーケンスが4,095に達したら次のミリ秒まで待ちます。このツールは計算の間に状態を保持しません。入力されたタイムスタンプ、ID、シーケンス番号から一つのIDを作るだけなので、形式の確認には便利ですが、稼働中の実運用サービスとは異なります。
この設計には、実装するサービスにかかわらず、次の固定された制限があります。
- 固定エポック:このジェネレーターが受け付けるのは2010年11月4日(Twitterエポック)以降のタイムスタンプだけです。それより前の日付はエンコードできません。
- タイムスタンプの上限:41ビットのタイムスタンプフィールドは、2080年7月ごろに上限に達します。それ以降は、エポックからの差分が41ビットに収まらなくなります。
- シーケンスの上限:同じミリ秒に1台のマシンが発行できる異なるIDは4,096個(0–4095)だけで、それを超えると値が繰り返されます。
- マシン空間:マシンIDとデータセンターIDにそれぞれ5ビットを使うため、1つのデプロイメントで衝突なく割り当てられる異なるマシン識別子は1,024個です(32 × 32)。
- ローカルな順序であり、グローバルな順序ではない:IDが互いに正しく並ぶのは、同期されたクロックを持つマシンから生成された場合だけです。マシン間のクロックのずれによって、厳密な時系列順が崩れることがあります。
Snowflake IDの歴史
Twitterは、連番のIDを扱う機能を持たないCassandraへストレージをMySQLから移行する際にSnowflakeを作りました。設計目標は、一意で、おおよそ時間順になり、そのまま並べ替えられる、64ビット未満のIDでした。初期バージョンは2010年に公開され、のちに廃止されて、社内での書き直し版に置き換えられました。他の大規模プラットフォームも、同じものを必要としたため、形を変えてこの設計を取り入れました。それは、多数のマシンが同時に生成する、一意で並べ替え可能なIDです。
よくある質問
Snowflake IDとは何ですか? Snowflake IDは、タイムスタンプ、マシン識別子、シーケンス番号で構成される64ビットの数値で、多数のマシンが互いに調整せずに一意なIDを生成できるよう設計されています。
Snowflake IDの計算式は何ですか?
id = ((timestamp − epoch) << 22) | (dataCenterId << 17) | (machineId << 12) | sequenceです。ここでエポックは固定された開始日であり、<<は左ビットシフトを表します。
このジェネレーターでエポックを変更できますか? いいえ。このツールは常に固定されたTwitterエポック、2010年11月4日からタイムスタンプを計算します。別の開始日を設定するフィールドはありません。
このツールは既存のSnowflake IDをデコードしますか? いいえ。入力されたタイムスタンプ、マシンID、データセンターID、シーケンス番号から新しいIDを生成し、その新しいIDのビット構成を表示するだけです。
1台のマシンが1ミリ秒に生成できるSnowflake IDの数はいくつですか? 最大4,096個です。シーケンスフィールドの幅が12ビットで、値は0から4,095までだからです。
このジェネレーターは何年まで有効なタイムスタンプを生成できますか。 2080年7月ごろまでです。41ビットのタイムスタンプフィールドに収まるのは、固定の2010年のエポックから測って最大およそ69.7年分です(Twitterのメモではこれを69年に丸めています)。それを過ぎると値がフィールドからあふれます。
参考文献
- Twitter. Snowflake README (snowflake-2010タグ), GitHub. Snowflake README — 調整なしで生成される、おおよそ時間順の64ビット未満のID。41ビットの時刻(69年)、10ビットのマシンID(1,024台)、12ビットのシーケンス(マシンごと、ミリ秒ごとに4,096)。MySQLからCassandraへの移行が動機。
- Twitter. IdWorker.scala (snowflake-2010タグ), GitHub. Snowflake IdWorker.scala — twepoch = 1288834974657。ワーカー用5ビット、データセンター用5ビット、シーケンス用12ビット。シフト量は12、17、22。
- Discord. API Reference: Snowflakes. Discord APIリファレンス — DiscordはIDにTwitterのsnowflake形式を使っています。
- Twitter. Snowflake README (master), GitHub. Snowflake廃止のお知らせ — 初期バージョンは2010年に公開され、すでに廃止されています。