🛠️

Whiz Tools

Build • Create • Innovate

Twitter用スノーフレークID生成および分析ツール

TwitterのスノーフレークIDを生成および分析します。これは、分散システムで使用されるユニークな64ビット識別子です。このツールを使用すると、新しいスノーフレークIDを作成し、既存のものを解析して、タイムスタンプ、マシンID、およびシーケンス番号のコンポーネントに関する洞察を提供します。

スノーフレークIDジェネレーター

スノーフレークIDジェネレーター

Optional: Unix timestamp in milliseconds (defaults to current time)
📚

ドキュメント

スノーフレークIDジェネレーター

はじめに

スノーフレークIDは、分散システムで使用される一意の識別子で、もともとはTwitterによって開発されました。このツールを使用すると、タイムスタンプ、マシンID、およびシーケンス番号で構成される64ビット整数であるスノーフレークIDを生成および分析できます。

スノーフレークIDの仕組み

スノーフレークIDは、次のように構成された64ビット整数です:

  • 41ビット:タイムスタンプ(カスタムエポックからのミリ秒)
  • 10ビット:マシンID(データセンターID用の5ビット、ワーカーID用の5ビット)
  • 12ビット:シーケンス番号

この構造により、マシンごとにミリ秒あたり約4,096のユニークIDを生成できます。

スノーフレークIDジェネレーターの使用方法

  1. (オプション)カスタムエポックを設定します(デフォルトはTwitterのエポック:2010-11-04T01:42:54.657Z)
  2. マシンID(0-31)とデータセンターID(0-31)を入力します
  3. 「生成」をクリックして新しいスノーフレークIDを作成します
  4. 生成されたIDとそのコンポーネントが表示されます

既存のスノーフレークIDを解析するには、「IDを解析」フィールドに入力し、「解析」をクリックします。

数式

スノーフレークIDはビット演算を使用して構築されます:

1ID = (timestamp << 22) | (datacenterId << 17) | (workerId << 12) | sequence
2

ここで:

  • timestampはエポックからのミリ秒数です
  • datacenterIdは5ビット整数(0-31)です
  • workerIdは5ビット整数(0-31)です
  • sequenceは12ビット整数(0-4095)です

計算

スノーフレークIDジェネレーターは、次の手順を実行します:

  1. 現在のタイムスタンプをミリ秒単位で取得します
  2. タイムスタンプが最後に使用されたタイムスタンプより大きいことを確認します(ユニーク性のため)
  3. タイムスタンプが最後のものと同じ場合、シーケンス番号をインクリメントします
  4. シーケンス番号がオーバーフローした場合(4096に達した場合)、次のミリ秒を待ちます
  5. ビット演算を使用してコンポーネントを組み合わせ、最終的なIDを作成します

使用例

スノーフレークIDは特に以下のような場合に便利です:

  1. 分散システム:複数のマシン間で調整なしにユニークIDを生成します
  2. 高ボリュームデータ:大規模データセットのためにソート可能なIDを作成します
  3. マイクロサービス:異なるサービス間でユニーク識別子を確保します
  4. データベースシャーディング:効率的なシャーディングのためにタイムスタンプまたはマシンIDコンポーネントを使用します

代替案

スノーフレークIDは強力ですが、他のID生成システムには以下が含まれます:

  1. UUID(ユニバーサルユニーク識別子):ソート可能性なしに分散生成が必要な場合に便利です
  2. 自動インクリメントデータベースID:シンプルですが、単一のデータベースインスタンスに制限されます
  3. ULID(ユニバーサルユニークレキシコグラフィカルソート可能識別子):スノーフレークに似ていますが、異なる構造を持っています

エッジケースと制限

  1. クロック同期:スノーフレークIDはシステム時間に依存します。NTP調整やサマータイムの変更によりクロックが逆戻りすると、ID生成に問題が生じる可能性があります。

  2. 2038年問題:41ビットのタイムスタンプは2079年にオーバーフローします(Twitterエポックを前提とした場合)。スノーフレークIDを使用するシステムは、この将来の事態に備える必要があります。

  3. マシンIDの衝突:大規模な分散システムでは、ユニークなマシンIDを確保することが難しく、追加の調整が必要になる場合があります。

  4. シーケンスのオーバーフロー:非常に高スループットのシナリオでは、ミリ秒あたり4096のシーケンスを使い果たす可能性があり、遅延を引き起こす可能性があります。

  5. マシン間の非単調性:IDは単一のマシン上では単調増加しますが、複数のマシン間では厳密に単調ではない場合があります。

歴史

スノーフレークIDは、分散かつ時間順序可能なユニーク識別子の必要性に対処するために、2010年にTwitterによって導入されました。それ以来、多くの他の企業やプロジェクトによって採用され、適応されています。

以下は、さまざまな言語でのスノーフレークIDジェネレーターの実装です:

1class SnowflakeGenerator {
2  constructor(epoch = 1288834974657, datacenterIdBits = 5, workerIdBits = 5, sequenceBits = 12) {
3    this.epoch = BigInt(epoch);
4    this.datacenterIdBits = datacenterIdBits;
5    this.workerIdBits = workerIdBits;
6    this.sequenceBits = sequenceBits;
7    this.maxDatacenterId = -1n ^ (-1n << BigInt(datacenterIdBits));
8    this.maxWorkerId = -1n ^ (-1n << BigInt(workerIdBits));
9    this.sequenceMask = -1n ^ (-1n << BigInt(sequenceBits));
10    this.workerIdShift = BigInt(sequenceBits);
11    this.datacenterIdShift = BigInt(sequenceBits + workerIdBits);
12    this.timestampLeftShift = BigInt(sequenceBits + workerIdBits + datacenterIdBits);
13    this.sequence = 0n;
14    this.lastTimestamp = -1n;
15  }
16
17  nextId(datacenterId, workerId) {
18    let timestamp = this.currentTimestamp();
19
20    if (timestamp < this.lastTimestamp) {
21      throw new Error('クロックが逆戻りしました。IDの生成を拒否します');
22    }
23
24    if (timestamp === this.lastTimestamp) {
25      this.sequence = (this.sequence + 1n) & this.sequenceMask;
26      if (this.sequence === 0n) {
27        timestamp = this.tilNextMillis(this.lastTimestamp);
28      }
29    } else {
30      this.sequence = 0n;
31    }
32
33    this.lastTimestamp = timestamp;
34
35    return ((timestamp - this.epoch) << this.timestampLeftShift) |
36           (BigInt(datacenterId) << this.datacenterIdShift) |
37           (BigInt(workerId) << this.workerIdShift) |
38           this.sequence;
39  }
40
41  tilNextMillis(lastTimestamp) {
42    let timestamp = this.currentTimestamp();
43    while (timestamp <= lastTimestamp) {
44      timestamp = this.currentTimestamp();
45    }
46    return timestamp;
47  }
48
49  currentTimestamp() {
50    return BigInt(Date.now());
51  }
52}
53
54// 使用例
55const generator = new SnowflakeGenerator();
56const id = generator.nextId(1, 1);
57console.log(`生成されたスノーフレークID: ${id}`);
58

スノーフレークIDの構造を視覚的に表現したものです:

タイムスタンプ(41ビット) マシンID(10ビット) シーケンス(12ビット)

64ビットスノーフレークID構造

参考文献

  1. "スノーフレークの発表。" Twitterエンジニアリングブログ、https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake
  2. "スノーフレークID。" ウィキペディア、https://en.wikipedia.org/wiki/Snowflake_ID
  3. "マイクロサービスにおける分散ID生成。" Medium、https://medium.com/swlh/distributed-id-generation-in-microservices-b6ce9a8dd93f