🎓 レベル:標準 | 重要度:B(重要)
📎 前提:分散システムとは・なぜ難しいか | 関連:論理時計(Lamportタイムスタンプ)
要点(BLUF)
- どのマシンの物理時計(水晶発振)も少しずつずれる(ドリフト)。放置すると秒〜分単位でずれ、タイムスタンプ比較が壊れる。
- NTPは上位時刻源(原子時計・GPS)からの時刻を、往復遅延を測って片道遅延を推定し、オフセットを補正する。典型精度は数ms〜数十ms。
- それでも順序づけには使えない:同期誤差より短い間隔のイベントは前後が逆転しうる。だから論理時計(論理時計(Lamportタイムスタンプ))に切り替える。Google Spanner は誤差を明示的に区間で扱う(TrueTime)ことで物理時計を合意に使う。
問題設定 ── 時計はなぜ信用できないか
水晶発振子の周波数は温度・電圧・個体差でわずかに違い、1日で数秒ずれることもあります(クロックドリフト)。さらにうるう秒やNTP補正で時刻が飛ぶ・巻き戻ることすらある。「サーバAの 10:00:00.100 はサーバBの 10:00:00.100 と同じ瞬間か?」は、原理的に保証できません。
仕組み ── NTPの往復推定
NTPはクライアントとサーバ間で4つのタイムスタンプを取り、**ネットワークが対称(行きと帰りが同遅延)**と仮定して片道遅延とオフセットを推定します。
sequenceDiagram
participant C as クライアント
participant S as NTPサーバ
C->>S: 要求(送信時刻 t1)
Note over S: 受信 t2、応答送信 t3
S->>C: 応答(t1,t2,t3 を含む)
Note over C: 受信 t4
往復遅延 δ とオフセット θ(クライアント時計をどれだけ進めるべきか):
要するに何か:往復時間から「処理時間」を引いて純粋なネットワーク往復を出し、半分を片道とみなしてオフセットを補正する。対称性の仮定が崩れる(行きと帰りで経路が違う)と誤差が出ます。
正しさの観点 ── 同期では順序を保証できない
NTP同期後でも残差 ε(数ms)があります。2つのイベントの実時刻差が ε より小さいと、タイムスタンプの大小が実際の前後と逆になりえます。
つまり物理時計は「だいたいの時刻」には使えても、「因果の順序づけ」には使えない。ここが論理時計が必要になる分岐点です。
他手法との比較 ── 物理 / 論理 / TrueTime
| 方式 | 何を保証 | 代償 |
|---|---|---|
| 物理時計(NTP) | 実時刻に近い値 | 順序づけ不可(誤差内は逆転) |
| 論理時計(論理時計(Lamportタイムスタンプ)) | 因果の順序 | 実時刻とは無関係 |
| TrueTime(Spanner) | 時刻を区間 [earliest, latest] で持ち、区間が重ならなければ順序確定 | 専用GPS/原子時計・区間幅ぶん待つ(commit-wait) |
TrueTime の発想は秀逸で、「誤差を消す」のでなく「誤差を明示して、重なる間だけ待つ」。これで物理時計を強一貫トランザクションに使えるようにしています。
なぜ分散だと難しいか(直観)
単一マシンなら1つの時計を全スレッドが共有でき、now() の順序=実際の順序。分散では時計がN個独立にずれ、しかも観測(同期)にネットワーク遅延が混ざる。「共通の今」という概念自体が無い、というのが核心です。
⚠️ よくある誤解・落とし穴
- 「NTPで合わせたタイムスタンプで順序づけできる」→ 誤差内のイベントは逆転する。ログのtimestampで因果を語らない。
- 「時刻は単調増加する」→ NTP補正・うるう秒で巻き戻ることがある。経過時間の計測には単調時計(monotonic clock)を使う。
- 「PTPなら完璧」→ PTPはNTPより高精度(μs級)でも誤差ゼロではない。区間の発想(TrueTime)が要る場面は残る。
- 「時計を合わせれば合意は要らない」→ 合わせきれないから合意(合意問題とFLP不可能性)が要る。
対応ラボ
なし(概念回)。順序づけは 論理時計(Lamportタイムスタンプ) のラボで論理時計として実証します。
関連
- 物理時計の限界を埋めるのが 論理時計(Lamportタイムスタンプ)
- 因果と並行の区別は ベクトル時計
- 時刻を区間で使う強一貫の例は 分散トランザクションとSaga の周辺