Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Go 1.27 の標準パッケージに uuid が入った!のでいろいろ喋る / go_127_s...

Avatar for convto convto
August 18, 2026

Go 1.27 の標準パッケージに uuid が入った!のでいろいろ喋る / go_127_std_go_uuid

go 1.27 release party で発表した内容です
https://gocon.connpass.com/event/401603/

Avatar for convto

convto

August 18, 2026

More Decks by convto

Other Decks in Technology

Transcript

  1. whoami @convto (よみは「こんぶと」です) LayerX所属 (2023-03 -) バクラク事業部 アカウント基盤開発部 IDチーム 2023-09

    くらいから ID 基盤の開発に関わっています ID チームなので各種 SNS の ID には一貫性があり、uuid も好きです。 名は体を表す © LayerX Inc.
  2. はじめに Go 1.27 から標準ライブラリで uuid が使える proposal #62026 にて議論されデザイン整理されました パッケージデザイン面の議論めちゃめちゃ面白かったんですが、今回は重要なところだ

    け紹介します 今日はせっかくなので深掘りして Go の UUID v7 実装の紹介をできればと思います!か なりいい実装だと思うため © LayerX Inc. 3
  3. はじめに そもそも、なんで今さら標準ライブラリに? uuid 実装は実際にかなり利用されている google/uuid は golang.org/x/crypto や google.golang.org/grpc より

    import が多い ref: https://blog.thibaut-rousseau.com/blog/the-most-popular-go-dependency-is/ エコシステムでの長い実運用実績があり、そこから妥当な設計を導ける段階になった © LayerX Inc. 4
  4. はじめに サポート範囲について: v4 と v7 だけサポート google/uuid の利用統計を分析してサポート範囲を決定 version v4

    v1 v7 その他 利用率 94.17% 4.39% 1.22% 0.22% 判断 サポート ✘ RFC 9562 が新規利用に非推奨 サポート(v1 の後継として推奨) ✘ 利用傾向などを分析した上で、十分利用されるものに絞ってサポート エコシステムで十分な実験がなされたおかげでこのような議論ができた! © LayerX Inc. 5
  5. はじめに 最終的な API の着地をざっと見る 生成・パースがメインの小さな API version / timestamp などの抽出

    API は無い。RFC で推奨される「UUID は不透明な値と して扱う」に従う 6 © LayerX Inc.
  6. UUID v7 の話 UUID v7 のビットレイアウト(RFC 9562) unix_ts_ms 48 bits

    ver 4 rand_a 12 bits var 2 rand_b 62 bits 先頭 48 bits が UNIX タイムスタンプ(ミリ秒)→ 時系列ソート可能な ID 時刻順に並ぶので、局所性がほしい用途に向いてる 基本レイアウトはこれで、おおよそのケースに対応できる © LayerX Inc. 8
  7. UUID v7 の話 v7 の基本レイアウトの課題:同一 tick 内の単調性 タイムスタンプはミリ秒精度 同一ミリ秒内に複数採番すると残りはランダムなので、順序が保証されない RFC

    9562 はこの対策を実装者が選ぶオプションとして提示している つまり v7 を実装するさいは、単調性に対するスタンスを決めて、 いずれかのオプションを選択しなければいけない © LayerX Inc. 9
  8. UUID v7 の話 オプション実装の概観(RFC 9562 より) unix_ts_ms 48 bits ver

    4 rand_a 12 bits ↑ var 2 rand_b 62 bits ↑ 単調性のための利用も可能 ① (OPTIONAL) timestamp の直後の空間をつかってタイムスタンプ精度を上げてもいい (rand の空間を削る) ② (OPTIONAL) さらに、単調増加カウンタを仕込んでもよい(rand の空間を削る) ③ 余った部分は rand で埋める © LayerX Inc. 10
  9. UUID v7 の話 タイムスタンプ精度向上(RFC の Method 3) rand_a の空間を「サブミリ秒タイムスタンプ」に転用する unix_ts_ms

    48 bits ver 4 sub-ms ts var 12 bits 2 rand_b 62 bits タイムスタンプが最大 12 bits ぶん高精度化 → 同一 tick に複数採番される確率自体を下げる 実装が単純。時刻の解像度を上げればtick衝突確率がかなり減る ただし衝突確率は下がるだけでゼロにはならない(同一サブミリ秒はあり得る) © LayerX Inc. 11
  10. UUID v7 の話 固定長カウンタ(RFC の Method 1) rand_a の空間を「カウンタ」に転用する unix_ts_ms

    48 bits ver 4 counter 12 bits var 2 rand_b 62 bits tick が変わったらランダム値で初期化、同一 tick 内は +1(幅が足りなければ rand_b 側へ拡張も可) ランダム空間を削ってカウンタに充てる 厳密にやるにはカウンタへの競合制御などが必要 カウンタが溢れたときの扱いも考慮する必要がある © LayerX Inc. 12
  11. UUID v7 の話 Monotonic Random(RFC の Method 2) レイアウトは変えず、ランダム空間の「振る舞い」を変える unix_ts_ms

    48 bits ver 4 rand_a 12 bits var 2 初回だけ乱数、同一 tick 内は +増分 62 bits カウンタに使う範囲は基本 rand_b. 増分は毎回ランダムな正整数がデフォルト(+1 は採番数が推測できてしまうため、推測困難性重視なら SHOULD NOT) ビット空間はそのまま rand 空間として扱いつつ、tick競合したら rand 振り直さずに同 じ空間に加算して単調増加をケア 前回値の保持・加算をするので、競合管理が必要なのはカウンタと同様 嬉しいのはランダム空間の広さを保ったまま単調にできること © LayerX Inc. 13
  12. UUID v7 の話 組み合わせは自由 = レイアウトは実装者が設計する 例:Method 3 + 1

    — rand_a の 12 bits を、タイムスタンプ精度の拡張とカウンタで分け合う unix_ts_ms 48 bits ver sub-ms ts counter var 4 6 6 2 rand_b 62 bits 精度向上で同一 tick の発生自体を減らしつつ、それでも重なったらカウンタで順序を守る 「単調性をどこまで保証したいか」「ロックなどの複雑性をどの程度受け入れられるか」 など求める性質合わせて柔軟に決められる どの性質を取り、何を捨てるかの意思決定が必要 © LayerX Inc. 14
  13. UUID v7 の話 Go UUID v7 実装:プロセス内での単調増加保証 Method 3 をベースに、単調性は

    timestamp 側で頑張る unix_ts_ms 48 bits ver 4 sub-ms ts var 12 bits 2 rand_b(毎回ランダム) 62 bits ms 48 + sub-ms 12 をひとつの 60 bit タイムスタンプとして扱う。rand_b はカウンタに使わない 前回採番したタイムスタンプをプロセス内に保持し、前回以下なら前回値 +1 を採用 前回値の参照・更新(加算)は sync.Mutex のロックで保護されている 競合だけでなくクロック逆行なども現実世界のシステムにはありうる 秒単位の大きなクロック逆行時は補正しない(そこまでは保証しない割り切り) © LayerX Inc. 15
  14. まとめ まとめ Go 1.27 から std で uuid が使える。v4 /

    v7 のみサポート。 UUID v7 の単調性をどう保証するかは、実装者が求める性質からオプションを選ぶ必要 がある カウンタ / monotonic random / timestamp 精度向上、組み合わせもできる Go は「timestamp 精度向上」+「timestamp でベストエフォート単調増加」をやって いる © LayerX Inc. 18