Tracing の不条理な効力

Systraceabout:tracing. Tracing ツールの威力を目の当たりにするたびに宣伝しなければと思いつつ、機を逸したまま数年が過ぎた。書くことを考えても退屈な論点しか思い浮かばず、どうせつかっている人にとっては当たり前だし…などと盛り下がるループ。でも最近 Dapper をつかう機会があり、また少し tracing 熱が高まった。この盛り上がりを逃すと二度と書くことはなさそうなので、わかりやすさは無視しても何か言っておきたい。

Tracing とは、プロファイリングとモニタリングの中間に位置する性能解析のツールだ。プロファイラは主に関数の実行時間を調べてくれる。そしてほぼ全ての関数がプロファイリング対象になる。コード行単位で実行時間がわかるものまであるミクロなツール。モニタリングはよりマクロな指標、たとえば HTTP リクエスト単位のレイテンシなんかを記録、集計する。

ノート

Tracing では、コードの中で興味がある(=遅そうな)処理の流れをプログラマが明示的にマークする。ひとつの「処理の流れ」は必ずしも関数一つで表現されなくてよい。たとえば結果を非同期に受け取る API コールのレイテンシが気になるならリクエストの直前とコールバックの先頭を開始や終了としてマークする。そんなマークをコードのあちこちに埋め込む。実行時に通過したマークはログに記録が残り、そのログを専用のビューアで表示し、性能問題を調べる。

Tracing は汎用のプロファイラよりデータのノイズが少なく、オーバーヘッドも低い。一方でモニタリングよりは詳しいデータが取れる。明示的にコードをマークする手間を通じ自分の関心をツールに伝えるおかげで、Tracing は開発者にとって興味のある情報だけを浮き上がらせることができる。眺めるだけだと理解が難しい教科書を読むときノートをとるのと似ている。もっとかっこよくいうと、 Tracing ではツールが用意したインフラの上にシステム、ドメイン固有のプロファイラをつくる。

ドメイン固有プロファイラというと、たとえばブラウザの DevTools 類がある。実際 DevTools のデータを集めるフックとブラウザ内 Tracing のフックの多くは同じ場所にある。ゲームエンジンの多くも画面にオーバーレイできる性能メーターを持っている。これもドメイン固有プロファイラの一種。アプリケーションのドメインが成熟すると、このようにプラットホームやフレームワークが抽象度の高いプロファイラを提供しだす。

Android も正直 Systrace より色々できる性能追跡ツールを提供してくれてもバチは当たらないと思うけれど、今のところそうなっていない。ま、仕方なし。

分散システム用の Tracer である Dapper や Zipkin は、 Tracing を名乗りつつ大半はデフォルトのトレーシング、すなわち RPC の追跡で足りる。その点ではフレームワーク提供のドメイン固有プロファイラに近い。一方で専用のプロトコルをしゃべるサーバとの通信をマークしたり、通信とは無関係な遅い処理をマークすることもできる。そこには Tracing らしさもある。

松明

分散システムではリモートアクセスを追跡できれば多くのことがわかるので、リモートアクセスを自動で追跡する分散トレーシングツールのデザインは悪くない。そして社内ほぼすべてのリモートアクセスを Stubby などの限られたライブラリに押し込んだ Google はえらかったなと今更思う。

先の説明では追跡マークをつける作業を通じコードの理解を深めることが Tracing の価値だと書いたけれど、今回 Dapper をさわって感じた驚きは実のところ逆だった。Tracing の結果をみると、そこからシステムの作りがわかる: どんなバックエンドに依存しているのか、ストレージシステムは何か。分散システムのように実行主体が散らばっていると、コードだけから全貌を理解するのは難しい。 分散 Tracing はコードの裏に隠されたそんな迷路を照らしだす。

自分が Dapper で調べていた API も、その API を提供するフロントエンドが呼び出している (ややレガシー気味の) バックエンド...が呼び出している他所のサービスの API が遅く、その他所の API のせいで遅いバックエンドの API をフロントエンドが複数回叩いており、大変遅い、みたいな結論だった。自分はそのバックエンドのコードは一行も読んだことがなかったし、手前のフロントエンドすら以前読んだ時によくわからないまま半ば投げ出していた。「めんどっちいからとりあえずこの遅い API はプリフェッチしましょう」と提案したところ、とりあえず Dapper で見てみ、とサーバのボスに諭され渋々使い方を調べたら一気に見晴らしがよくなって感動した。それがが今回 Tracing について書こうと思うきっかけなのだった。調べてわかるなら速くしといてくれよ・・・とは言うまい。

重い腰を上げて読んだ Dapper マニュアルの FAQ には「誰が Dapper をつかうべきですか」という項があり、答えは「すべてのエンジニア」だった。読んだ時はうぜえなと思ったものの、いまや心の底から説得された。すべてのエンジニアには Tracing ツールが必要だ。難しいものじゃないから手元にあるなら使ってみるべきだし、既成品を使えない環境ならしょぼくても自作する価値がある。自分も一時期は自作していた。可視化には Catapult を使えるから、データを吐くところだけ作ればなんとかなる。Tracing ツールを使おう。マーキングを通じシステムを学ぼう。先人の残したマークを灯し、システムの闇を照らし出そう。

補足。

Tracing ツールが性能解析のすべてではない。あたりまえ。トップレベルでの高速化が済んで細部の詰めが必要なときはマイクロベンチマークや CPU プロファイラのお世話になる。既存の Tracing ツールが提供する可視化の情報では足りないなら手の込んだドメイン固有プロファイラを作りたくなる。あるいは Tracing 結果を R や Python にロードして統計的に眺めたくなる。コードをさわれないバイナリには Dtrace 的な prober が欲しくなる。一旦速くしたら遅くしないためにモニタリングしたい。そんな道具の一つに Tracing も混ぜてあげてね、という話。