Snowflake ID(en.wikidedia.orgからの翻訳)

:::note warn
この記事は[Snowflake ID](https://en.wikipedia.org/wiki/Snowflake_ID)を日本語に翻訳したものです
:::

# Snowflake ID

Snowflake ID、またはsnowflakeは、[分散コンピューティング](https://ja.wikipedia.org/wiki/%E5%88%86%E6%95%A3%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0)で使用される一種の[ユニークな識別子](https://en.wikipedia.org/wiki/Unique_identifier)です。このフォーマットは[Twitter](https://ja.wikipedia.org/wiki/Twitter)によって作成され、ツイートのIDに使用されています。一般的には、[雪片](https://ja.wikipedia.org/wiki/%E9%9B%AA%E7%89%87)がそれぞれ独自の構造を持つと考えられており、それにちなんで「Snowflake(雪片) ID」という名前が付けられました。このフォーマットは、[Discord](https://ja.wikipedia.org/wiki/Discord)や[Instagram](https://ja.wikipedia.org/wiki/Instagram)などの企業にも採用されており、[Mastodon](https://ja.wikipedia.org/wiki/%E3%83%9E%E3%82%B9%E3%83%88%E3%83%89%E3%83%B3_(%E3%83%9F%E3%83%8B%E3%83%96%E3%83%AD%E3%82%B0))では変更されたバージョンを使用しています[^1]。

## フォーマット
snowflakeは、64[ビット](https://ja.wikipedia.org/wiki/%E3%83%93%E3%83%83%E3%83%88)のバイナリ形式です([符号付き整数](https://ja.wikipedia.org/wiki/2%E3%81%AE%E8%A3%9C%E6%95%B0)に収まるよう63ビットのみ使用されます)。最初の41ビットは、選択された[エポック](https://en.wikipedia.org/wiki/Epoch_(computing))からのミリ秒を表す[タイムスタンプ](https://ja.wikipedia.org/wiki/%E3%82%BF%E3%82%A4%E3%83%A0%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%97)です。次の10ビットはマシンIDを表し、衝突を防止します。続く12ビットがマシンごとのシーケンス番号を表し、同じミリ秒内で複数のsnowflakeの作成を可能にします。通常、最終的に数値は10進数でシリアル化されます。

snowflakeは作成された時間に基づいているため時間によって[並べ替え可能](https://ja.wikipedia.org/wiki/%E9%81%B8%E5%88%A5)です。[^1]さらに、snowflakeが作成された時間は、そのsnowflakeから計算することができます。これは、特定の日時の前後に作成されたスノーフレーク(およびそれと関連するオブジェクト)を取得することに使用できます。[^2]

![fixed_header_format.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114394/b3e06b23-c050-fb78-38c3-edfc8e165982.png)
※ [オクテット](https://ja.wikipedia.org/wiki/%E3%82%AA%E3%82%AF%E3%83%86%E3%83%83%E3%83%88_(%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF)), [ビット](https://ja.wikipedia.org/wiki/%E3%83%93%E3%83%83%E3%83%88)

### 例
2022年6月に@Wikipediaから生成されたツイート[^3]のsnowflakeIDは1541815603606036480です。この数値は3つのIDの部分を示すパイプシンボルを使用して、バイナリに変換できます。
```
00 0001 0101 0110 0101 1010 0001 0001 1111 0110 0010 00|01 0111 1010|0000 0000 0000
```

- 最初の41ビット(+1ビットの先頭ゼロ)は、10進数に変換すると`367597485448`になります。これに[UNIX時間](https://ja.wikipedia.org/wiki/UNIX%E6%99%82%E9%96%93)のミリ秒単位でのTwitterエポックの値`1288834974657`[^4]を加えると、ツイートのUnix時間は`1656432460.105`になります。つまり、このツイートの時間は2022年6月28日16時07分40.105秒(UTC)です。

- 中央の10ビット`01 0111 1010`はマシンIDです。

- 最後の12ビットはすべてゼロにデコードされます。つまり、このツイートは与えられたミリ秒においてそのマシンで処理された最初のツイートであることを意味します。

## 使用例

このフォーマットは、Twitterによって2010年6月に初めて発表されました[^5]。実装に問題があったため、その次の年になってからアップデートを展開することとなりました[^6]。

- Twitterでは、ツイート、ダイレクトメッセージ、ユーザー、リストなど、[API](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9)を介して利用可能なすべてのオブジェクトにsnowflakeIDを使用しています[^7]。
- Discordもスノーフレークを使用しており、そのエポックは2015年の最初の秒に設定されています[^2]。
- Instagramはsnowflakeフォーマットの変更版を使用しており、タイムスタンプには41ビット、[シャード](https://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%A3%E3%83%BC%E3%83%89_(%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%83%BB%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3))IDには13ビット、シーケンス番号には10ビットが割り当てられています[^8]。
- Mastodonのフォーマットでは、ミリ秒単位のタイムスタンプに48ビットを使用しており、[UNIX時間](https://ja.wikipedia.org/wiki/UNIX%E6%99%82%E9%96%93)を採用しています。残りの16ビットはシーケンスデータのために使用されています[^9]。

## 参照
- [UUID](https://ja.wikipedia.org/wiki/UUID)

## 参考文献

[^1]: ["twitter-archive/snowflake at b3f6a3c6ca"](https://github.com/twitter-archive/snowflake/tree/b3f6a3c6ca8e1b6847baa6ff42bf72201e2c2231). GitHub. October 1, 2012. Retrieved January 18, 2021.
[^2]: ["API Reference"](https://discord.com/developers/docs/reference#snowflakes). Discord Developer Portal. Discord. Retrieved January 18, 2021.
[^3]: @Wikipedia (June 28, 2022). "53 years ago today, members of the LGBTQI+ community began protesting in New York City in response to a police raid of the Stonewall Inn, a popular gay bar. The riots were a transformative event in the 20th century fight for LGBTQI+ rights in the US. (1/2)" (Tweet) – via Twitter.
[^4]: ["2019-08-03: TweetedAt: Finding Tweet Timestamps for Pre and Post Snowflake Tweet IDs"](https://ws-dl.blogspot.com/2019/08/2019-08-03-tweetedat-finding-tweet.html). 2019-08-03.
[^5]: King, Ryan (June 1, 2010). ["Announcing Snowflake"](https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake.html). blog.twitter.com. Twitter. Retrieved January 18, 2021.
[^6]: Siegler, MG (October 12, 2010). ["Tweet IDs About To Get Jumbled In A Blizzard As Snowflake Is Set To Roll Live"](https://techcrunch.com/2010/10/12/twitter-snowflake/). TechCrunch. Retrieved January 18, 2021.
[^7]: ["Twitter IDs"](https://developer.twitter.com/en/docs/twitter-ids). Twitter Developer. Twitter. Retrieved January 20, 2021.
[^8]: ["Sharding & IDs at Instagram"](https://instagram-engineering.com/sharding-ids-at-instagram-1cf5a71e5a5c). Instagram Engineering. May 2, 2016. Retrieved January 18, 2021.
[^9]: Source Code [mastodon/mastodon](https://github.com/mastodon/mastodon/blob/5e796dc6f85b37c8378fe01cfd8ac23222c89eea/lib/mastodon/snowflake.rb), Mastodon, November 11, 2022, retrieved November 11, 2022