えいのうにっき

むかしのじぶんのために書いています

読書メモ・詳解システムパフォーマンス 第9章/ディスク

「詳解システムパフォーマンス」の読書メモシリーズ・第8弾。だいぶしんどくなってきて、気がついたら2ヶ月以上も空いてしまっていた......。。

詳解 システム・パフォーマンス

詳解 システム・パフォーマンス

感想

  • SSD、書き込み回数の限度くらいであとは弱点のないデバイス、くらいに考えていたけど、落とし穴もあるんだなー
  • オペレーティングシステムから見たときに実ディスクで起こっていること」について、って、すぐにわかることは少なく、また詳細を知ろうとすると大変そうだなぁ
  • オンディスクキャッシュヒットを基準としたタイムスケールの比較、おもしろい。し、怖い。。
  • 「後から観測することを考えたときのメトリック」としての「ディスク使用率」や「IOPS」、「I/O待ち時間」は、「現実的に取得可能かどうか」ということも考えると、難しいな。。
  • あとやっぱり大事なのは、「やらなくていいこと・無駄なことはさせない(不要なワークロードを排除する)」ってことなんだなぁ

読書メモ

ディスクI/O は、アプリケーションレイテンシの大幅悪化の原因・ボトルネックとなる場合があるので、システムパフォーマンス分析の重要な対象。

9.1 用語

仮想ディスク

ストレージデバイスのエミュレーション。システムからは単一の物理ディスクのように見えるが、実際には複数のディスクから構築されている場合がある

トランスポート

データ転送やその他のディスクコマンドのやりとりのために使われる物理パス。

セクタ

ディスク上のストレージのブロック。伝統的にサイズは512バイト。

I/O

ディスクに関して厳密にいうと、I/Oは読み書きのみでその他のディスクコマンドはこれに含まれない。方向(R/W)、ディスクアドレス、サイズから構成される

ディスクコマンド

データ転送とは関連のないコマンドのこと。例えばキャッシュのフラッシュなど。

帯域幅・バンド幅

ストレージトランスポート、もしくはコントローラが実現できるデータ転送速度の上限。

9.2 モデル

9.2.1 シンプルディスク

ディスクには、I/O要求のためのオンディスクキューが含まれている。ディスクが受け入れたI/Oは、キューで待機しているか処理されているかのどちらか。

9.2.2 キャッシングディスク

物理ディスクデバイス内にメモリ(DRAM)を搭載しオンディスクキャッシュを追加することによって、一部の読み出し要求に対し高速にレスポンスを返すことができるようになる。

このオンディスクキャッシュは write-back キャッシュとして使うことで書き込み要求のパフォーマンスも上げられる。(ストレージデバイスに完全に書き込み終わることで書き込み完了とするのは write-through キャッシュ。)

9.2.3 コントローラ

ディスクコントローラは、ストレージトランスポートやそれに接続されたディスクデバイスとCPUのI/Oトランスポートの橋渡しをするもの。パフォーマンスは、このディスクコントローラかディスクのどちらかによって制限される。

9.3 コンセプト

9.3.1 計測時間

ストレージデバイス応答時間(ディスクI/Oレイテンシ)= I/O要求 〜 I/O完了までの時間 = サービス時間+待ち時間。

  • サービス時間=キューでの待ち時間を除く、I/Oがアクティブに処理されている時間
  • 待ち時間=I/Oがキューのなかで処理を待っている時間

応答時間、サービス時間、待ち時間は、「どこで計測されるか」によっても影響を受ける。

  • オペレーティングシステム(ブロックデバイスインターフェイス)からみたとき
    • サービス時間=ディスクにI/Oを発行したとき 〜 完了割り込みが発生したとき までの時間
    • 要求されたオペレーションに対するディスクデバイスのパフォーマンス全体
    • オペレーティングシステムのキューで待機している時間は除外される
  • ディスクから見たとき
    • サービス時間=I/Oがオンディスクキューで待機していた時間を除き、ディスクがアクティブにI/Oを処理している時間を指す

ディスクのパフォーマンスの計測値としては、一般にはブロックデバイスインターフェイスから見たサービス時間を使う。ただし、それ以下の各レイヤーにおいてキューが存在しているかもしれない・それも含めた単純化された値であることを理解する。

ディスクのサービス時間の計算

ディスクのサービス時間は、一般にオペレーティングシステムから直接計測することはできない。IOPSと使用率から平均ディスクサービス時間を推測することはできる。

ディスクサービス時間=使用率/IOPS

【例】 使用率が60%でIOPSが300ならば、平均サービス時間は 2m 秒(600msec / 300 IOPS)。ただし、「使用率」が単一デバイスの数値であることを前提としている。

9.3.2 タイムスケール

ディスクI/Oレイテンシのタイムスケールのイメージ。

イベント レイテンシ オンディスクキャッシュヒットしたときを1秒としたときの対比
オンディスクキャッシュヒット < 100n秒 1秒
フラッシュメモリからの読み出し 〜 100 から 1000μ秒(小規模なI/Oから大規模なI/Oまで) 1 〜 10秒
回転ディスクからのシーケンシャル読み出し 〜 1ミリ秒 10秒
回転ディスクからのランダム読み出し(7,200rpm) 〜 8ミリ秒 1.3分
回転ディスクからのランダム読み出し(キューイングされた場合) > 10ミリ秒 1.7分
回転ディスクからのランダム読み出し(キューに大量に待ちがある) > 100ミリ秒 17分
最悪の条件の仮想ディスクI/O(ハードウェアコントローラ・RAID 5・キューイング・ランダムI/O) > 1000ミリ秒 2.8時間

ディスクがふたつのタイプのレイテンシを返す場合もある。オンディスクキャッシュにヒットするI/OとそうでないI/Oなど。こういったものをひとつにまとめて「平均レイテンシ」として表現するのは誤解を招く。実際には二峰分布になる。

9.3.3 キャッシング

ディスクI/Oのパフォーマンスが最高になるのは、ディスクI/Oがないとき。ソフトウェアスタックの多くのレイヤが、ディスクI/Oを避ける目的で、読み出しをキャッシングし・書き込みをバッファリングしている。

9.3.4 ランダムI/OとシーケンシャルI/O

ディスクI/Oのワークロードは、ディスク上のI/Oがおこなわれる相対位置(ディスクオフセット)にもとづき、ランダムかシーケンシャルかになる。

回転ディスクの場合

ランダムI/Oは、I/OとI/Oの間にディスクヘッドのシークとプラッターの回転が起きるため、余分なレイテンシがかかる。そのため、パフォーマンスのチューニングには、ランダムI/Oを検出し、それを削減するためのさまざまな方法を試みる必要があった。

フラッシュメモリベース(SSDなど)のディスクタイプの場合

ランダムI/OとシーケンシャルI/Oの間に違いはない。(ディスクによっては、アドレスルックアップキャッシュが、シーケンシャルアクセスには対応できてもランダムアクセスには対応できない、といった、他の要因で差が生まれる場合はある)

オフセットの違い

オペレーティングシステムから見たディスクオフセット」と「物理ディスク上のオフセット」が一致しない場合もある。たとえば、ハードウェアが提供する仮想ディスクは、複数のディスクにまたがって連続したオフセット範囲をマッピングすることがある。また、ディスクがディスクデータコントローラを介してオフセットをマッピングし直す場合もある。

こうした理由のため、オフセットを見ただけではランダムI/Oかどうかはわからず、計測した処理時間からランダムI/Oの発生を推測するしかない場合もある。

9.3.5 読み書きの割合

ランダム・シーケンシャルワークロードの区別とは別に、IOPSやスループットに関して読み出し/書き込みの割合を把握しておくと、システムの設計・構成する際に役立つ場合がある(「ブート以降、システムは読み出しが80%で実行されている」等)。

読み出しの割合が高いシステムの場合は、キャッシュを追加することで大きな効果を得られる。書き込みの割合が高いシステムの場合は、スループットIOSの上限を上げるためにディスクを追加すると効果が大きい。

9.3.6 I/Oの規模

平均I/Oサイズ・その分布も、ワークロード特性のうちのひとつ。I/Oサイズが大きければスループットも高くなるが、逆に一回のI/Oあたりのレイテンシは高くなる。

I/Oサイズ

  • ディスクデバイスサブシステムによって変更される場合がある
  • アプリケーションレベルでI/Oが発行されたあと、カーネルコンポーネントによって増減されることもある
  • フラッシュベースのディスクデバイスは、読み書きのサイズによってパフォーマンスが大きく変わる
    • 理想のI/Oサイズがある・一定のサイズでの読み書きのときに最大のパフォーマンスを発揮するような場合がある

9.3.7 IOPS は等しくない

I/Oの種類・オペレーション種別・規模、といった属性から、IOPSはいつでも同じにはならず、異なるデバイスやワークロードの間でIOPSを直接比較することはできない。IOPSの値は、それ単体では大した意味を持たず、IOPSだけでワークロードを正確に比較することはできない。

(たとえば回転ディスクの場合、5,000シーケンシャルIOPSのワークロードは、1,000ランダムIOPSのワークロードよりもずっと高速になる場合がある。)

IOPS を意味のあるものにするには、ランダムかシーケンシャルか/I/Oサイズはどれだけか/読み出しか書き込みか、といった詳細も組み込む必要がある。また、「使用率」や「サービス時間」などの"時間にもとづく指標"を使うことも検討する。これらは「結果として得られたパフォーマンス」を反映しているものなので、IOPSよりも簡単に比較できる。

9.3.8 データ転送以外のディスクコマンド

例えばキャッシュのフラッシュ命令など。これらのコマンドもパフォーマンスに影響を及ぼすことがあるので、他のI/Oが待機していてもディスクに使用率を発生させる場合がある。

9.3.9 使用率

使用率=一定時間にディスクがアクティブに作業を実行しビジー状態だった時間から計算されるもの。

ディスクI/Oは一般に遅いアクティビティのため、使用率の高低に関わらずパフォーマンスを下げる要因になり得る。アプリケーションの問題がディスクのI/Oのためにブロックされているものかどうかは調べる必要がある。

また使用率は一定時間における集計値であるため、そのインターバルの長さによってはメモリのフラッシュなどによる書き込みのバーストなどに気が付きにくい問題があることについても注意する。

100%の使用率の物理ディスクにI/O要求がされると、そのディスクは飽和状態になる。

仮想ディスクの使用率

ディスクコントローラなどが提供する仮想ディスクの場合、オペレーティングシステムからわかるのは、「仮想ディスクがビジー状態になっているのがいつか」程度で、仮想ディスクの土台となっているディスクのパフォーマンスについてはわからない場合がある。オペレーティングシステムが返す仮想ディスクの使用率の数字が、実際のディスクで発生しているものとかけ離れている場合がある。

  • ライトバックキャッシュを内蔵する仮想ディスクにおける書き込みワークロードでは、それほどビジーになっていないように見える場合でも、それはディスクコントローラがすぐに書き込み完了を返しているだけの場合がある
    • 実ディスクではその後しばらくビジー状態になっている可能性がある
  • 複数の物理ディスクから構成された仮想ディスクの場合、100%ビジーでも要求を受け付けられる場合がある
    • 「一部のディスクがずっとビジー状態」という意味の「100%」

9.3.10 飽和

「リソースの能力を超えてキューイングされた要求」の計測値が飽和。

使用率が100%未満であれば飽和も発生していない、というわけではない。使用率はあくまで一定インターバルにおける集計値であることを認識する。

9.3.11 I/O待ち時間

ディスクI/O待ちでブロックされたスレッドがCPUのディスパッチキューに入っている(スリーブ状態になっている)ときのアイドル状態で過ごす時間を示すもの。CPU単位のパフォーマンス指標。

CPUワークロードが他にあると、I/O待ちの時間をそちらに割くようになるので「待ち時間」は減る。また、アプリケーションのCPUサイクル効率(処理効率)が向上した場合では「待ち時間」は上がる。

「アプリケーションのスレッドがディスクのI/O待ちでブロックされた時間」の方がより実体に近い。これは静的/動的トレーシングによって計測可能。

そのため、CPUのI/O wait を見るときには、その時間の長短よりも、I/O待ち時間の存在有無をシステムのボトルネックの兆候として捉えることが重要。

9.3.12 同期I/Oと非同期I/O

アプリケーションI/OとディスクI/Oとが非同期的に実行されている場合には、ディスクI/Oレイテンシはアプリケーションパフォーマンスに直接は影響しないことを理解する(ディスク側でライトバックキャッシングを利用している場合はそうなる)。

  • アプリケーションが非同期読み出しのために先読みをおこなうケース
  • ファイルシステムがキャッシュウォームアップのためにプリフェット胃する
  • アプリケーションのコードパスがI/O要求をクリティカルなものにしていないケース

9.3.13 ディスクI/OとアプリケーションI/O

アプリケーションが発行したI/O要求の頻度と量が、実ディスクのI/Oと一致しない要因はいくつかある。

  • ファイルシステムによるI/Oの膨張・縮小。無関係なI/Oの発行。
  • メモリ不足によるページングの発生
  • デバイスドライバのI/Oサイズによるもの。I/Oサイズの切り上げ・断片化の発生

9.4 アーキテクチャ

9.4.1 ディスクのタイプ

磁気ディスク

  • 磁気ディスクのI/Oが遅いのは、大半がディスクヘッドのシークとプラッターの回転にかかる時間によるもの。
  • この時間を削減するためにおこなわれていること
    • キャッシングによりI/O自体をなくす
    • ファイルシステムの配置と動作
      • COWなど
    • 異なるワークロードを別ディスクに分離する
    • 異なるワークロードを別システムに分離する
    • エレベーターシーキング
      • I/Oをディスク上の位置に基いて並び替え、ディスクヘッドの移動量を最小限に抑える方法。他のI/O要求よりも早いからといって、完了時刻も一番早い、とはならない
    • 高密度ディスクの採用
    • ショートストローキングなどのパーティション構成
      • ショートストローキング:ディスクの外周側のトラックだけを使う方法
      • ゾーンビットレコーディング:トラックあたりのセクター数固定にしない方式。外周側の長井トラックはセクター数が増え、内周側のトラックに比べてスループットを高められる
    • より高速(1分あたりの回転数)なディスクの採用
  • それ以外の、磁気ディスクのI/Oを悪化させる要因
    • セクターが正しく読めなかった場合の読み出しの再試行。
    • ディスクデバイスに対して物理的な振動が加わることによってI/Oパフォーマンスに影響を与える場合がある

SSD

SSDのパフォーマンスは通常、オフセットとは無関係に一定のため、I/Oサイズがわかれば予測することもできる。ランダムI/Oかシーケンシャルかについても同様。

  • フラッシュメモリベースのSSD
    • データの書き込みの際には、一度にメモリブロック全体(複数のページを含む)を消去してから内容を書き込み直す必要がある。そのため、書き込み速度は読み込み速度よりも遅い。
    • ライトアンプリケーションが発生し、消去-書き込みサイクルのレイテンシが発生する場合もある
      • フラッシュメモリのブロックサイズよりも小さなサイズの書き込みの場合、ブロックの書き込み対象以外の部分を別の場所にコピーしてから全体を消去、その後に書き込む、というオペレーション
    • 寿命の問題
      • バーンアウト、データの減衰、読み出し妨害......
      • ブロックあたりの書き換え可能回数の制限がある
      • SSDコントローラは、異なるブロックに書き込みを分散させて特定のブロックに書き込みサイクルが集中するのを避けたりしている
    • 発生し得る異常

9.4.2 インターフェイス

9.4.3 ストレージタイプ

サーバにストレージを提供する方法について。

ディスクデバイス

オペレーティングシステムが個々のディスクを認識し、別々に観察可能なため、パフォーマンスツールでの分析ももっとも簡単におこなえる。

RAID

  • 少し前まではハードウェアRAID
    • コストの高い計算処理を専用のハードウェアでおこなえる利点
  • 最近はプロセッサ技術の進歩により、ソフトウェアRAIDに移行しつつある
  • リードモディファイライト
    • データがチェックサムを含むストライプとして格納されていると、書き込みI/Oで追加の読み出しI/Oと時間計算が必要になる
      • ストライプサイズよりも小さい書き込みでは、ストライプ全体を読み出し、バイトを書き換え、チェックサムを計算しなおしてから改めてストライプを書き込むことになるため
    • ストライプのサイズと書き込みの平均I/Oサイズを揃えることにより、追加の読み出しによるオーバーヘッドが削減されてパフォーマンスが上がる。
  • キャッシュ
    • ライトバックキャッシュを使うことで、リードモディファイライトが必要なときのパフォーマンス低下を緩和できる
  • その他、高度なディスクコントローラカードでは、パフォーマンスに影響を与える高度な機能を提供できる場合があることに注意する。
    • トロールリード
    • キャッシュフラッシュのインターバル
    • など

ストレージアレイ

  • 多数のディスクをシステムに接続できるようにするもの
  • システムへの接続は、通常は外部ストレージコントローラカードを介して接続される
    • カードや、カード <-> ストレージアレイ間の経路は、IOPSやスループットに限界がある
    • デュアル接続されることもある

NAS

  • NASアプライアンスと呼ばれる専用システムから既存ネットワーク越しにネットワークプロトコルを介してシステムにストレージを提供するタイプ。
    • これらは別個のシステムであり、そのようなものとして分析をする必要がある
  • クライアント上からも一部のパフォーマンス分析を実行することはできる
    • ワークロードの確認
    • I/Oレイテンシの調査
  • ネットワークのパフォーマンスに対して大きな影響を及ぼす。
    • ネットワークの輻輳やマルチホップのレイテンシによって問題が起きることがある

9.4.4 オペレーティングシステムのディスクI/Oスタック

ブロックデバイスインターフェイス

  • Unixの初期に、ブロック(ひとつ512バイト)単位でストレージデバイスにアクセスするために作られたもの
  • パフォーマンスを上げるためにバッファキャッシュをもつ
  • Unixでは、バッファキャッシュをバイパスするために、RawブロックデバイスI/Oと呼ばれる経路もあった
    • Direct I/O と似ているが違うもの
  • ブロックI/Oインターフェイスは、 iostat(1) から観察が可能
  • Linux では、カーネルのこの領域に機能を追加してブロックレイヤを作っている
    • ブロックデバイスインターフェイス -> 仮想ブロックドライバ -> エレベータレイヤ(I/Oスケジューラ) -> 物理ブロックドライバ ->
    • エレベータレイヤは、要求のソート、マージ、バッチ処理の機能を提供する
      • エレベータシーキングのアルゴリズムも含む
      • スループットを上げ、I/Oレイテンシを下げるのに寄与する
      • このレイヤのI/Oスケジューラは、I/Oをキューイングし、スケジューリングポリシーによって決められた最適な順序への並び替え(スケジューリングのし直し)をおこなう
        • 特にI/Oレイテンシの高いデバイスにおけるパフォーマンス向上に寄与する
      • 利用なスケジューリングポリシー
        • Noop : スケジューリングをおこなわない
        • Deadline : 例えば読み書きの限界を m 秒単位で指定できるようにするなど、レイテンシの限界を強制しようとするもの。
        • Anticipatory : I/Oパフォーマンスを予想するヒューリスティックスが加わった Deadline の拡張バージョン。
        • CFQ : 完全に公平なキューイングスケジューラがプロセスにI/Oタイムスライスを割り当てる。

9.5 メソドロジ

9.5.1 ツールメソッド

  • iostat
    • 拡張モードを使うことで、以下のようなものを探す。
    • ビジー状態(使用率60%以上)のディスク
    • 長い(10m秒以上 など)平均処理時間
    • 高いIOPS
  • iotop
    • どのプロセスがディスクI/Oをおこなっているかの究明
  • dtrace / stap / perf
    • ディスクI/Oのレイテンシを詳細に解析し、レイテンシの外れ値(100m 秒以上 など)を探す
  • ディスクコントローラ固有ツール
    • ベンダー提供ツール。

問題が見つかった場合には、使えるツールが出力したすべてのフィールドを解析し、コンテキストを調べる。

9.5.2 USEメソッド

ディスクデバイス

個々のディスクデバイスについて、以下のものをチェックする。

  • 使用率:デバイスがビジーだった時間
    • 仮想ディスクの場合、実際のものを反映していない場合があるので注意(9.3.9 使用率)。
  • 飽和:I/Oがキューで待機している度合い
  • エラー:デバイスのエラー
    • 最初にチェックする。
    • デイスクエラーがあっても、システムは遅くなるものの正しく動作するようになっているので見過ごすことがある

ディスクコントローラ

個々のディスクコントローラについて、以下のものをチェックする。

  • 使用率:スループット稼働率について、現在値と最大値を比較する
    • ディスクコントローラの限界(スループットのバイト/秒、稼働率のオペレーション/秒)によって定義される
  • 飽和:コントローラの飽和によってI/O待ちが発生している度合い
  • エラー:コントローラのエラー

可観測性ツールがディスクごとの計測値しか表示しない場合、コントローラがひとつだけなら、全てのディスクのIOPSとスループットを合計することで、コントローラのIOPSとスループットになる。複数のコントローラを持つ場合は、どのディスクがどのコントローラに属するかを調べる必要がある。

ディスクコントローラとトランスポートのパフォーマンスは見過ごされがちだが、この部分の能力は接続されているディスクの能力を超えていることが多いので、システムのボトルネックの原因となることはあまりない。

9.5.3 パフォーマンスモニタリング

ディスクパフォーマンスの主要な指標は、以下の通り。

  • ディスクの使用率
    • 2秒以上も使用率が100%のままなら、問題が起きている可能性が非常に高い
  • 応答時間
    • 長引くとパフォーマンスに影響を及ぼす。
    • 1秒あたりの平均としてモニタリングした上で、最大値や標準偏差の値も含めると良い。
    • ワークロードがまちまちになっているときや、新しい競合するワークロードが届いたときにも長引くことがある。
    • 「正常」や「異常」の値は、ワークロード、環境、レイテンシ要件によって変わる。「よいことがわかっているワークロード」と「悪いことがわかっているワークロード」でマイクロベンチマークを実施し、応答時間を計測するとよい。

これらの指標はディスクごとに解析することで、アンバランスなワークロードや性能が悪化している個別のディスクを探し当てるのに役立つ。

上記の2指標は、ディスクパフォーマンスの「結果」である。ワークロードの特性を調べるためには、IOPSとスループットなどの指標も追加することで、キャパシティプランニングのための重要なデータを得ることに繋がる。

9.5.4 ワークロードの特性の把握

ディスクI/Oワークロードを特長付ける基本属性には、以下のようなものがある。

  • I/Oの頻度
  • I/Oスループット
  • I/Oサイズ
  • ランダム or シーケンシャル
  • 読み書きの比率

これらを総合することで、ディスクがどのような処理を要求されているかの概要がわかる。これらの特性は毎秒変わっていく場合があるため、ワークロードの特性をよりよく掴むために、平均値だけでなく最大値もキャプチャするようにする。

ワークロードの抽出のためのチェックリスト

  • システム全体でのIOPSはどうなっているか。ディスクごと・コントローラごとではどうか。
  • システム全体でのスループットはどうなっているか。ディスクごと・コントローラごとではどうか。
  • どのアプリケーション、またはユーザーがディスクを使っているか。
  • どのファイルシステム、またはファイルがアクセスされているか。
  • エラーは起きているか。それは無効な要求によるものか、それともディスクから発行されたものか。
  • 利用可能ディスクの間でのI/Oのバランスはどうか。
  • 個々のトランスポートパスごとのIOPSはどうなっているか。
  • 個々のトランスポートパスごとのスループットはどうなっているか。
  • データ転送意外のディスクコマンドとしてはどのようなものが発行されているか。
  • ディスクI/Oはなぜ発行されているのか(カーネルレベルコールパスはどうなっているか)。
  • ディスクI/Oのうちのどれくらいがアプリケーションに対して同期的なものか。
  • I/Oの到着時刻の分布はどうなっているか。

パフォーマンス特性の把握のためのチェックリスト

  • 個々のディスクはどれくらいビジーか。
  • 個々のディスクはどれくらい飽和しているか(キューイング)の度合い
  • 平均I/Oサービス時間はどれくらいか。
  • 平均I/O待ち時間はどれくらいか。
  • レイテンシの高いI/O外れ値はあるか。
  • I/Oレイテンシの完全な分布はどうなっているか。
  • I/Oスロットリングなどのシステムリソースコントロールはあるか。それがアクティブになっているか。
  • データ転送以外のディスクコマンドのレイテンシはどうなっているか。

9.5.5 レイテンシ分析

システムを掘り下げて、レイテンシの原因を見つけようとするもの。ディスクの場合、行き着く先は「I/Oが要求されたときから完了割り込みが発生したときまでの時間」、つまりディスクインターフェイスになることが多い。この時間がアプリケーションレベルのI/Oレイテンシと一致するなら、I/Oレイテンシはディスクによるものだと考えて間違いない。異なる場合には、オペレーティングシステムスタックの異なるレベルでレイテンシを計測することで、原因がどこかがわかる。

9.5.6 イベントトレーシング

すべてのI/Oイベントの情報をキャプチャし、別々に記録する。個々のI/Oについて、以下のような詳細情報を書き込む必要がある。

  • ディスクデバイスID
  • I/Oタイプ(読み出し / 書き込み)
  • I/Oオフセット(ディスク上の位置)
  • I/Oサイズ(バイト数)
  • I/O要求タイムスタンプ(デバイスに対してI/O要求が発行された時刻)
  • I/O完了タイムスタンプ(I/Oイベントが完了した(完了割り込みのあった)時刻)
  • I/O終了ステータス(エラー)
  • PID, UID, アプリケーション名、ファイル名
  • データ転送以外のディスクコマンドのイベント(及びそれらのコマンドの詳細)

9.5.7 静的パフォーマンスチューニング

構成された環境の問題点を明らかにする。以下のような側面をチェックする。

  • ディスクが何個あるか。それぞれどのタイプか。
  • ディスクファームウェアのバージョンはどうなっているか。
  • ディスクコントローラは何個あるか。どのインターフェイスタイプのものか。
  • ディスクコントローラカードは、高速スロットに接続されているか。
  • ディスクコントローラのファームウェアのバージョンはどうなっているか。
  • RAIDは構成されているか。ストライプの幅を含め、正確にどのような形か。
  • マルチパスは使えるか。構成されているか。
  • ディスクデバイスドライバのバージョンはどうなっているか。
  • ストレージデバイスドライバのためのオペレーティングシステムのバグやパッチはあるか。
  • ディスクI/Oにリソースコントロールは使われているか。

9.5.8 キャッシュチューニング

アプリケーションレベル、ファイルシステム、ディスクコントローラ、ディスクそのもの、など、システムにはさまざまなキャッシュが含まれている場合がある。

  1. 対象のシステムにどのようなキャッシュがあるかをチェック
  2. そのキャッシュが機能していること・どれくらいうまく機能しているかをチェック
  3. キャッシングするワークロードをチューニング
  4. そのワークロードに合わせてキャッシュをチューニング

といったことをおこなうことが、キャッシュをチューニングするということ。

9.5.9 リソースコントロール

オペレーティングシステムによる、プロセスやプロセスグループに対して加えられたディスクI/Oのアロケート量の制限。

9.5.10 マイクロベンチマーキング

ファイルシステムによる作用から分けて分析をおこなえるよう、raw デバイスパスを使ってテストする。

マイクロベンチマーキングのテスト対象となる要素は、以下。

  • 方向:読み出し or 書き込み
  • ディスクのオフセットパターン:ランダム or シーケンシャル
  • I/O サイズ:512バイト 〜 1MB
  • 並行処理:処理中のI/Oの数、もしくはI/Oを実行しているスレッドの数
  • バイスの数:1台 or 複数台

ディスクパフォーマンスのテストのためのマイクロベンチマーキング

ディスク単位でのマイクロベンチマーキングにより明らかになるものは以下。

  • ディスクのスループット上限(MB/秒)
  • ディスクオペレーションの頻度の上限(IOPS)
  • ディスクのランダム読み出しの上限(IOPS)
  • 読み出しレイテンシのプロファイル(平均 m 秒)
  • ランダムI/Oレイテンシのプロファイル(平均 m 秒)

ディスクコントローラのテストのためのベンチマーキング

  • コントローラのスループット上限(MB/秒)
  • コントローラオペレーションの頻度の上限(IOPS)

9.5.11 スケーリング

各ハードウェアには性能限界があり、仮にチューニングを効果的に実施したとしても、この上限を上回る性能を出すことはできない。さらに上の性能が必要な場合には、ディスクのスケーリングをおこなう。

  1. スループットとIOPSでターゲットディスクのワークロードを明らかにする
    • 現在のディスクのスループットとIOPSでユーザー数を表現し、目標とするユーザー数に合わせてスループットやIOPSの数値をプランニングする。
    • 同時にキャッシュのスケーリングも考慮に入れる。(ユーザーあたりのキャッシュの比率が小さくなり、ディスクI/Oが増え、ディスクワークロードが増える可能性がある)
    1. で計算したワークロードを支えるために必要なディスクの数を計算する
    2. 各ディスクのスループットとIOPSの上限を前提としてしまうと、ディスクの使用率が100%になるようなシステムになってしまう(飽和とキューイングによるパフォーマンス悪化を引き起こすことになる)ので、上限値は使用せず、目標とする使用率に合わせて値をスケーリングするようにする。

9.6 分析

9.6.1 iostat

  • iostat は、ディスクごとのI/O統計を集計し、ワークロードの特性、使用率、飽和を示す指標を提供
  • iostat 自身のオーバーヘッドは無視してよい程度。
  • デフォルト(オプション指定なし)では、CPUとディスクについてのブート移行の集計値が得られる。
$ iostat
Linux 3.10.0-327.10.1.el7.x86_64 (hostname)     20171028日    _x86_64_    (1 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.95    0.00    0.36    0.08    0.05   98.56

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
xvda              4.24       118.89        13.78 2204316514  255414483
  • tps : 1秒あたりのトランザクション(IOPS)
  • kB_read/s, kB_wrtn/s : 1秒あたりの読み出し kb 数と書き込み kb 数
  • kB_read, kB_wrtn : 読み出し、書き込みの合計 kb 数

-x オプションの指定により、拡張出力モードになる。追加で出力される情報は、ワークロードの特性の把握をするうえで役立つ IOPS とスループットの指標、USEメソッドで役立つ使用率やキューの長さ、パフォーマンスの特性の把握とレイテンシ分析で役立つディスクの応答時間

$ iostat -xkdz
Linux 3.10.0-327.10.1.el7.x86_64 (hostname)     20171028日    _x86_64_    (1 CPU)

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
xvda              2.67     2.22    3.42    0.82   118.89    13.78    62.55     0.02    4.23    3.90    5.64   0.36   0.15
  • rrqm/s : 1秒間にドライバの要求キューにセットされ、マージされた読み出し要求の数
  • wrqm/s : 1秒間にドライバの要求キューにセットされ、マージされた書き込み要求の数
  • r/s : 1秒間にディスクデバイスに発行された読み出し要求の数
  • w/s : 1秒間にディスクデバイスに発行された書き込み要求の数
  • rkB/s : 1秒間にディスクデバイスから読み出された kb 数
  • wkB/s : 1秒間にディスクデバイスに書き込まれた kb 数
  • avgrq-sz : セクター内の平均要求サイズ
  • avgqu-sz : 「ドライバの要求で待機している要求」と「デバイスでアクティブに処理されている要求」の合計の平均
    • マージ後のサイズ。
    • 小さい場合なら、マージできないランダムI/Oワークロードだと考えられる。
    • サイズが大きい場合は、I/O要求のサイズが大きいか、シーケンシャルなワークロードがマージされたことを示す。
  • await : I/O応答時間の平均(ドライバの要求キューで待機している時間とデバイスのI/O応答時間を含む(m 秒))
  • r_await : await と同じ/読み出しのみ(m 秒)
  • w_await : await と同じ/書き込みのみ(m 秒)
  • svctm : ディスクデバイスの平均I/O応答時間(推定・m 秒)
  • %util : デバイスがI/O要求を処理していてビジーだった時間の割合(使用率)
    • ビジー状況の計測値に過ぎず、複数のディスクからなる仮想デバイスではあまり意味をもたない可能性がある
    • IOPS(r/s + w/s)とスループットrkB/s + wkB/s)により求められる「かけられた負荷」を見る方が良い場合がある

rrqm/s, wrqm/s がノンゼロということは、シーケンシャルなワークロードが処理された兆候でもある。r/s, w/s は、実際にデバイスに発行された要求の数の平均を示すもの。

パフォーマンスの指標でもっとも重要なものは await。ライトスルーなどを使っている場合には r_await の解析に集中してよい。

9.6.2 sar

現在のアクティビティを観察することに加え、履歴データをアーカイブし、報告するように構成することもできる。

$ sar -d
Linux 3.10.0-327.10.1.el7.x86_64 (hostname)     20171029日    _x86_64_    (1 CPU)

000001秒       DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz     await     svctm     %util
001001秒  dev202-0      3.29     83.84     11.39     28.97      0.01      2.56      0.35      0.12
002001秒  dev202-0      2.94    120.56     12.46     45.22      0.01      2.60      0.33      0.10
003001秒  dev202-0      1.67     41.37      9.37     30.30      0.00      2.17      0.37      0.06
004001秒  dev202-0      3.41    117.02     11.53     37.70      0.01      2.89      0.33      0.11
005001秒  dev202-0      5.55    250.26     31.56     50.82      0.02      2.79      0.24      0.13

多くの項目は iostat と同じ。

  • tps : 1秒あたりのデバイスデータの転送量
  • rd_sec/s, wr_sec/s : 1秒で読み書きしたセクター数

9.6.3 pidstat

-d オプションでディスクI/Oの統計を表示させられる。

$ pidstat -d
Linux 3.10.0-327.10.1.el7.x86_64 (hostname)     20171029日    _x86_64_    (1 CPU)

085052秒   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
0850521001      1890      0.00      0.00      0.00  ruby
0850521001      6068      0.03      0.00      0.00  ruby
0850521001      6389      0.00      0.00      0.00  pidstat
0850521001      7822      0.01      0.00      0.00  ruby
0850521001     26271      0.00      0.00      0.00  ruby
0850521001     27852      0.09      0.00      0.00  ruby
0850521001     27865      0.03      0.00      0.00  ruby
  • kB_rd/s : 1秒あたりの読み出し(kB)
  • kB_wd/s : 1秒あたりの書き込み要求(kB)
  • kB_ccwr/s : 1秒あたりの書き込み取り消し(例:フラッシュする前に上書きされたもの)

自分がオーナーではないプロセスのディスク統計を表示できるのはスーパーユーザーだけ。

9.6.4 DTrace

カーネル内から以下のようなイベントを解析するために使用できる。

9.6.5 SystemTap

Linux であれば、ディスクI/Oイベントの動的トレーシングのために SystemTap も使うことができる。

9.6.6 perf

perf はブロックデバイスのトレースポイントを提供しており、これを用いてトレーシングすることで基本的な情報を得ることができる。

9.6.7 iotop

ディスクI/Oの項目を含む、top の一種。

9.6.8 iosnoop

ブロックデバイスインターフェイスを介して同時にすべてのディスクをトレーシングし、すべてのディスクI/Oを1行ずつにまとめて出力するもの。短い DTrace スクリプトでもあるので、より多くの情報を出力するように書き換えることも容易にできる。トレーシングとレイテンシ分析のために役に立つ。

9.6.9 blktrace

Linux のブロックデバイスI/Oイベントのカスタムトレーシング機能で、データのトレーシング・バッファリングするカーネルコンポーネントと、制御・レポートするメカニズムをもつユーザーランドツールから構成されている。

blktrace(8), blkparse(1), btrace(8) の3つのツールから構成されている。

  • blktrace
    • カーネルブロックドライバのトレーシングを可能にするもの
    • 未加工のトレースデータを取得する
  • blkparse
    • blktrace で取得したデータを処理し、人間が読める出力を得るためのもの
  • btrace
    • blktrace と blkparse の両方を実行するもの。
    • 以下の実行と同じ出力を得られる。
# blktrace -d /dev/sda -o * | blkparse -i -
# btrace /dev/sda

9.6.10 MegaCli

特定のディスクコントローラに付属している分析ツール。

ディスクコントローラは、システムの外のハードウェアとファームウェアから構成されている。オペレーティングシステムの分析ツールは、動的トレーシングを用いても、これらの内部を直接観察することはできない。

9.6.11 smartctl

ディスクは、キューイング / キャッシング / エラー処理などのディスクオペレーションを制御するためのロジックを持っているが、これらはディスクコントローラと同様、ディスクの内部動作となるため、オペレーティングシステムで直接観察することはできず、I/O要求とそのレイテンシの観察結果から推測するしかない。

最近のドライブは、健全性に関するさまざまな統計情報を含む S.M.A.R.T.(Self-Monitoring, Analysis and Reporting Technology)データを提供している。

9.6.12 ビジュアライゼーション

ディスクのパフォーマンス分析で役立つビジュアライゼーションの方法について。

折れ線グラフ

  • IOPS、スループット、使用率の時系列的な変化を示す際に用いる
  • 負荷の変化、反復されるイベントのインターバルなどを知るために役立つ
  • グラフ化されている指標が何であるか、については注意が必要。
    • 平均値は外れ値などの異常なふるまいを隠してしまう
    • 長いインターバルによる平均は、短期的な変動を隠してしまう

散布図

  • 外れ値の発生を捉えやすくなる

オフセットのヒートマップ

  • 列の量子化
  • 散布図を使うと重なり合って読みにくくなるような場合にはヒートマップを用いる
  • ディスクオフセット(ブロックアドレス)をy軸に、時間範囲をx軸に置き、ある時間範囲に分類されるI/Oの数とレイテンシの範囲に基いて色分けをする

レイテンシのヒートマップ

  • I/Oレイテンシの完全な分布を示すために利用可能

使用率のヒートマップ

  • y軸にディスクの使用率、x軸に時間範囲を置き、時間範囲と使用率が同じディスクの数をその色の濃さで表現することで、デバイスの使用率のバランスや個々の外れ値を可視化することができる

9.7 実験

ディスクI/Oのパフォーマンスをテストする際の手法とツールについて。

9.7.1 アドホックテスト

dd(1) コマンドを用いることで、シーケンシャルなディスクオペレーションのパフォーマンスのアドホックテストに利用可能。 1MBのI/Oサイズでのシーケンシャル読み出しのテストは dd if=/dev/sda1 of=/dev/null bs=1024k count=1k

9.7.2 カスタムロードジェネレータ

カスタムワークロードをテストするためのもの。デバイスパスをオープンし、ワークロードを送り込む簡単なCプログラムなどが該当。

9.7.3 マイクロベンチマーキングツール

hdparm(8) の -T オプションはキャッシングされた読み出し、 -t オプションはディスクデバイス読み出しをテストできる。

9.7.4 ランダム読み出しの例

9.8 チューニング

9.8.1 オペレーティングシステムのチューニング可能パラメータ

  • ionice
    • I/Oスケジューリングクラスやプロセスの優先度を設定する
  • リソースコントロール
    • Linux だと、cgroup の blkio サブシステムが、プロセスやプロセスグループに対するストレージデバイスのリソースコントロールを提供している
  • オペレーティングシステムのチューニング可能パラメータ
    • /sys/block/sda/queue/scheduler
      • I/Oスケジューラのポリシーの選択

9.8.2 ディスクデバイスのチューニング可能パラメータ

Linux では、hdparm(8) でさまざまなディスクデバイスのチューニング可能パラメータを設定可能。

9.8.3 ディスクコントローラのチューニング可能パラメータ

ディスクコントローラのモデルとベンダーによって異なる。

9.9 練習問題

1. ディスクの用語について

  • IOPS とはなにか
    • 1秒間あたりの読み書きオペレーションの回数
  • ディスクのI/O応答時間とは何か
    • ディスクに対してI/Oの要求がされてから、実際にI/Oが完了するまでの時間。
  • サービス時間と待ち時間の違いは何か
    • 「キューでの待ち時間を除く、I/Oがアクティブに処理されている時間」がサービス時間。
    • 「I/Oがキューのなかで処理を待っている時間」が待ち時間。
    • 「どこで計測されるか」によっても影響を受ける。
      • オペレーティングシステムから見たときの「サービス時間」はディスクに対してI/Oを発行したときから完了割り込みが発生するまでの時間になる
      • ディスクから見たときの「サービス時間」は、I/Oがオンディスクキューで待機していた時間を除き、ディスクがアクティブにI/Oを処理している時間を指す
  • レイテンシ外れ値とは何か
    • 大半のレイテンシと著しくかけ離れたレイテンシ数値のこと
    • 例えばライトバックキャッシュを内蔵しているような場合、キャッシュに対する書き込みの場合は短いレイテンシが得られるが、そのフラッシュの際のレイテンシは大きくなる
  • データ転送以外のディスクコマンドとは何か
    • キャッシュのフラッシュコマンドなど。

2. コンセプトについての問い

  • ディスクの使用率と飽和についての説明
    • 使用率:一定時間にディスクがアクティブに作業を実行しビジー状態だった時間から計算されるもの。
    • 飽和:「リソースの能力を超えてキューイングされた要求」の計測値。
    • 使用率が100%未満であれば飽和も発生していない、というわけではない。使用率はあくまで一定インターバルにおける集計値である。
  • ランダムディスクI/OとシーケンシャルディスクI/Oのパフォーマンスの違い
    • 回転ディスクかSSDかによっても異なる
    • 回転ディスクの場合、そのI/Oにかかる所要時間の大半がディスクヘッドのシークとプラッターの回転にかかる時間によるものになるため、それらの発生が必須となるランダムI/Oのレイテンシはどうしても長くなる
    • SSDの場合では、ランダムI/OとシーケンシャルI/Oの間での違いは基本的にない
  • 読み出しI/Oと書き込みI/Oにおけるオンディスクキャッシュの役割についての説明
    • 大きなレイテンシの発生要因であるディスクアクセスを省略しデータを読み出すための役割
    • シーケンシャルな書き込みI/Oを一定の単位でまとめて実行するためのバッファとしての役割

3. 難しい問題

  • 仮想ディスクの使用率(ビジー状態の割合)が誤解を招く理由
    • 仮想ディスクの場合、オペレーティングシステムからわかるのは、「仮想ディスクがビジー状態になっているのがいつか」程度で、仮想ディスクの土台となっているディスクのパフォーマンスについてはわからない場合があるため。
    • オペレーティングシステムが返す仮想ディスクの使用率の数字が、実際のディスクで発生しているものとかけ離れている場合がある。
    • ライトバックキャッシュの恩恵によるものであったり、複数の物理ディスクのうちの一部のディスクの使用率が反映されてしまっているものだったり
  • I/O待ち時間という指標が誤解を招く理由
    • I/O待ち時間:ディスクI/O待ちでブロックされたスレッドがCPUのディスパッチキューに入っている(スリーブ状態になっている)ときのアイドル状態で過ごす時間を示すもの。CPU単位のパフォーマンス指標。
    • そのため、CPUワークロードが他にあると、I/O待ちの時間をそちらに割くようになるので「待ち時間」は減り、また、アプリケーションのCPUサイクル効率(処理効率)が向上した場合では「待ち時間」は上がるため。
    • 「アプリケーションのスレッドがディスクのI/O待ちでブロックされた時間」の方がより実体に近い。
  • RAID 0(ストライピング)と RAID 1 のパフォーマンス特性について
    • RAID 0
      • ランダム / シーケンシャル I/O のパフォーマンスは最高になる
    • RAID 1
      • 実装によっては、すべてのドライブから同時に読み出すことができるため、ランダム / シーケンシャル読み出しは優れたパフォーマンスをもつ。
      • 書き込みは、ミラー内のもっとも遅いディスクのスピードに制限され、スループットにかかるオーバーヘッドは倍(ドライブ2台)になる
  • ディスクが過負荷になったとき、アプリケーションのパフォーマンスに対する影響を含めて何が起きるのかを説明せよ
    • ディスクI/Oは一般に遅いアクティビティのため、ディスクが過負荷に陥るとシステム全体のパフォーマンスを下げる要因となる・ディスクI/Oのために処理がブロックされる場合がある
    • CPU の I/O 待ち時間が増えるが、CPUワークロードが他にある場合ならばそちらにCPUリソースを割くようになる
  • ディスクコントローラが過負荷になったとき(スループットかIOPSのどちらかで)、アプリケーションのパフォーマンスに対する影響を含めて何が起きるのかを説明せよ
    • ひとつのディスクコントローラに複数のストレージデバイスが接続されている場合、仮にストレージデバイス側に余力があったとしても、ディスクコントローラが過負荷になった場合は全体としての性能のボトルネックになりうる


follow us in feedly