Spike 状態から抜けられない!?!?

皆様、こんにちは。Windows プラットフォーム サポート担当の藤田です。

今回は、Spike 状態についてご案内します。

 

システム ログに ID : 50 が記録された経験はありませんか?

下記のようなイベントですが、内容を確認すると、時刻同期が正常に行えているのか、それとも何か異常が発生しているのか、少し不安になってしまうと思います。

今回は、このイベント ID 50 がどのような場合に記録されるかについて、詳細を説明したいと思います。

 

---------------------------------------------------

ログの名前:        
System

ソース:          
Microsoft-Windows-Time-Service

日付:           
2013/04/01 15:33:55

イベント ID:      
50

タスクのカテゴリ:     
なし

レベル:          
警告

キーワード:        
クラシック

ユーザー:         
N/A

コンピュータ:       
NTP2008R2domain.test12.com

説明:

タイム サービスにより 900 秒間で 5000 ミリ秒を超える時間差が検出されました。時間差が発生した原因として、正確度の低いタイムソースと同期した、またはネットワークの状態が最適でなかったことが考えられます。タイム サービスは現在同期されておらず、他のクライアントへの時間の提供、またはシステムクロックの更新を行うことができません。タイム サービス プロバイダから有効なタイム スタンプが受信されると、タイム サービスは自動的に訂正されます。

---------------------------------------------------

 

このログは、Windows Time サービスの内部状態が "Spike" の状態から "Unset" の状態に遷移したことを示しています。

では、Spike 状態ってどんな状態?

 

まずは、w32time の状態遷移についてご説明します。(下記はすべて、既定値における動作です。)

 

NTP クライアントの内部状態は、"Unset" の初期状態から、正常に時刻サンプルを取得する度に、"Unset"=> "Hold" => "Sync" へと推移します。

・ Unset の状態で 1 回時刻のサンプルを取得すると Hold の状態に移行します。

・ Hold の状態で 5 回、時刻のサンプルを正常に取得できると、Sync の状態に移行します。

 

時刻サンプルを取得した後、実際にその時刻に同期するかどうかの精査が行われますが、Unset、Hold の状態においては、NTP クライアントと NTP サーバーの時刻差に関わらず時刻同期が行われます。

しかし、W32time サービスの内部状態が "Sync" の時に、5 秒以上ずれた時刻サンプルを NTPサーバーから受信すると、その信頼性の確認のために、SpikeWatchPeriod で設定された一定期間 (15分間) 時刻の更新を行わない"Spike" の状態となります。

 

w32time は時刻補正を行う毎に下記のように内部状態を遷移させています。

 

<図>

+→Unset:  クライアントと NTP サーバーにどのような時刻差があっても、時刻補正を行う状態です。

|   |

|   |  (Hold
状態へ遷移します)

|   ↓

|  Hold: Spike と判定されるか否かにかかわらず、取得した時刻サンプルにあわせて時刻補正を行う状態です。

|   |

|   |  (既定では 5 回目以上で Sync へ遷移します、Hold の回数は "HoldPeriod" によって設定されています)

|   ↓

|  Sync: Sync 状態になると、Spike と判断されない場合のみ時刻補正を行います。

|   |

|   |  (
Spike と判断されると Spike 状態へ遷移します)

|   ↓

+←Spike: SpikeWatchPeriod にて設定された時間はローカルと 5 秒以上時刻がずれた時刻サンプルを許容しない状態となります。SpikeWatchPeriodにて設定された時間が経過した後の同期時に、Event 50 を発生させて Unset 状態へ遷移します。

 

 

===========================

推移の条件と経過時間について

===========================

1. Unset→Hold

Unset 状態の場合、次の同期時に Hold 状態へ移行します。

この時刻同期処理においては、必ず時刻同期に成功して、Hold に移行します。

 

2. Hold→Sync

Hold 状態は
"HoldPeriod" の回数、同期が行われてから Sync 状態へ移行します。

この Hold 状態においては、5 秒の時刻のずれを検知した場合でも、時刻同期を行います。

 

3. Sync→Spike

定義されている時刻差に問題がない場合、この Sync 状態が継続されます。

時刻差が発生し Spike と判断される条件に一致した場合 (5 秒の時刻のずれを検知) に 次の同期時に Spike 状態へ移行します。

 

4.
Spike→Unset

Spike
状態となった場合 "SpikeWatchPeriod" で設定された時間はローカルと 5 秒以上時刻がずれた時刻サンプルを許容しない状態となります。"SpikeWatchPeriod"にて定義された時間が経過した後に 次の同期時に Unset 状態へ移行します。

このUnset 状態へ移行した際に イベント ID : 50 を通知し、同期が再開されます。

 

 

===========================

Spike と判断される条件

===========================

以下に該当する場合、Windows Time サービスは Spike と判定されます。

・NTP サーバーから受信した時刻とローカル タイムの差分 5000 ms を超える時間差を検出した場合

 

- 詳細

Windows
Time サービス
NTP サーバーと同期した後、NTP サーバーから受信した時刻とローカルタイムの差分が LargePhaseOffset の値 (既定で 5 秒) 以上の場合には Spike 状態となり、"SpikeWatchPeriod" で設定された時間は、ローカルと 5 秒以上時刻がずれた時刻サンプルを許容しない状態となります。

この場合 Spike 状態のままレジストリ値 SpikeWatchPeriod の時間が経過すると 常時時刻同期を行うモードであるUnset 状態に遷移し、再度同期処理を開始します。

 

"SpikeWatchPeriod" で定義された時間内に Spike 状態からの復帰ができないと、イベントビューア上にイベント ID:50 が記録され、Spike状態から Unset 状態へ遷移したことが通知されます。

 

===========================

ID 50 のイベントが発生する一般的な要因

===========================

上記のような理由で ID 50 のイベントが記録されますが、このイベントが記録される一般的な要因としては、下記のようなものが挙げられます。

 

・ ハードウエア クロックの異常

・ 上位
NTP サーバーの異常

・ 意図的に時刻を変更した直後

・ 3rd パーティ製のアプリケーションによる時刻の変更

・ 仮想環境におけるホスト OS との時刻同期機能の影響

 

また、仮想環境においては、ソフトウェア的にクロックのエミュレートを行う必要があるため、物理環境と比べてローカル時刻のずれが発生しやすいとの報告があります。

 

 

===========================

KB2638243 の問題

===========================

Spike の発生要因については上述した通りですが、ここで注意すべきことがあります。

Windows Server 2008 以降の OS バージョンで SpecialPollInterval の値を用いて時刻同期の間隔を指定している場合、Spike 状態に移行した後に Unset状態に移行することができず、その後の時刻同期が正常に行えなくなってしまう既知の問題があります。

 

え!?じゃあ、どうしたらいいの?

 

実はこの問題、弊社の製品の問題として認識しており、公開ドキュメント (KB2638243) があります。

When SpecialPollInterval is used as
a polling interval, the Windows Time service does not correct the time if the
service gets into Spike state

https://support.microsoft.com/kb/2638243/en-us

 

 

 

*********************************

対処法

*********************************

対処法は 2 つ

[1] SpecialPollInterval の値を時刻同期間隔としないで、MaxPollInterval と MinPollInterval の値を時刻同期間隔とする。

[2] SpecialPollInterval の値を時刻同期間隔としている場合、SpecialPollInterval の値を小さくする。

 

 

[1] を選択していただくと、そもそも Spike 状態にならないので、KB2638243 の問題について懸念する必要はなくなります。

[2] を選択していただいた場合、時刻同期間隔を短くしていただくことで、Spike 状態に移行することを防ぐことができます。

マシンそのものの時計がずれやすいケースもありますが、その場合、Windows Time サービスの機能では制御することはできません。

Windows Time サービスから可能な対処策は、SpecialPollInterval の値を変更していただく方法があります。

時刻同期間隔を短くすると、時計のずれによって時刻の乖離が大きくなることを防ぐことができます。

よって、Spike 状態になる確率を下げることが可能となります。

 

SpecialPollInterval

-----------------------------------

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProvider\NtpClient

値 : SpecialPollInterval

値のデータ : 43200

#例として 12 時間に変更してみました。

-----------------------------------

 
レジストリ変更後、設定を反映させる必要があります。

下記のコマンドを実行するか、Windows Time サービスを再起動することで、設定変更した内容を反映させてください。

w32tm /config /update

 

 

KB2638243 の問題について

--------------------------------------------

KB2638243 の問題は、下記のすべての条件に合致した場合に発生します。

 

・ NTP クライアントは、手動で設定した NTP サーバーとの間で時刻同期を行う。

・ NTP クライアントは、SpecialPollInterval で指定された間隔に従い、時刻同期を行う。

・ NTP クライアントと NTP サーバーの間の時刻差が 5 秒
(LargePahseOffset) よりも大きい。

 

上記の全ての条件に合致した場合、この問題が発生したと推測できます。

これにより、一度 Spike 状態に遷移してしまうと、Unset 状態への復帰が期待通りに行われず、継続的に NTP サーバーとの時刻同期に失敗し続ける問題が発生します。

通常、Spike 状態を検知した場合は、一度 NTP クライアントの内部状態が "Unset" の状態に初期化されます。これにより、次回の時刻同期のタイミングで、NTP サーバーから取得した時刻サンプルを基に必ず時刻合わせが行われることが期待されます。

しかしながら、Windows Server 2008 以降の OS バージョンにおいては、Spike 状態に移行した後の NTP クライアントの内部状態の遷移は、SpecialPollInterval を使用して時刻同期を行う設定であったとしても、MinPollInterval で指定された間隔に従って内部状態の遷移が行われるように動作が変更されております。

この動作変更に伴い、MinPollIntervalで定義された間隔が SpecialPollInterval で定義された間隔よりも非常に小さい場合、次回の時刻同期のタイミングでは既に "Unset" 状態から "Sync" 状態への移行が行われます。この際に、NTP サーバーとの時刻差が 5 秒以上ある場合は、再度 Spike を検知して時刻同期に失敗する結果となります。

 

公開情報に記載の通り、SpecialPollIntervalを使用しない設定に変更していただくか、MinPollInterval の値を大きい値に変更して、次回の時刻同期が行われるまでの間に "Sync" 状態への移行が行われないようにする必要がございます。

 

では、実際に対処しましょう!!

 

SpecialPollInterval を使用して時刻同期を行う場合は、MinPollInterval の設定を変更してください。MinPollIntervalの値は 2 のべき乗です。

 

MinPollInterval

-----------------------------------

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Config

値 : MinPollInterval

現在の値 : a

変更後の値 : f

-----------------------------------

今回は時刻同期間隔(SpecialPollInterval の値) を 12 時間にしているので、MinPollInterval の値は f にしてみました。

2 の 15 乗は 32768 秒で約 9 時間ですので、Unset に移行後、Sync まで状態が遷移する前に次の時刻サンプルを受信することができます。ここでのポイントは SpecialPollInterval で指定した時間内に内部状態が Sync まで遷移しないように、MinPollInterval の間隔を考慮することです。

 

 

レジストリ変更後、設定を反映させる必要があります。

下記のコマンドを実行してください。お忘れなく・・・

w32tm /config /update

 

 

いかがでしたでしょうか?

実際のお問い合わせでも、イベント ID : 50 が記録された、原因不明だがいきなり時刻同期できなくなったという案件はたくさんあります。

思い当たることあれば、一度、上述の事柄を見直してみましょう。