要約
- UUIDv7の先頭48ビットはUnixエポックからのミリ秒である。残る74の利用可能ビットは既定ではランダムで、任意のミリ秒未満精度やカウンターを組み込める。
- 同一ミリ秒内の単調化、時計の巻き戻り、カウンターの桁あふれ、状態の永続化は実装方針である。独立ノードの値をソートしても因果順やコミット順は証明できない。
- UUIDは識別子であり、認証、認可、セキュリティ能力ではない。強い順序が必要なら、イベント時刻、生成者、因果参照、コミット位置、検証可能な受領証を別に持つ。
48ビットの時刻が果たす仕事
UUIDv4は値をランダムに分散させる。中央登録なしで生成しやすい一方、連続したデータベース挿入が索引上の遠い場所に飛びやすい。RFC 9562の時間順レイアウトは局所性を改善し、解析せずに不透明なバイト列として並べられるよう設計された。
UUIDv7の最上位48ビットは、うるう秒を除くUnix時刻のミリ秒数である。バージョンとバリアントを除く74ビットには、ランダム値、任意のサブミリ秒精度、カウンターを順に使える。仕様は可能ならv1やv6よりv7を推奨する。
通常は後のミリ秒に生成した値ほど後へ並ぶ。近接する挿入も索引内で近付きやすい。これは実際的な性質である。
ただし、その時刻は生成器の時計と方針から来る。共有トランザクション順序、第三者の時刻証明、因果グラフから来るのではない。レイアウトが時刻を可視化しても、時計の権威までは高まらない。
一ミリ秒の中には複数の選択肢がある
高い生成率では、多数のUUIDが同じミリ秒プレフィックスを持つ。十分なランダム値は衝突を抑えるが、その部分の大小が生成順を表すとは限らない。
RFC 9562は任意の単調化手法を三つ示す。固定長カウンターを高位に置く方法、ランダムに開始する単調カウンター、最大12ビットの追加時刻精度である。残りをランダムにして衝突耐性や予測困難性を保つこともできる。
どれも共通のサブミリ秒時計ではない。適合する二つのライブラリーが別の手法を採用でき、同じホストの二プロセスが別々の状態を持てる。結合後のバイトソートは全順序を作るが、開始、完了、コミット、可視化の順序を必ず再現しない。
一意性と順序は別の主張だ。エントロピーは衝突を減らす。カウンターは一生成器の順序を強める。独立した出来事の因果関係は、どちらからも生まれない。
時計が後ろへ動いたとき
手動修正、時刻同期、仮想マシンの再開、故障により時計は巻き戻り得る。RFC 9562は、単調性を重視する実装に要件に沿った処理を求める。
新しいUUIDが前の値より大きいかを検査し、そうでなければ対処する。前の時刻を再利用してカウンターを増やす、物理時計を待つ、埋め込み時刻を先へ進める、エラーを返す、といった選択がある。
前の時刻を使えば局所順序は守れるが、現実時刻から離れる。待てば遅延や可用性へ影響する。先へ進めれば意図的な未来時刻になる。エラーは識別子発行を拒む。
仕様は時刻の変更、ぼかし、スミアも認め、実時刻への近さを保証しない。値をデコードできても、どの方針が働いたかは分からない。生成方針の記録が必要である。
状態の境界が保証の境界
生成器は最後の時刻、カウンター、ランダム状態を安定ストレージへ保存できる。再起動後も過去の値より先へ進む助けになる。ただし永続化は任意であり、状態なしで新しいバッチとして始めることも許される。その場合は衝突確率とエントロピー負荷が増える。
したがって「単調」の範囲を名付けなければならない。スレッド、プロセス、ホスト、クラスター、リージョンのどこまでか。コンテナー内のカウンターは隣のコンテナーを順序付けない。単一データベースなら、データベース自身がUUIDを生成すると最良の単調性を得られる場合がある。
複数ノードは独立生成できる。ランダム性は重複回避を助けるが、共有シーケンサーではない。後でソートすることはページングや概略時間には便利でも、存在しなかった共通コミット順を作り出せない。
時刻同期と因果関係は異なる
NTPとRFC 8633の運用慣行は時計の品質を高める。しかし、全アプリケーション時計を常時一致させるものでも、操作間の依存を表現するものでもない。
サービスAが記録を書き、その後Bへメッセージを送っても、時計差によってBのUUIDがAより前へ並ぶ場合がある。再試行は別のライフサイクル地点でIDを得るかもしれない。同じミリ秒内では二ノードのサフィックス規則も共有されない。
因果証拠はアプリケーションが持つ関係から得る。BがAのメッセージを参照する、データベースがコミット位置を与える、台帳が受理後に受領証を出す、といった情報である。UUIDv7はそれらと共存し、鍵と時刻の手掛かりを提供する。
これは仕様の不足を非難する話ではない。RFC 9562は識別子形式と生成慣行を定める。分散合意や世界時計を提供すると主張していない。
ソート結果を監査証言に変えない
データ基盤がUUIDで並べ、「イベント順」と表示すると、複数の仮定を隠す。全生成器の時計が比較可能、巻き戻り方針が同じ、ミリ秒内方式が互換、正しい業務地点で発行され、先行発行や再試行や履歴取り込みがない、という仮定だ。
いずれかが崩れてもUUIDは適合し得る。ロールバックされたトランザクション前にIDを作れる。配送前にキューのIDを作れる。古い記録へ今日のUUIDを付けられる。許可された時刻ぼかしも実時刻との差を変える。
監査モデルは、不変ID、イベント時刻と出所、取り込み時刻、生成器と方針版、因果前任、コミットまたは受領位置を分けるべきだ。全項目が不要なシステムでも、どの主張を省くかは意識する。
UUIDv7しか残らない場合は「生成器時計による近似順」と限定して使える。それだけで当事者の先後を裁定してはならない。
識別子を見せても権利は生じない
RFC 9562はUUIDを推測困難だと仮定せず、所持だけでアクセスを許すセキュリティ能力に使ってはならないと警告する。高品質なランダムビットを残すv7でも同じだ。
衝突耐性、予測困難性、権限は別である。エントロピーとCSPRNGは前二者を改善できるが、提示者を認証せず、対象操作を認可しない。
埋め込み時刻はUUIDと対応データの生成順を限定的に漏らす。カウンターは生成量を示し得る。RFC 4086とRFC 8937が扱うように、統計的にランダムに見えることと安全な予測困難性も同じではない。
APIは利用者を認証し、操作を認可し、必要な完全性を別の仕組みで守る。正しい形のUUIDを持つことは所有証明にならない。
採用時に記録すること
目的が索引局所性なら実データベースで測る。局所単調ページングなら、生成器範囲、ミリ秒内方式、永続状態、巻き戻り対応を文書化する。
分散監査なら、発行地点、時計源、方針版、ライフサイクルの発行段階を残す。因果参照とコミット位置を別項目にする。第三者が順序へ依存するなら、発行者と完全性を検証できる受領証を加える。
同一ミリ秒の大量生成、カウンター枯渇、再起動、状態喪失、時計の前後ジャンプ、リージョン分断、独立ストリーム結合を試験する。形式ではなく、実際に宣言した保証を検証するためだ。
情報源
会員向け解説
プロフィールの詳細
適切な会員レベルでログインすると、解説全文と出典メモをご覧いただけます。
Strategic Circle 限定
Strategic Circle
すべての読者に公開されています。参加してログインすると プロフィール解説 を閲覧できます。
Strategic Circle に参加Leadership Alliance 会員限定
Leadership Alliance
対象となる IP 資産の所有者・管理者向けです。ログインすると Leadership Alliance の解説を閲覧できます。
Leadership Alliance に参加
