Development

時刻から Twitter のステータス ID を求める

現在、Twitter のステータス ID (Twitter IDs) は、1 ずつインクリメントされているわけではありません。上位の 41bit は、ある時刻からのミリ秒のオフセット値になっています。

ID の上位 bit さえわかれば、Twitter API でステータスを取得する時に使う max_id や since_id に、ある時刻の範囲を指定するといったことが可能です。

Twitter のステータス ID 生成方法と Snowflake

Twitter のステータス ID (63bit) は、上位 bit から次のように構成されています。

  • timestamp (41bit) : 現在の unixtime から、ある時点の unixtime を引いた値
  • machine id (10bit) : 生成器に割り当てられた ID。datacenter id + worker id。
  • sequence (12bit) : 生成器ごとに採番する sequence 番号

特長は、「複数台のマシンを用いて並列に一意な ID の生成が行える」ことです。

この ID 生成器を Twitter 社は Snowflake という名前で、ソースコードを公開しています。

ただし、当初は Apache Thrift と Finagle を元にしていたようですが、現在は Twitter インフラに依存したまったくの別物に置き換わっているとのことで、ソースコードは公開されていません。

当時の Snowflake については、下記スライドがとても参考になります。

Twitterのsnowflakeについて from moai kids

別の手法で ID が生成されているというだけで、ID の構成は変わっていないため、時刻から ID を求めることができます。

時刻からステータス ID を生成する

ID の timestamp となっている「ある時点の unixtime」とは、1288834974657 (2010/11/4 1:42:54 (UTC)) です。

というわけで、timestamp を求め 22bit 上位へシフトすることで、次のように現在の時刻の ID を求めたり、10分間のミリ秒を差し引きすることで10分前の ID を求めたりできます。

StatusId.cs
// 現時刻の status id
var currentId = Convert.ToInt64(
        DateTime.UtcNow.Subtract(
            new DateTime(1970, 1, 1).AddMilliseconds(1288834974657)
        ).TotalMilliseconds
    ) << 22;

// 10 minutes 分のミリ秒
var offset = Convert.ToInt64(
    TimeSpan.FromMinutes(10).TotalMilliseconds) << 22;

// 10分前の status id
var pastId = currentId - offset;

この方法は、Snowflake の仕組みが使用され始めた 2010/11/4 以降の ID にのみ有効です。