Red Hat Training

A Red Hat training course is available for Red Hat Enterprise Linux

30.6. VDO のチューニング

30.6.1. VDO チューニングの概要

データベースまたはその他の複雑なソフトウェアを調整するため、VDO を調整するには、さまざまなシステム制約と実験が必要です。VDO のチューニングに使用できる主な制御は、異なるタイプの作業、そのスレッドの CPU アフィニティー設定、キャッシュ設定に割り当てられているスレッドの数です。

30.6.2. VDO アーキテクチャーの背景情報

VDO カーネルドライバーは、複数の同時 I/O リクエスト全体で処理コストを収益化することで、パフォーマンスを向上させるためにマルチスレッドです。開始から終了に I/O 要求を送信する代わりに、異なるステージを 1 つ以上のスレッドまたはスレッドのグループに委譲し、メッセージが I/O 要求として渡されるとパイプラインを通過します。これにより、1 つのスレッドが、ロックせずにグローバルデータ構造へのすべてのアクセスをシリアライズし、I/O 操作が処理されるたびにロックを解除できます。VDO ドライバーが適切に調整されると、スレッドが要求された処理ステージを完了するたびに、通常、同じ処理のために別のリクエストはキューに置かれます。これらのスレッドをビジー状態に維持すると、コンテキストスイッチおよびスケジューリングのオーバーヘッドが削減され、パフォーマンスが向上します。個別スレッドは、基盤となるストレージシステムへの I/O 操作を、UDS へキューに入れるなど、ブロックできるオペレーティングシステムの各部分にも使用されます。
VDO が使用するさまざまなワーカースレッドタイプは次のとおりです。
論理ゾーンスレッド
文字列 kvdo:logQ などのプロセス名を持つ論理スレッドは、VDO デバイスのユーザーに提示された論理ブロック番号(LBN)と、基になるストレージシステムの物理ブロック番号(PBN)とのマッピングを維持します。また、同じブロックに書き込みを試行する 2 つの I/O 操作が同時に処理されないようにロックも実装します。論理ゾーンスレッドは、読み取りおよび書き込みの両方の操作時にアクティブになります。
LBNs はチャンクに分割 (ブロックマップページにはビット 3 MB の LBN が含まれます)、これらのチャンクはスレッド間で分割されるゾーンにグループ化されます
処理は、スレッド全体にも均等に分散する必要がありますが、未発のアクセスパターンによっては、1 つのスレッドまたは別のスレッドで作業を集中することがある場合があります。たとえば、特定のブロックマップページ内で LBN に頻繁にアクセスすると、論理スレッドのいずれかがそれらのすべての操作を処理します。
--vdoLogicalThreads=thread count コマンドのオプションを使用して制御できます。
物理ゾーンスレッド
物理または kvdo:physQ、スレッドはデータブロックの割り当てを管理し、参照数を維持します。書き込み操作中にアクティブです。
LBN と同様に、PBN はスラブと呼ばれるチャンクに分割されます。これはさらにゾーンに分割され、処理の負荷を分散するワーカースレッドに割り当てられます。
--vdoPhysicalThreads=thread count コマンドのオプションを使用して制御できます。
I/O 提出スレッド
kvdo:bioQ スレッドは、VDO からストレージシステムにブロック I/O(bio)操作を送信します。その他の VDO スレッドによりキューに格納された I/O 要求を取り、それらを基礎となるデバイスドライバーに渡します。このスレッドは、デバイスに関連付けられたデータ構造と通信および更新を行うか、デバイスドライバーのカーネルスレッドを処理する要求を設定できます。基となるデバイスの要求キューが満杯であれば I/O 要求を送信するため、処理遅延を回避するために、この作業は専用のスレッドにより行われます。
ps または top ユーティリティーによりスレッドが D に頻繁に表示されると、VDO はストレージシステムを I/O 要求でビジー状態を維持するのが頻繁に行われます。通常、ストレージシステムは、SSD によっては要求処理がパイプラインされる可能性があるため、複数の要求を並行してサービスできる場合に適しています。この期間にスレッド CPU 使用率が非常に低い場合、I/O 提出スレッドの数を減らすことが可能です。
CPU 使用率とメモリーの競合は、VDO の下にあるデバイスドライバーによって異なります。I/O 要求ごとの CPU 使用率が増えると、より多くのスレッドが追加され、それらのデバイスドライバーで CPU、メモリー、またはロックの競合を確認します。
I/O --vdoBioThreads=thread count コマンドのオプションを使用して制御できます。
CPU プロセススレッド
kvdo:cpuQ スレッドは、ハッシュ値の計算や、他のスレッドタイプに関連するデータ構造への排他的アクセスを必要とするデータブロックの圧縮など、CPU 集約型の作業を行うため存在します。
CPU --vdoCpuThreads=thread count コマンドのオプションを使用して制御できます。
I/O 確認スレッド
kvdo:ackQ スレッドは、上位 VDO(カーネルページキャッシュや直接 I/O を実行するアプリケーションプログラムスレッド)にコールバックを発行し、I/O 要求の完了を報告します。CPU 時間の要件とメモリーの競合は、この他のカーネルレベルのコードに依存します。
--vdoAckThreads=thread count コマンドのオプションを使用して制御できます。
スケーリングできない VDO カーネルスレッド:
重複排除スレッド
kvdo:dedupeQ スレッドは、キューに格納された I/O 要求を取り、UDS にお問い合わせください。ソケットバッファーは、サーバーが要求をすぐに処理できない場合や、カーネルメモリーが他のシステムアクティビティーによって制限されている場合は、この作業は別のスレッドにより実行されるため、スレッドをブロックした場合に、その他の VDO 処理が継続できます。また、長い遅延後に I/O 要求をスキップするタイムアウトメカニズムもあります(秒単位)。
ジャーナルスレッド
kvdo:journalQ スレッドはリカバリージャーナルを更新し、ジャーナルが書き込み用にスケジュールします。VDO デバイスが 1 つのジャーナルのみを使用するため、この作業はスレッド全体で分割できません。
Packer スレッド
圧縮が有効な場合に書き込みパス内で有効な kvdo:packerQ スレッドは、kvdo:cpuQ スレッドによって圧縮されるデータブロックを収集し、領域が最小限に抑えられていました。パンパッカーデータ構造が 1 つあるため、VDO デバイスごとに 1 つのパンパースレッドがあります。

30.6.3. チューニングする値

30.6.3.1. CPU/メモリー

30.6.3.1.1. 論理、物理、CPU、承認スレッドカウント
論理、物理、CPU、および I/O 確認作業は、複数のスレッドに分散できます。VDO デバイスが再起動されると、初期設定時または後で指定できる回数になります。
1 つのコア(または 1 つのスレッド)で、特定の時間内に作業量を手に入れることができます。スレッド 1 つですべてのデータブロックハッシュ値を計算すると、1 秒あたり処理できるデータブロックの数にハード制限が課されます。複数のスレッド(およびコア)全体で作業を分割すると、ボトルネックが関係します。
スレッドやコアが 100% 使用率に比べると、より多くの作業項目は、処理用に最大 10 個となります。これにより、CPU のアイドルサイクルが少なくなる可能性がありますが、個々の I/O 要求のキューイング遅延とレイテンシーは通常増加します。一部のキューディネーションモデルによると、70% または 80% を超える使用状況レベルでは、通常の処理時間よりも長い時間を過剰に遅延する可能性があります。そのため、スレッドまたはコアが常にビジー状態にない場合でも、スレッドやコアに 50% 以上の使用率の作業をさらに分散すると便利です。
逆の場合、スレッドや CPU が非常に負荷がかかっている場合(多くの場合は、sleep)は、行わないように作業を行うと、余分なコストが発生する可能性が高くなります。(別のスレッドがウェイクアップしようとするスレッドは、スケジューラーのデータ構造上でグローバルロックを取得し、別のコアに作業を転送するためにプロセッサー割り込みを送信する可能性があります)。VDO スレッドを実行するようにコアが多く設定すると、一部のデータの一部がスレッド間で移動するか、コア間でスレッドが移動してもキャッシュされる可能性が低くなります。そのため、ワークの分散によってパフォーマンスが低下する可能性があります。
I/O 要求ごとの論理、物理、および CPU スレッドが実行する作業は、ワークロードのタイプによって異なります。そのため、システムは、サービスすることが想定される異なるタイプのワークロードでテストする必要があります。
重複排除が正常に関係する sync モードでの書き込み操作により、一部の CPU サイクル(以前保存されたデータブロックの読み取り)、一部の CPU サイクル(一致するデータブロック)、およびジャーナルの更新(LBN を以前に保存されたデータブロックにマッピング)を新しいデータに書き込みます。重複が async モードで検出されると、上記の読み取りおよび書き込み操作のコストでデータの書き込み操作が回避されます。重複が検出されても、書き込みごとに 1 つのジャーナル更新のみが実行される可能性があります。
圧縮が有効にされている場合、圧縮可能なデータの読み取りおよび書き込みには、CPU スレッドによるより多くの処理が必要になります。
すべてのゼロバイト (ゼロブロック)を含むブロックは、一般的に発生するため、特別に処理されます。ブロックマップでこのようなデータを表すために特別なエントリーが使用され、ゼロブロックはストレージデバイスに書き込まれるか、または読み取りされません。そのため、ゼロ以外のブロックの書き込みまたは読み取りを行うテストでは、誤解を招く結果が発生する可能性があります。ゼロブロックまたは初期化されていないブロック(VDO デバイスの作成後に書き込まれたもの)に書き込むテストの場合も同様です。これは、物理スレッドによって実行された参照カウントの更新は 0 あるいは未初期化ブロックには必要ないためです。
I/O 操作の承認は、1 つのコールバックごとに発行されるため、作業のタイプによって大幅に影響のない唯一のタスクか、操作されるデータのみが I/O 操作ごとに発行されます。
30.6.3.1.2. CPU のアフィニティーおよび NUMA
NUMA ノード境界全体でメモリーにアクセスすると、ローカルノード上のメモリーへのアクセスよりも長い時間がかかります。Intel プロセッサーがノード上のコア間で last-level キャッシュを共有する場合、ノード間のキャッシュ競合は、ノード内のキャッシュ競合よりも大きな問題となります。
top などのツールは、停止したワークやサイクル間の CPU サイクルを区別できません。これらのツールはキャッシュ競合を解釈し、メモリーのアクセスを実際の機能として解釈します。その結果、スレッドをノード間を移動すると、1 秒あたりに実行する操作の数を増やす間に、スレッドの正当な CPU 使用率が削減される可能性があります。
VDO のカーネルスレッドの多くは、1 つのスレッドによってアクセスされるデータ構造を維持しますが、I/O 要求に関するメッセージが頻繁に交換されます。VDO スレッドが複数のノードで実行される場合、またはスレッドがスケジューラーによってあるノードから別のノードに再割り当てされた場合、競合が発生する場合があります。VDO 関連のその他の作業(VDO への I/O 提出や、ストレージデバイスの割り込み処理など)を VDO スレッドと同じノードで実行できる場合は、競合をさらに削減できます。あるノードで VDO 関連の作業をすべて実行するサイクルが十分でない場合は、他のノードに移動するスレッドを選択する場合にメモリー競合を考慮する必要があります。
実用的な場合は、taskset ユーティリティーを使用して 1 つのノードで VDO スレッドを収集します。その他の VDO 関連の作業を同じノードで実行することもできます。これにより競合の可能性が低下する可能性があります。このような場合には、あるノードに処理の要求に対応するための CPU 電源がない場合には、他のノードに移動するスレッドを選択する際にメモリー競合を考慮する必要があります。たとえば、ストレージデバイスのドライバーのデータ構造が多数ある場合は、デバイスの割り込み処理と VDO の I/O 提出の両方を他のノードに移動するのに役立ちます(デバイスのドライバーコードを呼び出す bio スレッド)。直接 I/O の承認(ack スレッド)および高レベル I/O サブ処理スレッド(直接 I/O またはカーネルのページキャッシュフラッシュスレッドを実行するユーザーモードスレッド )のペアを維持することは良い方法です。
30.6.3.1.3. 周波数のスロットリング
電力消費が問題ではない場合は、/sys/devices/system/cpu/cpu*/cpufreq/scaling_governor ファイルに文字列パフォーマンスを書き込みます (存在する場合)。これらの sysfs ノードが存在しない場合、Linux またはシステムの BIOS が CPU 周波数管理を設定するための他のオプションを提供できます。
パフォーマンス測定は、タスクの切り替えやキャッシュ競合がなくても CPU が特定の作業を行うことが必要となるため、ワークロードに基づいて動的に頻繁に異なる CPU でさらに複雑になります。

30.6.3.2. キャッシュ

30.6.3.2.1. ブロックマップキャッシュ
VDO は、効率のために多くのブロックマップページをキャッシュします。キャッシュサイズはデフォルトで 128 MB --blockMapCacheSize=megabytes コマンドのオプションを使用して増やすことができます。キャッシュが大きいキャッシュを使用すると、ランダムアクセスのワークロードに大きな利点が発生することがあります。
30.6.3.2.2. キャッシュの読み取り
ストレージシステムから読み取られたデータブロックのキャッシュに 2 つ目のキャッシュを使用すると、VDO の重複排除アドバイスを確認できます。同様のデータブロックが短期間内に現れると、必要な I/O 操作の数を減らすことができます。
読み取りキャッシュは、圧縮したユーザーデータを含むストレージブロックも保持します。圧縮可能なブロックが複数期間内に書き込まれた場合、圧縮されるバージョンが同じストレージシステムブロック内に配置される可能性があります。同様に、短時間で読み取られる場合はキャッシュがストレージシステムから追加の読み取りを行う必要がない場合があります。
vdo --readCache={enabled | disabled} 。有効な場合、キャッシュの最小サイズ 8 MB --readCacheSize=megabytes 。読み取りキャッシュを管理すると、わずかなオーバーヘッドが発生するため、ストレージシステムが十分に高速になるとパフォーマンスが向上しない可能性があります。読み取りキャッシュはデフォルトで無効になっています。

30.6.3.3. ストレージシステム I/O

30.6.3.3.1. bio Threads
RAID 設定の汎用ハードドライブの場合、I/O 操作を送信するのに 1 つまたは 2 つの bio スレッドで十分です。ストレージデバイスドライバーに I/O 提出スレッドを非常に多くの作業に必要な場合(ドライバーのデータ構造やデバイスとの通信など)で、1 つまたは複数のスレッドがビジー型であり、ストレージデバイスがアイドル状態になることが多い場合は、bioio スレッド数を補正するために引き上げることができます。ただし、ドライバーの実装によっては、スレッド数が高すぎると、キャッシュまたはスピンロックの競合が発生する可能性があります。デバイスアクセスタイミングがすべての NUMA ノード全体で統一されていない場合は、ストレージデバイスコントローラーに対して「クローズ」のノードで bio スレッドを実行することが役に立つ場合があります。
30.6.3.3.2. IRQ 処理
デバイスドライバーが割り込みハンドラーで重要な作業を行い、スレッド化された IRQ ハンドラーを使用しない場合、スケジューラーが最適なパフォーマンスを提供しないことがあります。ハードウェア割り込みの確保に費やした CPU 時間は、一部の方法で通常の VDO(またはその他の)カーネルスレッド実行のように見えることがあります。たとえば、ハードウェアの IRQ 処理がコアサイクルで 30% を必要とする場合、同じコア上のビジーカーネルスレッドは残りの 70% のみを使用することができます。ただし、コアサイクルでこのスレッドに応じてキューに置かれますが、スレッドはキャッチされないので、スケジューラーはそのスレッドをビジーなコアに切り替える代わりに、そのコア上で impeded を実行するだけです。
このようなデバイスドライバーを多用 VDO ワークロードで使用すると、ハードウェア割り込みをサービスするのに多数のサイクルが必要になる場合があります (トップディスプレイのヘッダーの %hi インジケーター)。この場合は、特定のコアに IRQ 処理を割り当て、VDO カーネルスレッドの CPU アフィニティーを調整するのに役に立ちます。

30.6.3.4. Maximum Discard Sectors

VDO デバイスに対する DISCARD(TRIM)操作の最大許容サイズは、システムの使用に基づいて /sys/kvdo/max_discard_sectors で調整できます。デフォルトは 8 セクター(1 つの 4 KB ブロック)です。サイズが大きいサイズを指定できますが、VDO はループで処理しても、一度に 1 つのブロックが 1 つのブロックを処理し、1 つの破棄されたブロックのメタデータ更新がジャーナルに書き込まれ、次のブロックを起動する前にディスクにフラッシュされるようになります。
VDO ボリュームをローカルファイルシステムとして使用すると、Linux カーネルの汎用ブロックデバイスコードが複数の破棄要求に分割され、並行して送信されるため、小さな破棄サイズが、小さい破棄サイズが最適なものであることが分かりました。デバイスに I/O アクティビティーが低くなると、VDO は、大量の要求を同時に処理できます。
VDO デバイスを SCSI ターゲットとして使用する場合は、イニシエーターとターゲットソフトウェアにより、追加の要因が考慮されます。ターゲット SCSI ソフトウェアが SCST の場合、破棄の最大サイズを読み取り、イニシエーターにリレーします。(Red Hat は、LIO SCSI ターゲットコードとともに VDO 設定を調整しようとしていません。)
Linux SCSI イニシエーターコードでは一度に破棄操作しかできないため、最大サイズを超えるリクエストは複数の破棄に分割され、一度に 1 つずつはターゲットシステム(VDO)にそれぞれ分割されます。したがって、VDO 処理が連続で小さな破棄操作を複数処理することに加え、2 つのシステム間のラウンドトリップの通信時間は、追加のレイテンシーを追加します。
大きな最大破棄サイズを設定すると、この通信のオーバーヘッドを減らすことができますが、大きなリクエストは VDO 全体に渡され、一度に 4 KB ブロックが処理されます。ブロックごとの通信遅延はありませんが、大きなブロックの追加処理時間が長くなると、SCSI イニシエーターソフトウェアがタイムアウトする可能性があります。
SCSI ターゲットの使用には、通常の破棄時間をイニシエーターのタイムアウト値内にも良く維持しつつ、最大破棄サイズを中程度に設定することを推奨します。たとえば、数秒ごとに追加のラウンドトリップコストが、30 秒または 60 秒のタイムアウトが設定された SCSI イニシエーターが大幅に影響しません。

30.6.4. ボントリクの特定

VDO パフォーマンスに影響する主な要因や、最も影響を与えるものを特定できるツールが多数あります。
top または ps などのユーティリティーで表示される 70% を超えるスレッドまたは CPU 使用率は、1 つのスレッドまたは 1 つの CPU 上で集中していることを意味します。ただし、場合によっては、VDO スレッドが CPU で実行するようにスケジュールされているが、実際に発生しないのに発生しない場合もあります。このシナリオは、過剰なハードウェア割り込みハンドラーの処理、コアまたは NUMA ノード間のメモリー競合、またはスピンロックの競合により発生する可能性があります。
top ユーティリティーを使用してシステムのパフォーマンスを調べる場合、Red Hat は、全プロセススレッドを個別に表示してから 1 f j キーを入力し、Enter/Return キーの後に、個々の CPU コアに負荷を表示し、各プロセスまたはスレッドが最後に実行した CPU を特定します。この情報は、以下の洞察を提供します。
  • コアに %id (idle)および %wa (waiting-for-I/O)の値がある場合、何らかの種類の機能でビジー状態になります。
  • コアの %hi 値が非常に低い場合、コアは通常の処理を行います。これはカーネルスケジューラーによって負荷分散されています。コアをこのセットに追加すると、NUMA の競合が発生しない限り、負荷が削減される可能性があります。
  • コアの %hi がパーセントを超えており、1 つのスレッドのみがそのコアに割り当てられ、%id および % wa がゼロである場合、コアはオーバーコミットされ、スケジューラーはその状況に対応しません。この場合、別のコアにカーネルスレッドまたはデバイス割り込み処理を再割り当てする必要があります。
perf ユーティリティーは、多くの CPU のパフォーマンスカウンターを検証できます。Red Hat は、perf top サブコマンドを開始点として使用して、スレッドまたはプロセッサーが行う作業を調べることを提案します。たとえば、bioQ スレッドはスピンロックの取得を試みる多くのサイクルを費やしていると、VDO 以下のデバイスドライバーで競合が多くなり、bioQ スレッドの数を減らすと、状況を軽減できる可能性があります。CPU の使用率が高い(スピンロックの取得など)、たとえば bioQ スレッドおよびデバイス割り込みハンドラーが異なるノードで実行されている場合、NUMA ノード間の競合を示す可能性もあります。プロセッサーがサポートする場合は、stoped-cycles-backend、cache-misses 、node-load-misses などのカウンターが関心のある場合があります。
sar ユーティリティーは、複数のシステム統計に関する定期的なレポートを提供できます。sar -d 1 コマンドは、ブロックデバイス使用率レベル(1 秒あたりに 1 回以上 I/O 操作のある時間のパーセンテージ)とキューの長さ(I/O 要求の数)を報告します。ただし、すべてのブロックデバイスドライバーがそのような情報を報告できるわけではないので、有用性は使用中のデバイスドライバーに依存する場合があります

このページには機械翻訳が使用されている場合があります (詳細はこちら)。