本セッションの登壇者
セッション動画
それでは「しつこくじわじわパフォーマンスチューニング」ということで、馬場からお話をさせていただきます。
『達人が教えるWebパフォーマンスチューニング』、通称「ISUCON本」では、Chapter 1「チューニングの基礎知識」を担当しました。なぜチューニングが重要なのか、チューニングする時に何をどう考えていくのか、基礎知識として基本的な考え方などを解説しています。
こちらは今、私が会社でやっている取り組みです。入れたはいいけどうまく使えていないDatadog、なんとかします」ということで「OBServe」というサービスを始めました。SREや運用界隈の最近のホットトピックがオブザーバビリティ、可観測性で、「推測するな、計測せよ」とよく言われます。データドリブンで考えて行動するためにはデータが必要で、それにはオブザーバビリティが必須です。Datadog、New Relic、Dynatraceなど、モニタリングサービスを入れてはいるものの、正直あまりうまく使えていないという事例をよく見かけますが、OBServeはそこを解決するサービスです。データが読めるようになると、データからユーザーが透けて見えるようになってくるので、すごく楽しいんですよ。モニタリングサービスのデータが読めるようになって、楽しくサービスの開発や運用をして欲しいです。
何はなくともまずモニタリング
ここからパフォーマンスの話に入りますが、パフォーマンスの問題が難しいのは、致命傷にならないと気付かないことだと思っています。気付いた時には破滅しているので、なんとか避けたいわけです。
対策としては、継続的にしつこくモニタリングすることに尽きます。分解すると、まずはパフォーマンスをモニタリングできるようになること。次に課題を効率よく見つけられるようになること。そして致命傷になる前に発見できるようになること。この3つの要素に分けて考えていきます。
まずはパフォーマンスをモニタリングできるようになりましょう。何がなくてもまずはモニタリングができることです。
話の前提知識として、モニタリングSaaSのことを知っておいて欲しいなと思います。モニタリングSaaSは、モニタリングされる側のシステムでいろいろなデータを獲得してSaaSに集めるものです。データの種類としてはログ、メトリクス、APMがあります。ログはアクセスログなど、メトリクスはCPU利用率などの時間と数字です。APMはプログラムの実行記録で、こういう環境でこういう引数で実行されてどのぐらい時間がかかったかなどです。ログやAPMのデータは、SaaS上でそのまま見るだけじゃなくて、メトリクスにして見ることもできるところがポイントです。
コードと切っても切れない関係に
我々の武器は何かというと、ログとAPMなんですね。ログやAPM、あるいはそれらをもとにしたメトリクスというのがパフォーマンスを見ていく上では非常に役に立ちます。
データを読むときに意識してほしいことは、ログとAPMの性質の違いです。データの前提条件が違うので、性質の違いを意識してデータを使うようにしましょう。データがどういう単位で、どういう固まりで取れるのかということと、その取得されたデータに全体がどういうふうに反映されているのかの2つが大きなポイントです。ちょっと抽象的な話をしましたけれど、特に気付きづらいのが、ログは全行取れますが、APMはほとんどの場合、何らかの法則に従って一部を取ってくるサンプリングです。味噌汁の味見みたいなもので、全部は取れていないので、このユーザーのこの時のこのリクエストみたいな特定のものは含まれていたりいなかったりします。
そこで、APMは使いづらいのかなと思ってしまうかもしれないですけど、今回の「しつこくじわじわパフォーマンスモニタリング」という用途でまずは始めてみようという場合は、APMをお勧めします。本当は私に相談してほしいんですけど、自分でやる場合にはAPMから始めるというのが一番やりやすいと思います。これから話すことのほとんどは、APMをうまく使っていくための内容になります。
まずAPMを始める際に具体的にどういうことをするかというと、多くの場合はプログラムライブラリをロードして、場合によってはアプリケーションプログラムのソースコードをちょっと書き換えるということをやります。プログラムライブラリというのは、Rubyだったらgemとか、JavaだったらMavenとか、PythonだったらPyPIとか、Node.jsだったらNPMとかのことです。それらをロードして実行すればだいたいの場合においては概ねデータが取れるようになります。モニタリングを今までやってきた人からすると違和感があるだろうところは、モニタリングがコードの外側じゃなくてコード自体と非常に密にくっついている、場合によってはコードを書き換えるというところで、心理的に障壁を感じるかもしれません。それは私もわかるんですが、現代のモニタリングはコード自体と非常に密なところまで踏み込んでいくものだ、ということでやっていきましょう。
## データをじわじわ探索して、着目する場所の目星をつける
次に2つ目ですね。課題を効率よく見つけましょう。
「効率良く見つける」というのは、何らかの手法があってその手法で全体から絞り込んで目星を付けていくという意味です。リクエストやコントローラやURLなどの目星をつけていきましょう。実はデータから見つける以外に、ユーザーの声とか、プロダクトオーナーの意思決定という手段もあって、そういったものがあるならまずそこからやればいいと思います。でも、継続して行うなら特に、データを探索して見つけるのが重要です。ISUCON本ではアクセスログをalpで分析する方法を紹介しています。
Datadogの場合はAPMのServicesというのを入り口にするのがお勧めです。見るべきデータはトータルタイムとか、パーセンタイルとか平均とかいろいろあるんですけど、多くの場合はリクエストです。回数が一定数以上あるリクエストから選んで、50パーセンタイル(P50)、90パーセンタイル(P90)でレイテンシが高いものに着目していくと良いと思います。
リクエストの数は集計区間の長さにもよるので、システムに合わせて十分な母数が確保できるように調整してください。いきなり99パーセンタイルなど高いところからやるのはお勧めしません。そうするとコーナーケースに寄りがちというか、全体をうまく取れなくなってくるので、最初は50パーセンタイルくらいからじわじわ上げていくのがお勧めです。
これで、対象のリクエスト、URL、コントローラなどを見つけたら、今度はURL単位で時系列の変化を確認します。あるタイミングからガラッと傾向が変わって、たとえばリリースだとか構成変更があったなら非常にわかりやすいですね。あとはよくよく調べてみたら連携している外部サービスの仕様が変わったとかもあったりします。
この段階では、原因を探し当てるよりもまず狙いどころ、確認ポイントやタイミングを絞りましょう。この辺で傾向が変わっている、あるいはこの辺の傾向が安定しているので、レイテンシが低い時期と高い時期で比べるためにこの区間とこの区間で比べましょうなど、ポイントを絞るべきです。
データの対象区間を決めたら、今度はレイテンシの分散を確認します。下のグラフの横軸がレイテンシ、縦軸がリクエスト回数になっていて、同じ山は同じ傾向とか同じ特性の集まりの可能性が高いわけですね。もちろん要因が一つとは限らないので、因果関係や原因まではわかりません。ただ、この例では1.5ミリ秒付近と2~3ミリ秒付近に山があって、前提条件が違って同じような結果の固まりができているんだろうなというふうに推測できるので、それごとに分けて考えることをお勧めしています。たとえばこれで90パーセンタイルをとるときに、0から2ミリ秒のあたりではなく、2~2.5ミリ秒のあたりの山を中心にしようといった狙いの付け方をすると的が外れにくくなると思います。
最後に、狙いを定めて実際の処理の中身をトレースで見ます。ここから先は統計データではなくて個別の実績データになります。
フレームグラフを読み解こう
これはフレームグラフと呼ばれますが、横幅が処理時間の長さを表します。処理を呼び出したら、下に箱が積まれていきます。一連の箱全部を指してトレース、箱のそれぞれをスパンと呼びます。この箱をマウスでクリックすると、処理内容が表示されます。RDBMSのクエリなら正規化されたSQL文やかかった時間、宛先サーバーなどがわかります。スパン、つまり箱のそれぞれが何を指しているかというと、実装は自由にできるのですが、メソッドの呼び出し、DBなど外部システムの呼び出しやHTTPリクエストの単位で箱になるように自動計測されることが多いですね。同じ箱が横長なら、中の処理に時間がかかっているということです。1個がすごく長く見えても実はうまく計装できていないだけで、本当は箱がどんどん積まれるはずだったという場合もあるので、その辺はコードを確認して確定します。
次は数の話です。このスクリーンショットには入っていないですが、画面では少し上あたりにスパンの数が出ています。さすがにデータベースにリクエストが何百回とか何千回とかあると、パフォーマンス的には厳しいですね、みたいなのがわかるわけですね。こういう結果を見て、どの箱の数を減らすべきか、あるいはたとえばすごい時間がかかってるクエリがあるのであれば、そのクエリなり処理なりを高速化すべきで、どれがそれに当たるのかというのを検討できます。そして、それを解消したりチューニングしたりして、結果を前後比較してということができるようになってくるわけですね。これがデータ獲得の意義です。
「習慣の力」を使って継続的にモニタリング
では、最後にパフォーマンス問題を致命傷になる前に発見できるようになりたいという話です。それには、継続的にしつこくモニタリングすることです。
そのためには、定点観測が大事です。習慣の力を使いましょう。「火曜日はハグの日」みたいなやつですね。習慣化にもいろいろな知識やテクニックはもちろんあるんですけれど、土台と詰めは「根性と執念」だったりします。これには精神論という側面ももちろんあるんですけど、意思決定とか価値判断において流されないというのは非常に重要です。頭で考えて大事だとわかることを仕方ないで終わらせてはいけないわけです。物事を仕方ないで終わらせてそのままにしだすと、倫理の底が抜けちゃって、エンジニアとして、職業人として社会人としてまずい。根性と執念というのは馬鹿にできないと思っています。
とはいえ、なんだかんだ続かないということは現実問題としてもちろんあるので、われわれがサービスとしてやっています。これはさっき紹介したOBServeというX-Tech5のサービスなのですが、お問い合わせをいただくとたぶん私が出てきます。アドバイスやコンサルティングのようなコーチスタイルもやっていますし、ペア/モブプログラミングみたいに一緒にやる伴走もやってますし、「最初はわからないので代わりにやってくれ」というのもあったりします。
はじめにも言いましたが、モニタリングはすごく楽しいです。データが読めるようになると、データからユーザーが透けて、サービスの成長も見えるしユーザーの動きも見えるし、もっと良くするにはどうするか、もっとユーザーに楽しんでもらうにはどうすかというのがわかるようになってすごく楽しいので、モニタリングSaaSのデータを読めるようになってもらって、楽しくサービスの開発や運用ができるようになりましょう、という話をして、私の発表は以上にしたいと思います。
ありがとうございました。