Red Hat Training

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

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

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