ディスク from 詳解システム・パフォーマンス
9章 ディスク
コンセプト - ディスクパフォーマンス上の概念について
本節では議論のために応答時間(E2Eなレイテンシ)を「待ち時間」と「サービス時間」に分類する
待ち時間はある時点でキューに積まれ実際の処理が走ってない時間
サービス時間は待ち時間以外の、実際にそのデバイスの責務である処理が進んでいる時間
ディスクパフォーマンスの値がどこから計測されているか把握しておくべきだ
OSはブロックデバイスインターフェースに対し命令するが、実際にはその下にも2,3段レイヤが挟まっており、そこで排他制御やキャッシングされる場合がある
ブロックデバイスレベルのレイテンシには待ち時間が複数計上されていると見るべき
iostat(1)もブロックデバイスレベル
一般的なディスクIOスタック
Raw IOはここに着地する
ブロックデバイスインターフェースにもバッファがある
3. ターゲットIOドライバ
4. マルチパスIOドライバ(無い場合もある)
ディスクのパフォーマンスはディスクかディスクコントローラのどちらかに制約される
後者が問題にあることは少ない
6. ディスクデバイス
ディスクはキャッシュを積んでいることがあるので、レイテンシはヒットの有無で二峰分布を成す
iostatは平均レイテンシを表示するので適切な理解は得られない 物理ディスクドライブは複数のディスクを一つの論理ディスクとして提供することもあるので、OSからみたディスクオフセットが物理オフセット上の位置と一致しないことがありうる
実際にディスクコントローラが賢くなることで物理オフセット≠OSから見たオフセットが増えている
特にSSDではセルの耐久性を維持するためにアクセスパターンをデバイス内で管理している
無駄に悲観的になる必要はなくて、コントローラが解釈するとしても、オフセットの連続性は「積極的にランダムでない」程度の意思表示になるだろう
ディスクの半径の方向へ読み込み先を動かすのがシークで、円弧の方向へ動かすのがディスクの回転である
ある一定時間の読み書き比率や読み書きのアクセスパターンを把握すると最適化の助けになる
読み重視ならワークロードに応じたキャッシュを追加する
書き重視ならスループットやIOPSの上限を上げるためにディスクを追加する
COWのファイルシステムを採用している場合、アクセスパターンが特殊になるので、それに対応する
書き込みはシーケンシャルになるが、読みがランダムで遅くなるので、そこにキャッシュを加えてやるなど
特にSSDはパフォーマンスが最大になる読み書きサイズがあるのでベンダのドキュメントやマイクロベンチマーキングで確認せよ
現在のサイズは確認できるツールがある
使用率と飽和
デバイスが仮想ディスクを見せてくることから、OSが見た使用率が直感に反することがある
ライトバックキャッシュを持つディスクの場合、書き込みでそれほどビジーにならないように見えるが、書き込み後実際のディスクはビジー状態であるかもしれない
複数の物理ディスクを束ねた仮想ディスクでは100%ビジーであっても一部のアイドル状態のディスクが受け付ける場合がある
この節のキューイングされすぎて60%くらいになる場合があるってのがよくわからない
日本語版 9.3.9 (P. 425)
2章メソドロジの 図2-19(日本語版P.66) のグラフを参照
待ち行列のM/D/1モデルにて、サービス時間が固定のストレージを考えると、使用率60%を境目に平均レイテンシが指数関数的増大を見せることを示している
これはサービス時間にばらつきが起きない理想的な場合であり、実際にはもっと手前の使用率が境界かもしれない
ストレージはCPUと違って基本的に割り込めないキューイングシステムであり、優先度によるプリエンプションが働かないのでこのような挙動になる
デバイス内のキューが直接見えないので、飽和はOS内のデバイス待機キューの平均の長さで計算される
使用率は区間に依存することに注意
すなわち50%だとして、前半が100%で後半が0%なのかもしれない
区間で慣らされることでバーストを見逃している可能性がある
実際にその区間で何が起きたかを詳細に知りたい場合、トレーサを使ってIOイベントを分析すること
IO待ち時間
スレッドがディスクIO待ちでブロックされ、CPUがアイドル状態の時間を示す
CPUの本当のアイドル時間との区別をつけるために用意された
非常に誤解を招きやすい
CPU-intensiveなタスクが追加されるとIO待ち時間は減る
逆に走っているソフトウェアが改善されCPU処理の時間が減ると、IO待ち時間は増える
あるスレッドがディスクIOでブロックされた時間を計測したほうが適切
トレーサで取得可能
しかしLinuxではIO待ち時間が使われ続けている
ただしCPUがアイドルかつディスクがビジーな状況を示すことはできる
一つの利用法として、IO待ち時間があるならシステムにボトルネックがあると捉え、(CPU使用率が高いとしても)IO待ち時間を最適化するように調整するとよい
その時のプロセスのコードパスを解析し、ブロッキングIOの場合そこがボトルネックになっているかも
ファイルシステムの章で説明したように、OSレベルのIOとディスクレベルのIOでは頻度や量が一致しないことが多い
ファイルシステムによる膨張や削減
メモリ不足によるページング
デバイスドライバレベルのIOサイズに合わず、切り上げられたり、逆に分割されている場合
書き込みにいたるアーキテクチャ全体を学んで分析に役立てよう
アーキテクチャ - 著名なディスクやストレージの構成方法について
磁気ディスク HDD
酸化鉄の粒子を染み込ませた一枚以上のディスクからなる
これ1枚1枚をプラッターという
ディスクヘッドが同時に読めるように複数ヘッドが付いていることがある
プラッターを半径方向に微分(伝われ)したのがトラック
同一トラック内で読む位置を変えるのが回転
トラックを切り替えるのがシーク
トラックをディスクヘッドで書き込みできる最小単位に分解したのがセクター
シークや回転を減らすために
キャッシング
読み書き戦略の選択、コピーオンライトなど
異なるワークロードを別ディスクへ分離する
異なるワークロードの別システムへの移動
ディスク自体が行うエレベータシーキング
高密度ディスク
パーティション構成、ショートストローキングなど
ディスクの回転速度
こうやってみると多数のパラメータのうちの一つでしかない
スループットの理論的上限
トラック辺りのセクター数の最大 * セクターサイズ * rpm
トラックやプラッターなどの構成がOSに対して仮想化されつつある現在では効力を失いつつある
頻度の高いワークロードに対してプラッターの外周部のトラックのみを使用し、それ以外の内側を頻度の低いアーカイブ用に持ちいる
ヘッドの移動が狭い位置に制限され、アイドル状態復帰後のシーク量が狭く済む
またゾーンビットレコーディング採用ディスクでは内側よりスループットが高い
ディスクベンチマークではショートストローキングの有無で初動のレイテンシが違うため、確認が必要
トラックによって長さが違うので、それぞれのビット数も変えよう、という実装方法のこと
直感的には普通そうあってほしいけど、過去にはそうでなかったっぽい
ディスク外周部の方がよりスループットがあがる
オンディスクキャッシュでIOをヘッドの移動量が最小になるようにソートすること
エレベータがボタンを押された順ではなく、ボタンが押された通り掛けの階で止まることから
プロセススケジュールと同様、優先度付きキューは常に公平性の問題を抱える
あるIOのレイテンシが直感以上に増大することがあり得る
ECC (エラー訂正コード)
セクターの末尾近くに配置される
セクターが読みだせなかった場合、次の回転で読みだしを再試行する
磁気ディスクは物理実装なので、ヘッドの位置を少しずつかえ複数回再試行することもある
つまり異常に遅いIOの原因として頭に入れておく必要がある
振動
https://www.youtube.com/watch?v=tDacjrSCeq4
エラーなしにIOレイテンシがめっちゃ思いディスクがあるらしい
ディスクの歩留まりの問題?
ディスクデータコントローラ
ディスクのマイクロプロセッサ上に実装されているファームウェア
OSが指定したオフセットをどう配置するかはコントローラが決める
例えばZBRが実装されているのに、OSからみて全トラックのセクタ数が共通だったりする
ソリッドステートドライブ SSD
固体電子工学を応用した非揮発性メモリをさす
可動部品がなく、振動による影響をうけない
一部は非揮発性DRAM(NVDRAM)を使っているが、大半はフラッシュメモリを採用している
フラッシュの場合書き込みはメモリブロックを削除してから書き込む必要がある
なのでフラッシュメモリ
メモリブロックは複数のページの集まりだったりする
読みに対し書き込みは遅くなる
フラッシュメモリのタイプ
SLC(Single Level Cell)はセル辺り1ビットを格納するのに対し、MLC(Multi)は2ビット、TLC(Tri)は3ビット格納できる。
SLCはMLCと比べハイパフォーマンスであり、コスト的に高くなる
コントローラ
コントローラの役割
入力
ページ(通常8kB)単位に発生する読み書き
書き込みは消去されたページのみに発生する
ページ32-64個分のブロック単位で消去される
出力
ハードディスクのブロックインターフェース
つまり任意のセクター(512B)に対する読み書きのエミュレート
実装
FTLはフリーブロックも扱うためにLog-structured File Systemなどの独自ファイルシステムも使う
IOサイズはマイクロベンチマーキングで調べるように
フラッシュに必要な命令はブロックインターフェースとずれがある
TRIMコマンド
SSDに使われてない領域を知らせ、SSDがフリーブロックのプールを組み立てやすくなるようにする
寿命
NANDセルは使い続けると寿命がくるので延命技術がある
どうしても追加の新鮮な領域が欲しい時用に予備の領域を予約しておく
異なるブロックに書き込みを分散させて特定ブロックへの読み書きの集中を避ける
SLCだと信頼性が高く、集積度があがるほど落ちる
コンシューマレベルだと価格競争のために最近だとTLCの上にQLCとか言いだしてる
意識しておくべき異常
寿命によるレイテンシ外れ値
ECCチェックのためのリトライなどで遅くなる
フラグメンテーションによるレイテンシ上昇
FTLブロックマップをクリンナップすると解決できることがあるらしい
SSDが内部圧縮を実装している場合
インターフェース
SCSI
SASとかつかえ
SAS
2012年12Gbpsになった
8b/10bエンコーディングのために実行速度は帯域幅の80%になる
冗長コネクタ、リンクアグリゲーション、IOマルチパス、SASドメイン、ホットスワップ、SATAに対する互換性など
主にエンタープライズ向けの冗長化に秀でる
SATA
同期コストが掛かることから、パラレルATAからシリアルになった
SCSI -> SASも似た理由
6Gbpsだが、8b/10bエンコーディングのために実行速度は帯域幅の80%になる
IO命令のキューイングに対応
ストレージの提供方法
ディスクデバイス
RAID (Redundant Array of Independent Disks)
ハードウェアRAIDの方がチェックサムとパリティの計算をオフロードできるが、昨今はCPUが進歩していて気にならなくなりつつある
むしろOSからの可観測性的にソフトウェアRAIDの方が有利
ミラーリングはディスク複数から同時に読めるが、書く際にtail latencyに引っ張られる
RAID5,6はリードモディファイライトとチェックサム計算のために書き込みパフォーマンスが落ちる
RAID5のようにデータがチェックサムを含むストライプとして格納されている場合、チェックサムの読み書きと計算の分だけコストがかかる
ストライプサイズが固定なので、少量の読み書きの場合オーバヘッドがある
RAID5を実装するコントローラはライトバックキャッシュが使える
高度なディスクコントローラカードは色々追加機能があるのでベンダのドキュメントを読んでおくといい
パトロールリード
数日ごとに全てのディスクブロックを読み出しチェックサムを確認する
システムワークロードに競合しないようにリードのリソースは調整される
キャッシュフラッシュのインターバル
ストレージアレイ
多数のディスクをシステムに接続するためのハードウェア
GB単位の大きなキャッシュと、それをライトバックとして使用するためのバッテリが搭載されている
バッテリの故障を検知するとライトスルーモードに切り替わるらしい
コントローラ-トランスポート間で冗長化が可能、デュアル接続できる
NAS
ネットワークの構成までパフォーマンスの分析対象に入ってくる
ブロックデバイスインターフェース
Unixの初期にブロック(512B)単位でストレージデバイスにアクセスするために作られた
Linuxではこの領域に機能を追加しブロックレイヤを作っている
1. ブロックデバイスインターフェース
2. 仮想ブロックドライバ
3. エレベータレイヤ(IOスケジューラ)
4. 物理ブロックドライバ
エレベータレイヤでのスケジューラポリシーには次のようなものがある
Noop
なにもしない
Deadline
レイテンシの読み書き有効期限を設定する
deadlineスケジューラは読み出しFIFO、書き込みFIFO、ソート済みキューの3つの独立したキューを使って、エレベータシーキングにおける問題を部分的に改善する
実践的にはこれがベターらしいよ
Anticipatory
IOパフォーマンスを予想するヒューリスティックが加わったdeadlineの拡張
全体のスループットが上がっている
CFQ
完全に公平なスケジューラがCPUのために作られたので、それをディスクのキューイングスケジューラに応用したもの
ionice(1)コマンドでユーザプロセスに優先度やクラスを設定できるようにする
Documentation/block/cfq-iosched.txt参照
メソドロジ - 分析とチューニングのための
USEメソッド
以下の三つをディスクデバイスとディスクコントローラについてチェックする
ディスクデバイス
1. 使用率 - デバイスがビジーだった時間
仮想ディスクの場合は実際の使用率と一致しない場合があり得るので注意
2. 飽和 - IOがキューで待機している度合
3. エラー - デバイスのエラー
ディスクはエラーに耐性があるため見過ごしやすいが、速度低下の原因になる
OSの機能以外に、S.M.A.R.T.みたいなハードウェアの機能もある
ディスクコントローラ
1. 使用率 - スループットと稼働率について、現在の値と最大値を比較する
2. 飽和 - コントローラの飽和によってIO待ちが発生している度合
3. エラー - コントローラのエラー
一般にディスクを動かすのに十分な能力があるはずなのであまりボトルネックにならない
どんなワークロードでもディスクのスループットが一定量を超えない場合、コントローラやトランスポートが問題を起こしていることがある
パフォーマンスモニタリング
2秒以上ディスクの使用率が100%なら問題が起きている可能性が高い
使用率が60%を超えただけでもキューイングが増えパフォーマンスが低下する場合がある
確信が持てない場合良いことがわかっているワークロードと悪いことが分かっているワークロードでマイクロベンチマーキングを実施
ディスクごとに解析すること、一秒あたりの平均としてモニタリングしたうえで、最大値や標準偏差が得られるとよい
負荷的に厳しいかもしれないが、ヒストグラムが手に入ればなおよい
リソースコントロールが掛かっている場合調査が必要
ワークロードの把握
基本
IOの頻度
IOスループット
IOサイズ
ランダムorシーケンシャル
読み書きの比率
高度なワークロード
システム全体のスループットと、ディスク、コントローラ毎のスループット
つまりどのレイヤでの律速か
どのアプリケーションやユーザがディスクを使っているか
どのファイルシステム、ファイルがアクセスされているか
エラーが起きているか、それは要求が無効なものだったのか、あるいはディスクから発行されたものか
利用可能なディスクの間でのIOのバランスはどうか
個々のトランスポートバスごとのIOPS、スループット
データ転送以外のディスクコマンドではどのようなものが発行されている
ディスクIOはなぜ発行されているか
カーネルレベルコールパスはどうなっているか
ディスクIOのうちにどれくらいがアプリケーションに同期的か
IO到着時刻の分布はどうか
パフォーマンス特性の把握
個々のディスクはどれくらいビジーか(使用率)
個々のディスクはどれくらい飽和しているか(キューイングの度合い)
平均サービス時間い、IO待ち時間はどれくらいか
レイテンシの高いIO外れ値はあるか
レイテンシの完全な分布はどうなっているか
IOスロットリングなどのシステムリソースコントロールがアクティブになっているか
データ転送以外のディスクコマンドのレイテンシはどうなっているか
静的パフォーマンスチューニング
IOレイテンシを解析する前に構成がおかしくないか調べるのは大事
特にRAIDのストライプ幅がIOサイズにあってないとか
デバイスドライバやファームウェアにはパフォーマンスに関わるバグが含まれている場合がある
ディスクやコントローラの構成でキャッシュの位置が違ったり
スタックレイテンシの分析
アプリからディスクに至る各スタックでレイテンシを分析することで問題となるワークロードが真に把握できる
上位でのレイテンシが変わらないままなら原因は下位にある
下位でレイテンシが減らないようなら上位(ファイルシステム、アプリでのロックやキューイングなど)にある
スケーリング
1. システムが既にワークロードを持っている場合、現在のディスクスループットとIOPSでユーザ人口を表現し、目標とする人口に併せこれをスケーリングする
同時にキャッシュがスケーリングされないと、ユーザ辺りのキャッシュヒットが減ってディスクIOが増えるので予測には注意
2. ワークロードをサポートするためのディスク数を計算する
RAID構成を考慮すること
使用率は50%程度で計算すること
ディスクのスループットやIOPSは理論値だと成立しない
前述のとおり60%程度からキューイングによるパフォーマンス問題が起きる
4. 同様にコントローラの数も計算する
5. トランスポートの限界を超えてないことを確認する
6. ディスクIO辺りのCPUサイクルと必要なCPUの数を計算する
ツール
iostat
-xkdzt -p ALL 1が便利、パーティション単位でiopsなども見れる
sarは -d だけで大体iostatだが、読み書きがセクター単位なのが
pidstat -d はプロセス単位で見れるけど、パラメータが粗い
実験
hdparm使いつつ、iostatたててダブルチェックすること
ファイルシステムからのテストツールの方が多いので、それとファイルシステム、ディスクレイヤの計測ツールを組み合わせるのもあり
チューニング
ionice, cgroup, blkio
チューニングできるパラメータ /sys/block/sda/queue/scheduler
ベンダー提供のディスク、コントローラの管理コマンド