UNIX タイムスタンプの仕組み - エポック秒が時刻表現を統一する理由
UNIX タイムスタンプ (エポック秒) の設計思想から、2038 年問題、ミリ秒精度の扱い、各言語での変換方法まで、システム開発者が知るべき時刻表現の基盤を体系的に解説します。
単一のサーバーでは、すべてのイベントに一意のタイムスタンプを付与し、発生順序を確定できます。しかし分散システムでは、物理的に離れた複数のノードが独立した時計を持ち、ネットワーク遅延が不確定であるため、「どちらのイベントが先に起きたか」を正確に判定することが原理的に困難です。
NTP で同期しても数ミリ秒〜数十ミリ秒の誤差が残ります。ノード A で 12:00:00.005 に発生したイベントとノード B で 12:00:00.008 に発生したイベントがあった場合、NTP の誤差範囲内では実際の発生順序を確定できません。この不確実性が、分散データベースのトランザクション整合性に根本的な課題をもたらします。
1978 年に Leslie Lamport が提案した論理時計は、物理時刻に依存せずにイベント間の因果関係 (happened-before 関係) を追跡する仕組みです。各ノードはカウンターを持ち、ローカルイベントごとにインクリメントし、メッセージ送信時にカウンター値を添付し、受信時に自身のカウンターと受信値の大きい方 +1 に更新します。
Lamport 時計は「イベント A がイベント B の原因であれば、A のタイムスタンプは B より小さい」ことを保証します。ただし逆は成り立ちません。タイムスタンプが小さいからといって因果関係があるとは限らず、並行 (concurrent) なイベントを区別できないという限界があります。この限界を克服するのがベクトル時計です。
ベクトル時計は、N ノードのシステムで各ノードが N 次元のベクトル (各ノードのカウンター値) を維持する方式です。2 つのイベントのベクトルを比較し、一方が他方のすべての要素以上であれば因果関係があり、そうでなければ並行であると判定できます。Amazon の Dynamo (2007 年の論文) はベクトル時計を使って書き込みの競合を検出していました。
ベクトル時計の欠点は、ノード数に比例してベクトルのサイズが増大することです。数千ノードのシステムでは、各メッセージに数千要素のベクトルを添付する必要があり、帯域とストレージのオーバーヘッドが無視できなくなります。この問題に対処するため、実用的なシステムではベクトルの刈り込みや、後述する HLC のような代替手法が使われます。
Google の Spanner (2012 年) は、物理時計の不確実性を API レベルで明示するという独自のアプローチを取りました。TrueTime API は現在時刻を単一の値ではなく区間 [earliest, latest] として返します。GPS 受信機と原子時計を各データセンターに配備し、不確実性を通常 7 ミリ秒以下に抑えています。
Spanner のトランザクションは、コミット時に TrueTime の不確実性区間が経過するまで待機 (commit-wait) することで、外部整合性 (linearizability) を保証します。不確実性が 7 ミリ秒であれば、各トランザクションに 7 ミリ秒の待機が追加されます。この設計は、専用ハードウェア (GPS + 原子時計) への投資と引き換えに、分散トランザクションの強い整合性を実現しています。
Hybrid Logical Clock (HLC) は、物理時計と論理時計を組み合わせた実用的な手法です。タイムスタンプは (物理時刻, 論理カウンター) のペアで構成され、通常は物理時刻が支配的ですが、同一物理時刻内のイベント順序は論理カウンターで区別されます。CockroachDB はこの HLC を採用し、専用ハードウェアなしで強い整合性を提供しています。
HLC の利点は、NTP 同期された一般的なサーバーで動作し、タイムスタンプが人間可読な物理時刻に近い値を保つことです。Spanner の TrueTime ほどの厳密さはありませんが、NTP の誤差範囲内で実用的な整合性を提供し、不確実性区間内の競合はリトライで解決します。多くの分散データベースにとって、この妥協点が最も現実的な選択肢です。
この記事は役に立ちましたか?
UNIX タイムスタンプ (エポック秒) の設計思想から、2038 年問題、ミリ秒精度の扱い、各言語での変換方法まで、システム開発者が知るべき時刻表現の基盤を体系的に解説します。
GPS が位置を特定するために不可欠な精密時刻システムの全体像を解説。衛星搭載原子時計、相対性理論補正、GPS 時刻と UTC の関係、週番号ロールオーバー問題まで網羅します。
主要プログラミング言語の日時処理 API を比較。JavaScript の Temporal、Python の datetime/zoneinfo、Java の java.time の設計思想、機能差、移行パスを実務的な観点から解説します。