<書評> 達人が教えるWebパフォーマンスチューニング 〜ISUCONから学ぶ高速化の実践

概要

発売前から気になっていたこの書籍を読んだので学びをつらつらと書いていく。

自分が業務で担当しているアプリケーションもパフォーマンスがボトルネックとなることがあるので、少しでも何か吸収できれば。

1章: チューニングの基礎知識

本書ではリクエストレスポンス一連の動作が完了するまでの時間(RTT: Round Trip Time)が短いWebサービスを高速なWebサービスと定義している。

Webサービスのキャパシティは単純化すると個々の性能×数になり、それを調整するアプローチは**垂直スケーリング(スケールアップ: 性能UP)か水平スケーリング(スケールアウト: 数増やす)**の2種類がある。

パフォーマンスチューニングの基本は下記2点

負荷試験を実施して改善してのサイクルになる。負荷試験と言えるほどちゃんとしたものをやったことが無いな。

2章: モニタリング

モニタリングは外形監視と内部監視の2種類がある。

本書ではPrometheusというPull側のモニタリングツールを使用している。

基本的には内部監視の方が多いんじゃないかなと考える。外部監視だとネットワークの状態に左右されるから再現性が低そう。

3章: 基礎的な負荷試験

各種指標をどう見るかが大事。 本書では下記の数値が紹介されており、MySQLのボトルネックになっている箇所を調査していく流れ。 (スロークエリの発見。実行計画を見ていく)

実務でもスロークエリログがあってCPU使用率が跳ね上がった経験がある。

あのような事象はかなりインシデントにつながるので、普段からパフォーマンスをより意識したい。

4章: シナリオを持った負荷試験

この章の内容は自分の勤務先でもやりたい...!

どの画面表示時に遅いのかをシナリオを使って調査して可視化できるのはとても良い。

よりユーザー目線に立ったテコ入れができると感じる。

テスト環境ではデータ量が足りず、どうしてもクライアントのボトルネックに気付けないという問題がある。

ローカルだと開発生産性に影響するのでやりたくないから、それ用の環境を作るとかになるのかな。 コスパとの相談かも

それを事前に検知できる仕組みが欲しい。

書籍だとOSSのk6というツールを紹介している。

5章: データベースのチューニング

特に印象に残ったのはインデックス周りのこと。二分探索に適した構造であるBツリーについて。

インデックスの走査についてかなり丁寧に説明されていた。

Covering Index について

ref. https://dev.mysql.com/doc/refman/5.6/ja/glossary.html#glos_covering_index

クエリーによって取得されたすべてのカラムを含むインデックス。完全なテーブル行を見つけるためのポインタとしてインデックス値を使用する代わりに、クエリーはインデックス構造から値を返し、ディスク I/O を節約します。InnoDB セカンダリインデックスには主キーカラムも含まれるので、InnoDB は MyISAM よりも多くのインデックスにこの最適化方法を適用できます。InnoDB は、トランザクションが終わるまで、そのトランザクションによって変更されたテーブルに対するクエリーにこの方法を適用できません。正しいクエリーの場合、どのカラムインデックスまたは複合インデックスでも、カバリングインデックスとして機能できます。可能な場合は必ず、この最適化方法を活用するようにインデックスおよびクエリーを設計してください。

usersテーブルのnameカラムにindexが貼ってあるとする。

これだとidがプライマリーインデックス / nameがセカンダリインデックスとなる。

下記のSQLクエリ結果セットで利用しているカラムはidとnameだけなのでCovering Indexが有効になる。(EXPLAIN結果のExtraにUsing Indexが付与される。)

これにより、テーブルフルスキャンでなくインデックススキャンのみで結果を返すのでパフォーマンスが良くなる。

SELECT *の場合は、全てのカラムにインデックスを貼っていないので Covering Index は無効となる。

SELECT id
FROM users
WHERE users.name = 'hoge'

6章: リバースプロキシの利用

リバースプロキシが必要な理由としてアプリケーション側のHTTPコネクションでは捌ききれないというものがある。

本書では例としてunicornを利用したRubyアプリケーションのマルチプロセス・シングルスレッドを紹介している。

このように大量のリクエストを捌くのが難しいので、リバースプロキシでクライアントとのHTTPコネクションを解決する。

代表的なものとしてNginxがある。

マルチプロセス・シングルスレッドは同じだがイベント駆動アーキテクチャであるため、1プロセスが複数クライアントのリクエストを処理できる。

ノンブロッキングI/O(他の処理でのファイル読み書きが完了するまで待たない)と多重I/Oを活用し、イベント駆動でリクエスト・レスポンスを大量に捌くことでC10Kを解決している。

業務でもNginxを利用しているがあまり触っていないため色々と忘れがちなので、適宜振り返っていきたいと思う。

7章: キャッシュの活用

この章を読んでキャッシュは慎重に利用したいと感じた。

本書ではこのような問題があるのでまずはキャッシュを使わない方法を模索してみようと記述されている。

確かに扱い方によってはリスクを孕んでいる。

また、アプリケーションのインメモリで管理するか外部のミドルウェア(Redis等)で管理するかも考慮ポイント。

などの問題をちゃんと考慮しないといけないということを認識できた。

8章: 抑えておきたい高速化手法

特に印象深かったものだけ

最近、CDN周り(特にCloudflare Workers)をちゃんと触ってみたい欲がすごい。

9章: OSの基本知識とチューニング

割とOS周りが詳しく記述されているがポイントだけ。Linux周りがまだ分からないことだらけなのでもっと学びたい。

まとめ

パフォーマンスチューニングの書籍だけれど、ミドルウェアの設計やアーキテクチャの基礎知識に対する説明が丁寧にされていたのが好印象。

Covering Indexの概念を知れたのはよかった。Linux周りがまだ分からないことだらけなのでもっと学びたい。あとCDNも。