ファイルが残っていてもプロセスは死ぬ:死活監視の見直し

スマートホームを描いたアイキャッチ画像

CPU側の処理が、いつまで経っても終わりませんでした。確認すると、抽出ジョブはすでに34時間前から停止していました。それでも自動監視は一件も異常を報告していません。

原因は、死活監視が「いま動いている実体」ではなく、過去に作られたログファイルを見ていたことでした。ファイルは残り、プロセスだけが消える。再起動では、この分離が自然に起こります。

目次

再起動後にワーカーだけ停止した

前日の障害では、GPUノードを再起動しました。対象だったGPUレーンは復旧しており、再起動そのものは適切な対処でした。

ただし、同じノードにはデータ収集パイプラインの前段となるCPU抽出ジョブが二本動いていました。再起動により、これらも停止しました。復旧時の確認はアラートを上げたレーンに集中しており、そのノードで動いていた全ワークロードを列挙していなかったのです。

復旧は、ホストが起動したことだけで完了しません。再起動された機能が、実際に仕事を再開していることまで確かめて、初めて復旧です。所長の運用でも、この確認が抜けていました。弁解できる種類の穴ではありません。

古いファイルが残ると存在チェックは通る

問題の判定は、概念的には「ログファイルがあればジョブは生きている」というものでした。

これは平常時にはもっともらしく見えます。ジョブを起動すればログが作られ、ジョブが動いている間はログもそこにあるためです。しかし、ログファイルは現在の状態ではなく、過去に起動した痕跡です。

再起動、メモリ不足による終了、親プロセスの消滅では、痕跡を残したまま実体だけが消えます。ディレクトリの存在やPIDファイルも同じです。過去の成果物は、生存証明にはなりません。

このケースでは、生存判定を次の考え方へ変更しました。

  • ログが存在する
  • かつ、完了マーカーがある、または当該ジョブのプロセスが実在する

実際のカテゴリで、プロセスが生きている分岐と、完了マーカーがある分岐をそれぞれ確認してから投入しました。以後は、再起動でジョブが停止しても、次の周回で自動的に再投入されます。

死活監視の基礎となる「停止したら気付く」仕組みについては、Uptime Kumaの死活監視の検証でも扱っています。ただし、通知経路があっても判定対象を誤れば、正常という誤報を丁寧に届けるだけです。

下流処理ではエラーではなく無出力になる

停止を見逃した理由は、上流の死活判定だけではありません。後段の処理は、ログ内に書かれる完了マーカーを待っていました。そのマーカーを書ける唯一の存在は、すでに停止した抽出プロセスです。

つまり、待機する処理は二つとも、生産者が生きているかを確認していませんでした。結果として死はエラーにならず、「完了を待ち続ける」という静かな待機として下流へ伝播しました。

エラーで落ちる処理は見つけやすいものです。待ち続ける処理は、監視対象として設計しなければ、何も起こらないように見えます。プロセスが存在していても処理が進まない問題は、GPU処理の進捗監視で見逃した停止と同じく、状態・疎通・進捗を分けて観測する必要があります。今回は、その最下層である状態監視の判定対象自体が壊れていました。

途中出力は完了条件を分けて扱う

図解: 停止を早く検出する価値(単一パスのダンプ走査 / 再開機能がない / 再投入はゼロからのやり直し / 停止を早く検出する価値 / 監視の設計は先に変えるべき)
図解: 停止を早く検出する価値(AI生成)

抽出ジョブには再開機能がなく、再投入はゼロからのやり直しでした。途中出力の731行と1,614行は破棄しています。

再開機能がない点は、単一パスのダンプ走査であることから、当面は許容しています。すべてを一度に直す必要はありません。しかし、再開できない処理ほど、停止を早く検出する価値は高くなります。復旧コストが見えているなら、監視の設計は先に変えるべきです。

似た構造として、処理が成功したように見えながら失敗を隠す問題もあります。収集系で起きたサイレント失敗は、成功扱いのまま異常が消える危険を扱いました。今回も、異常が「エラー」ではなく「正常な待機」に見えていた点が厄介でした。

停止中も入力だけは記録する

再起動のきっかけになったサスペンド機能は、initレベルで無効化しました。一方で、サスペンドを叩く内部HTTPトリガは残しています。呼び出しは失敗し、呼び出した相手は記録されます。これは、無効化した機能へのアクセスを観測するハニーポットです。

ただし、事故後に追加した記録は、過去の事故を説明しません。元の呼び出し元は特定できないままです。設置以降の実呼び出しは0件であり、この仕組みが説明できるのは次に同じ入口が使われた場合だけです。

常時稼働の環境では、復旧後の確認を仕組みに落とすことが重要です。無人運用の土台となる監視の考え方も合わせて確認すると、監視を単発の通知ではなく運用全体の一部として整理しやすくなります。

存在確認・プロセス確認・完了確認を使い分ける

方法 適用条件 避ける条件 注意点
ファイルの存在確認 成果物が作られたかだけを確認したい場面 現在の生存を判定したい場面 過去の起動痕跡を生存と誤認しやすい
プロセスの実在確認 実行中ジョブの死活を確認したい場面 完了済みジョブだけを判定したい場面 プロセス名や識別条件を運用に合わせる必要がある
完了マーカーと進捗の確認 バッチ完了や処理の前進を確認したい場面 生産者の生存を単独で保証したい場面 生産者の死活確認、またはタイムアウトを組み合わせる

ファイルの存在確認が不要という意味ではありません。用途は「成果物があるか」の確認です。「いま動いているか」を知りたいなら、プロセスまたは進捗を見ます。両者を同じ問いに使わないことが重要です。

サービス再起動後に確認する項目

  • 死活監視はプロセスの実在を見ているか。それともファイルの存在だけを見ているか。
  • その判定は、再起動直後にも正しい答えを返すか。
  • 完了マーカーを待つ処理があるなら、生産者が停止したとき待ち手はどうなるか。生産者の生存条件またはタイムアウトはあるか。
  • 再起動を伴う復旧で、そのノード上の全ワークロードを列挙したか。
  • 復旧完了の条件は、ホストの起動ではなく、機能が実際に動いていることになっているか。

結論は単純です。死活監視は、プロセスまたは進捗を見ます。ファイル、ディレクトリ、PIDファイルは過去の起動の痕跡であり、生存証明ではありません。

「再起動後にバッチが終わらない」状態を避けたいなら、まず再起動直後の監視結果を試験してください。普段どおりに見える監視ほど、境界条件で静かに外れます。

この検証を回している環境

この検証は、自宅の常設ラボ(使い捨てVM/LXCを回す母艦+GPU+VLAN分離ネットワーク)で動かしています。使っている機材と選定理由、全体構成は1本にまとめています。

ラボ構成のまとめを見る →
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次