AWS の内部時刻同期の仕組み - Amazon Time Sync Service とうるう秒スミアリングの設計

AWS が独自に運用する Amazon Time Sync Service の仕組み、GPS と原子時計による高精度時刻源、うるう秒をスミアリングで吸収する設計判断、分散システムにおける時刻同期の重要性を解説します。

なぜクラウドで時刻同期が重要なのか

分散システムにおいて、正確な時刻同期は想像以上に重要です。CloudTrail のログ、CloudWatch のメトリクス、DynamoDB の条件付き書き込み、S3 のオブジェクトバージョニング、TLS 証明書の有効期限検証など、AWS のほぼすべてのサービスが正確な時刻に依存しています。時刻がずれると、ログの時系列が狂い、障害調査が困難になります。TLS 証明書の有効期限チェックが誤動作し、正常な証明書が無効と判定されることもあります。Kerberos 認証 (Active Directory) は、クライアントとサーバーの時刻差が 5 分以上あると認証を拒否します。分散データベースでは、時刻のずれがデータの整合性に直接影響します。Google の Spanner データベースが原子時計と GPS を使って TrueTime API を提供しているのは、分散トランザクションの整合性を時刻の精度で保証するためです。AWS も同様の課題に対して、Amazon Time Sync Service という独自のソリューションを提供しています。

Amazon Time Sync Service の仕組み

Amazon Time Sync Service は、各 AWS リージョンに配置された高精度な時刻源です。EC2 インスタンスからリンクローカルアドレス 169.254.169.123 で NTP (Network Time Protocol) サーバーにアクセスできます。このアドレスはメタデータサービスの 169.254.169.254 と同様にリンクローカルで、ネットワーク設定に依存せず、インスタンス起動直後から利用可能です。Time Sync Service の時刻源は、各リージョンに配置された GPS アンテナと原子時計 (ルビジウムまたはセシウム) です。GPS 衛星は原子時計を搭載しており、ナノ秒精度の時刻情報を提供します。AWS は GPS からの時刻情報をローカルの原子時計と照合し、GPS 信号が一時的に途絶えても正確な時刻を維持できるようにしています。EC2 インスタンスから Time Sync Service までのレイテンシはマイクロ秒単位であり、インターネット上の公開 NTP サーバー (pool.ntp.org など) と比較して桁違いに高精度です。公開 NTP サーバーではミリ秒単位の精度が限界ですが、Time Sync Service ではマイクロ秒単位の精度が得られます。

うるう秒スミアリング - 23:59:60 を作らない設計

うるう秒は、地球の自転速度の変動を補正するために、UTC (協定世界時) に 1 秒を挿入する仕組みです。うるう秒が挿入されると、23:59:59 の次に 23:59:60 という通常は存在しない時刻が出現します。この 23:59:60 は、多くのソフトウェアにとって想定外の値であり、過去に複数の大規模障害を引き起こしています。2012 年のうるう秒では、Linux カーネルのバグにより、Reddit、Mozilla、Yelp などのサービスが障害を起こしました。Amazon Time Sync Service は、うるう秒を「スミアリング」(smearing) で処理します。うるう秒の前後 12 時間にわたって、1 秒を均等に分散させて時刻を微調整します。つまり、23:59:60 という時刻は出現せず、代わりに 24 時間かけて 1 秒分の調整が行われます。各秒が通常より約 11.6 マイクロ秒長くなりますが、この差はほとんどのアプリケーションにとって無視できるレベルです。Google の NTP サーバーも同様のスミアリングを採用していますが、スミアリングの方式 (線形、余弦波など) が異なるため、異なるスミアリング方式の NTP サーバーを混在させると時刻の不整合が生じます。AWS 環境では Time Sync Service のみを使用することが推奨されます。

ClockBound - 時刻の不確実性を可視化する

2021 年に AWS がオープンソースで公開した ClockBound は、現在の時刻の「不確実性の範囲」を提供するデーモンです。NTP で同期された時刻には、ネットワーク遅延やクロックドリフトによる誤差が含まれます。ClockBound は、この誤差の上限と下限を計算し、「現在の真の時刻は X ± Y マイクロ秒の範囲にある」という情報を提供します。この情報は、分散データベースのトランザクション順序付けに使用できます。2 つのイベントのタイムスタンプの差が不確実性の範囲内であれば、どちらが先に発生したかを確定できません。不確実性の範囲を超えていれば、順序を確定できます。Google Spanner の TrueTime API と同様の概念ですが、ClockBound はオープンソースであり、AWS 以外の環境でも使用できます。DynamoDB や Aurora のような AWS のマネージドサービスは、内部的にこの種の時刻不確実性を考慮した設計になっていますが、ユーザーが自前で分散システムを構築する場合は、ClockBound を活用することで時刻に起因するデータ不整合を防げます。

時刻同期の失敗が引き起こす実際の問題

時刻同期の問題は、症状が分かりにくく、原因の特定が困難です。実際に発生する問題パターンをいくつか紹介します。第 1 に、TLS 証明書の検証失敗です。インスタンスの時刻が未来にずれると、まだ有効な証明書が「期限切れ」と判定されます。過去にずれると、「まだ有効期間に入っていない」と判定されます。HTTPS 通信が突然失敗し始めた場合、時刻のずれが原因であることがあります。第 2 に、AWS API の認証失敗です。SigV4 署名にはタイムスタンプが含まれており、リクエストのタイムスタンプと AWS サーバーの時刻の差が 5 分以上あると、リクエストが拒否されます。第 3 に、ログの時系列の乱れです。複数のインスタンスのログを集約する際、時刻がずれているインスタンスのログが時系列順に並ばず、障害調査が困難になります。対策として、すべての EC2 インスタンスで chrony (NTP クライアント) を設定し、Amazon Time Sync Service (169.254.169.123) を唯一の時刻源として使用してください。Amazon Linux 2 以降ではデフォルトで設定済みです。時刻同期と分散システムの設計を体系的に学ぶには、専門書籍 (Amazon)が参考になります。