yoskhdia’s diary

DDDとかプログラミングとかアーキテクチャとか雑多に

システムの透明性

shop.ohmsha.co.jp

システム監視について整理しておきたいなぁと思い、Release It!という本があったので、週末読んだ内容をメモしておきます。 監視は第17章の「透明性」に書かれているものです。 要約なので、ほとんどは書中からの引用です。

透明性とは

オペレータや開発者やビジネス上のスポンサーが、システムの歴史的傾向、現在のステータス、瞬間的な振る舞い、将来の予測について理解できるかどうかの特性である。

なぜ透明性が必要か

経験を積んだ船舶技術者はディーゼルエンジンのわずかな音の変化からマズイことが起きそうかを察知することができる。
しかし、システムはエンジンとは異なり顔の見えないボックスの中で動作している。「環境への気付き」を私達が獲得しようとするなら、自分たちのシステムに透明性を組み込んで気づきやすいようにしなければならない。

信頼できるデータがないと、誰かの政治的影響力や偏見、あるいはヘアスタイルに基づいた意思決定をしてしまうだろう。
透明性のないシステムは本番で長く生き延びることができない。システムが何をしているか分からない管理者には、システムをチューニングして最適化することはできない。本番で何が動作し、何が動作しないか分からない開発者には、信頼性や弾性を高めることはできない。そして、そのシステムで儲けられるか分からないビジネス上のスポンサーは、将来の作業に資金を投じてくれない。透明性がないシステムは、リリースのたびに少しずつ動きが悪くなり、衰退への道をたどるだろう。システムが十分に成熟できるのは、ある程度の透明性がある場合だけだ。

歴史的傾向

システムの明日の振る舞いは昨日の結果から推定して予測できる。これはビジネス上の指標(顧客数、注文数、顧客転換率、収益、配達サービスのコストなど)にも、システム上の指標(ストレージの空き、平均CPU使用率、ネットワーク帯域幅、ログに記録されたエラー数)にも当てはまる。
当然、過去から現在に至るまでの歴史的な記録は一定期間どこかに保存する必要がある。歴史観を得るのに最も役立つのはデータベースだ。そのためのデータベースを OpeDb と呼んでいる。

現在のステータス

瞬間的な振る舞いとの相違点は、太っている人のジョギングを想像すればよく分かるだろう。ジョギングという瞬間的な振る舞いからは健康改善が連想されるが、その人の現在のステータスは「あと1回の鼓動」で心臓発作かもしれない。

現在のステータスは、システム全体的な状態だ。これはシステムが何をしているかではなく、むしろ何をしてきたかを表すものである。ハードウェアの各部、アプリケーションサーバ、アプリケーション、バッチジョブの状態がすべて含まれる。
コンポーネントのステータスは、イベントとパラメータの組み合わせで決まる。
イベントは特定の時点における出来事だ。正常な出来事を示すイベントもあれば、懸念すべき異常事態を示すイベントもある。
パラメータはシステムについての連続的な指標や離散的な状態で、観測が可能なものだ。ここで透明性が決定的に重要になる。内部状態がよく分かるアプリケーションほど、正確で実用的なパラメータを提供してくれる。なかでも基本となるのは、OSから提供される指標だ。

主なもの

著者が過去の経験から一貫して有益だったものをあげている。
※「最後のn分間における」という前提付である点に注意

  • トラフィックを表示するもの
    ページリクエストの総数、ページリクエスト、トランザクション数、同時セッション
  • リソースプールの健康状態
    使用可能な状態、リソースの総数(接続プール、ワーカスレッドプール、その他)、チェックアウトされたリソース、ハイウォーターマーク、作成されたリソースの数、破棄されたリソースの数、チェックアウトされた回数、リソースを持ってブロックされたスレッドの数、特定のスレッドがブロックされた回数
  • データベース接続の健康状態
    発生したSQLExceptionの数、クエリの数、クエリへの平均レスポンス時間
  • 統合点の健康状態
    ブレーカーの状態、タイムアウトの数、リクエストの数、平均レスポンス時間、良好なレスポンスの数、ネットワークエラーの数、プロトコルエラーの数、アプリケーションエラーの数、リモートのエンドポイントの実際のIPアドレス、現在来ている各リクエストの総数、全リクエスト数のハイウォーターマーク
  • キャッシュの健康状態
    キャッシュ内のアイテム、キャッシュに使われているメモリ、キャッシュのヒット率、ガベージコレクタによってフラッシュされたアイテム、設定されている上限、アイテムの作成に要した時間

瞬間的な振る舞い

瞬間的な振る舞いは、「いったい何が起きているのか?」という問に対する答えだ。瞬間的な振る舞いに最も関心が寄せられるのは、すでに事件が発生している場合である。
瞬間的な振る舞いは明らかに現在のステータスと関連がある。瞬間的な振る舞いの異常により、必ずではないが正しくないステータスになることが多い。
振る舞いの問題の発露としては、スタックトレース、スレッドダンプ、ログファイル内のエラー、ユーザへのお粗末なレスポンスなどがあるが、ステータスとして見えることもあれば見えないこともある。異常な振る舞いはユーザが立ち去ろうとする前に補足したほうがいい。
瞬間的な振る舞いは監視システムの領分だ。自家製のログファイルスクレイパーから、数億円規模の導入に至るまで、監視システムは監視対象となるシステムを外部から監視するものである。

将来の予測

将来の予測は直接測定できるものではなく、相関や連係でしかない。
予測は常にシステムのモデルに基づいて行われる。「十分に使える」モデルであれば、過去のデータにおける相関を探すことで開発できる。そのモデルは一定の適用範囲内であれば予測に利用できる。
将来の予測は機密でデリケートな情報になりがちだ。また、緊急性のある即時的なデータではない。したがって、一般にダッシュボードに組み込むべきではない。 アプリケーションのリリースにより、予測の基になっている相関が変わったり無効になったりすることがある。それらの予測はシステムの振る舞いから派生するものなので、アプリケーションのリリースのたびに妥当性を調べなおす必要がある。(当然、新しい測定値が十分に集積されてから判断しなければならない。)さらに、それらの予測に基づく情報には、どの予測を使ったかを示す参照を含める必要がある。

透明性のための設計

透明性は熟慮された設計とアーキテクチャからもたらされる。開発の後のほうで「透明性を付け加える」効率は、「品質を付け加える」効率と同じくらいだ。つまり、可能かもしれないが、始めから組み込んだときの何倍もの努力とコストがかかる。
1つのアプリケーションやサーバの内部を可視化するだけでは十分でない。局所的な可視化は局所的な最適化をもたらすだけだ。
透明性のための設計では統合に気を配る必要がある。監視フレームワークは、容易にシステムの内部に入り込めてしまう。過剰な密結合を避けるため、以下のような基準を参考にしてほしい。監視システムとレポートシステムは、あなたのシステムを取り囲む外骨格のようなものであるべきであり、内部に組み込まれてはいけない。特に、警報のトリガーになる指標、閾値の設定、状態変数をシステム全体の健康状態として「まとめる」方法は、すべてのアプリケーションの外部に追いやるべきである。これらは、いずれもポリシーの決定に関連しており、しかもその決定はアプリケーションのコードとはまったく異なるタイミングで変化するものだ。

実現技術

本質的に、サーバで実行されるプロセスは不透明そのものである。デバッガ経由で実行しない限り、プロセス自身についてはほとんど何も分からない。 リクエストを順調にさばいているのかもしれないし、動いているのは唯一最後まで生き残っているスレッドだけかもしれないし、実は何もせずに空回りしているだけかもしれない。
だとすると、真っ先にすべきことはプロセスから情報を取り出すことだ。
これらは「ホワイトボックス」な技術と「ブラックボックス」な技術に分類できる。
ブラックボックス技術は、プロセスの外部で、外から観測できる事柄を通じてプロセスを調べる。
ホワイトボックス技術は、観測するプロセスやシステム全体の内部で実行するものだ。システムは、ホワイトボックス技術を通じて、意図的に自分自身を外部にさらす。ホワイトボックス技術は開発時に組み込まなければならない。

ホワイトボックス技術の代表的なものはロギングがあげられる。 ログファイルはアプリケーションの内部の活動を反映するものだ。したがって、そのアプリケーションの瞬間的な振る舞いが明らかになる。持続性もあるので、ログファイルを調べてシステムのステータスを知ることができる。ただし、それには状態遷移を追跡して現在の状態に至るまでに何が起こったか「要約する」ことが必要になることが多い。
特定の監視ツールやフレームワークとの密結合を避けたければ、ログファイルを使うのが賢明だ。ログファイルより疎結合な方法はない。

感想

書中では、SNMPやCIM/WBEM、JMXなどについても言及があります。気になる人は書籍をどうぞ。

いずれにしても、Observe-Orient-Decide-Actループで判断していくことが大事な気がしました。 何を収集(Observe)するかは、どう判断(Orient)したいかによって効果的な取得方法が変わってくると思うので、OOはセットで考える必要があるっぽいです。 リーンなどで語られるように、仮説と検証の繰り返しによって、より良いものに近づけていくプロセスはシステムの透明性においても同様に考えられそうです。