「絵で見てわかるシステムパフォーマンスの仕組み」を読んだ
目的、モチベーション
バックエンドのパフォーマンス改善において、指標となるCPUやメモリ等の基礎の理解を深め、実際の調査方法などが知りたかった。
全体の感想
表紙とタイトルから、図録みたいなものなのかと勝手に連想していたが、いい意味で裏切られた。普通にテキストによる説明がメインで、他の技術書よりもイメージをつかみやすいように絵がたくさんあったという印象。
アルゴリズムやデータ構造、アプリケーション、OS、インフラ、プロジェクトの進め方など、カバー範囲がとにかく広かった。
パフォーマンスのボトルネックの調査方法を知りたいのが目的の一つだったので、OSのコマンドの使い分けなどは特に良かった。
またパフォーマンステストの進め方は目的ではなかったが、私の経験で思ってるよりも時間がかかったり、再現が難しかったり今まであまりうまくいかなかったことが言語化されていて、整理もできて良かった。
少し個人的に残念なのは、2014年に出版された本のためDockerやコンテナ周りの話は触れられてなかった。
目次
概要
【第1章】パフォーマンスの基礎的な考え方
計算量やアルゴリズムの説明だった。知ってる内容だったので割愛。
【第2章】パフォーマンス分析の基本
2.2 必要なパフォーマンス情報とは
2.2.1 「はさみうち」の原則
前後の計測も行わないと、ただのスパイクなのか、何が原因なのかを確認できないので、必ず行うこと。
2.2.2 パフォーマンス情報の3種類
名前 | 特徴 |
---|---|
サマリ形式 | 一定期間の合計や平均の情報。概況を抑えるのには向いているが、変動を捉えるのには不向き。 |
イベント記録形式 | 個々のイベントを逐次記録された情報。詳細な調査には向くが、データ量や負荷が大きくなるので、本番で常に実行するには不向き。 |
スナップショット形式 | ある時点での状況の記録情報。定期的に取得することで、原因調査などが行える。 |
2.4 OSのコマンド
コマンド | 形式 | 計測点 | 補足 |
---|---|---|---|
sar | サマリ形式 | OSのカーネルからのOS情報 | CPU、I/O、メモリなどの概況がわかる。 |
vmstat | サマリ形式 | OSのカーネル情報からのOS情報 | 実行待ちの平均プロセス数、ブロックされているプロセス数などがわかる。 |
ps | スナップショット形式 | OSのカーネルで各プロセスの情報 | プロセスの状態、CPU時間などがわかる。負荷が高いので高頻度で取得するには向いてない。 |
netstat | サマリ形式/スナップショット形式 | ドライバレベル | ソケット、ルーティング、インターフェースごとの統計がわかる。 |
iostat | サマリ形式 | OSカーネル内部のブロックデバイスレベル | |
top | スナップショット形式 | OSレベル | OS全体の概況把握に最適。少々負荷が高い。 |
パケットダンプ(wireshark、tcpdumpなど) | イベント記録形式 | ドライバレベル | 負荷が大きく、パフォーマンスに影響が出る。 |
pstack | スナップショット形式 | OSから見たコールスタックの情報 | 何度か取得し、詰まってる処理を特定して、アプリケーションなどの問題を特定する。負荷は低い。 |
システムコール(straceなど) | イベント記録形式 | OSから見たプロセスのシステムコール情報 | 負荷が高い。 |
プロファイラ | サマリ形式 | OSから見たプロセスの各関数の処理時間 |
【第3章】実システムのパフォーマンス分析
用語の説明が多かったので、割愛。
【第4章】パフォーマンスチューニング
4.3 現場で用いられるテクニック
パフォーマンス改善と一口に言っても様々な方法があるが、一覧化されると整理できて良かった。
- ループの省略、キャッチボールの削減
- 局所最適に陥られないこと。例えば、DBで何度もINDEXを使った参照をするよりかは、1度のフルスキャンでデータを取得する。
- 参照頻度の高いデータはキーバリューストア化かハッシュ化する
- ハッシュのアクセスはO(1)
- 参照頻度の高いデータは使う場所の近くに置く
- CPUの内部レベルでも、CDNなどでも。
- 同期を非同期に変える
- 帯域制限
- LRU(Least Recent Used)方式
- 処理の分割またはロックの粒度の詳細化
- 不揮発なライトバックのキャッシュの採用
- マルチレイヤのキャッシュの採用
- ジャンボフレームと高速ネットワークの採用
- パケットあたりのデータ量を増やすことでパケット数を減らし、CPU使用量を減らす
- 負荷分散、ラウンドロビン
- アフィニティ、バインド、Stickyセッション
- キャッシュの特性を活かすために局所化する
- copy on write(COW)
- ジャーナル、ログ
- DBへの書き込みなどを一括で行い、パフォーマンスを改善する
- 圧縮
- 楽観的ロック
- カラムナデータベース(Columnar Database)
- サーバのパフォーマンス設定は初期値=最大値?
【第5章】パフォーマンステスト
この章では、パフォーマンステストの進め方が紹介されていた。
企画段階から、リリースしてから運用するまで、関係者とどのように進めるのかなど。
ややSIerっぽい内容ではあるが、環境構築や実際のテスト時の注意点は大変参考になった。
5.2 よくある失敗:9つのアンチパターン
5.2.1 期間内に終わらない!
本番環境でないと再現しない、再現するための環境構築に時間がかかる、特定の操作で問題発生などで、スケジュール通りに進まない。
5.2.2 パフォーマンスが出ない! パフォーマンス問題が解決できない!
原因究明には、あらゆるレイヤーの知識が求められるため、時間がかかる。
5.2.3 環境差異を考慮しないために問題が発生
インフラやサーバの設定が異なるなど。
5.2.4 負荷シナリオ設計に不備があるために問題が発生
- 一部の画面操作しか考慮していなかった
- 長時間滞在して多くの画面を遷移し、セッションに蓄積されて多くのメモリが使用された
5.2.5 バッファ/キャッシュの利用を考慮しないために問題が発生
特定のデータやパターンを集中的にテストしたために、キャッシュが乗った状態で十分に検証できてなかった。
5.2.6 シンクタイムを考慮しないために問題が発生
本番環境でユーザが複数の操作する際にテスト時よりも時間がかかり、HTTPのコネクション数やセッションの維持数に影響が出てしまう。
5.2.9 テストに時間がかかる
インフラの環境構築、計測や監視の設定、負荷生成シナリオスクリプト、本番同等のデータ作成、調査の時間など。
5.3 パフォーマンステストの種類
開発段階に応じて、できる種類のテストが異なる(インフラ、アプリケーションなどの単体しか行えないなど)。
また、知りたいパフォーマンスの種類によっても分類できる。
- 狭義のパフォーマンステスト: 要件が満たせるか
- 限界パフォーマンス: 上限の調査
- 縮退パフォーマンス: 一部のノードが落ちてしまったときのテスト
- 障害テスト: 障害が起こってしまった際のエラーの確認や対応の確認など
5.4 プロジェクト工程で考えるパフォーマンステスト
5.4.1 要件定義
「スループット」、「レスポンスタイム」、「ユーザ多重度」の3つは必ず設定すること。これらは互いに依存し合うため、一つ改善しても他が悪化する可能性があるため。
【第6章】仮想化環境におけるパフォーマンス
仮想化をすることによって、CPUの命令の変換やメモリのマッピングなどの処理が入るため、遅くなる。
また、元のOSのCPU数より多くのCPUを使用するとオーバーヘッドが生じるので、チューニングが必要になる。
【第7章】クラウド環境におけるパフォーマンス
ざっと読んだが、今回の目的とは関係ないので割愛。
次のアクション
詳解 システム・パフォーマンスを読む。