「ストレージ IO パス」特別トピック: ブロック デバイス層マルチキュー blk-mq アーキテクチャ

あなたがレストランのシェフで、さまざまな料理を準備する必要があり、それぞれの料理に必要な材料と調理時間が異なると想像してください。全ての料理を順番どおりに作ってしまうと、作業効率が非常に悪くなってしまいます。効率を向上させるために何をしますか?

Linux アーキテクチャでは、マルチキュー ブロック レイヤーはスマート レストラン マネージャーのようなもので、シェフは前の注文が完了するのを待たずに複数の注文を同時に処理できます。このメカニズムは、Linux カーネルに複数の I/O スケジューリング キューを実装し、各キューが特定の種類の I/O 操作を処理します。このようにして、プロセスが I/O リクエストを発行すると、マルチキュー ブロック層はそのリクエストを対応するキューに割り当てることができ、I/O 操作を並行して実行できるようになり、システムのパフォーマンスが大幅に向上します。

Linux では、blk-mq アーキテクチャはブロック層を改良したもので、複数の I/O スケジューリング キューをサポートすることでシステムの同時実行性と応答性が向上します。マルチキュー ブロック層はカーネル バージョン 3.14 の後に導入され、後続のバージョンではさらに開発および改善されました。

blk-mq アーキテクチャでは、各ブロック デバイスは複数の I/O スケジューリング キューを維持し、各キューは特定の優先順位に対応します。システムが I/O リクエストを受信すると、そのリクエストはリクエストの優先度に従って対応するキューに割り当てられます。各キューは、先入れ先出し (FIFO)、最短ジョブ優先 (SFS) などの独自の I/O スケジューリング戦略を採用します。このメカニズムにより、さまざまな優先順位の I/O リクエストをより適切に処理し、応答できるようになります。

以下は、マルチキュー ブロック レイヤーの基本原理を示す簡単なサンプル コードです。

#include <linux/blkdev.h>  
  
/* 初始化块设备 */  
struct gendisk *disk;  
  
/* 初始化块设备分区 */  
struct hd_struct *part;  
  
/* 初始化块设备请求队列 */  
struct request_queue *queue;  
  
/* 初始化块设备I/O调度器 */  
struct elevator_type *elevator;  
  
/* 初始化I/O调度参数 */  
elevator_param_t elevator_params[];  
  
/* 初始化I/O调度队列 */  
struct blk_queue_layer queue_layer;  
  
/* 分配I/O调度队列 */  
queue_init_queue(&queue_layer, disk, part, queue, elevator, elevator_params);

上記のコードでは、まずブロック デバイス、パーティション、リクエスト キュー、I/O スケジューラなどのコンポーネントを初期化します。次に、I/O スケジューリング キュー層を表す queue_init_queue 関数を呼び出して、blk_queue_layer 構造体を初期化します。この関数は、ブロック デバイス、パーティション、リクエスト キュー、I/O スケジューラ、I/O スケジューリング パラメータなどを含む複数のパラメータを受け入れます。関数内では、指定されたパラメーターに基づいて新しい I/O スケジューリング キューが作成され、対応するブロック デバイスの I/O スケジューリング キュー層に追加されます。

従来の Linux システムでは、ブロック デバイス層と IO スケジューラは主に HDD (ハードディスク ドライバー) 用に設計されていました。HDD デバイスのランダム IO パフォーマンスは非常に低く、スループットは数百 IOPS (IO 数/秒) 程度であり、遅延はミリ秒レベルであるため、当時の IO パフォーマンスのボトルネックはハードウェアではなくハードウェアでした。カーネル。しかし、高速SSD(Solid State Disk)の登場とその高性能化に伴い、数百万、場合によっては数千万IOPSのデータアクセスが主流となり、従来のブロックデバイス層ではそのような高い要件を満たすことができなくなりました。 IOPS 要求が徐々にシステム IO パフォーマンスのボトルネックになってきました。最新のストレージ デバイス (高速 SSD など) の高 IOPS および低遅延 IO 特性に適応するために、新しいブロック デバイス層フレームワーク Block multi-queue (blk-mq) が登場しました。

  • マルチキュー ブロック層は、ソフトウェア キューとハードウェア ディスパッチ キューの 2 つの層に分かれています。
  • ソフトウェア キューはコアごとにあり、キューの数はプロトコルに関連します。たとえば、NVMe プロトコルでは、最大 64K の IO SQ/CQ ペアを持つことができます。Software Queues レイヤーが行うことは、上の図に示すとおりです。
  • ハードウェア キューの数は、基礎となるデバイス ドライバーによって決まり、1 つ以上の場合があります。サポートされる最大数は通常、2K をサポートする MSI-X 割り込みの最大数と同じです。デバイス ドライバーは、map_queue を通じてソフトウェア キューとハードウェア キュー間のドッキング関係を維持します。
  • ハードウェア キューとソフトウェア キューの数は必ずしも等しいわけではなく、上図の 1:1 マッピングの状況が最も理想的な状況であることに注意してください。

実際のアプリケーションでは、blk-mq アーキテクチャによりシステムの同時実行性と応答性が大幅に向上します。複数の I/O スケジューリング キューをサポートすることで、さまざまな優先順位の I/O リクエストをより適切に処理でき、さまざまな I/O 負荷条件やシステム構成に応じて調整および最適化して、より優れたパフォーマンスと応答性を得ることができます。

blk-mq のマッピング関係は、ソフトウェア キューをハードウェア ディスパッチ キューにマッピングするメカニズムを指します。このマッピング関係は、固定されたマッピング関係を通じて実現されます。

blk-mq アーキテクチャでは、各ハードウェア キューは 1 つ以上のソフトウェア キューに対応しており、この対応関係はドライバーの初期化時の構成によって設定されます。通常、各ハードウェア キューは複数のソフトウェア キューに対応しており、このマッピング関係により、リクエスト キューのロック競合やリモート メモリ アクセスの問題が回避され、ブロック層の IOPS スループットが向上します。

ユースケース空間がブロック デバイスへの IO 操作を実行すると、BLK-MQ はこれらの IO リクエストを保存および管理し、ユーザー空間、ファイル システム、ブロック デバイス ドライバーの間のミドルウェアの役割を果たします。BLK-MQ は、ソフトウェア ステージ キューとハードウェア割り当てキューを通じてリクエストのスケジューリングと管理を実装します。リクエストがブロック デバイス層に到達すると、最短パスが試行され、ハードウェア キューに直接送信されます。

ただし、これが起こらない状況が 2 つあります。

まず、IO スケジューラがある場合、これは実行できません。

次に、リクエストをマージしたい場合、それはできません。

どちらの場合も、リクエストはソフトウェア キューに送信されます。ソフトウェア キュー内のリクエストは処理された後、ハードウェア キューに配置され、ハードウェアはハードウェアに直接アクセスしてこれらのリクエストを処理します。

blk-mq のマッピング関係は、blk-sq アーキテクチャにおけるリクエスト キューのロック競合とリモート メモリ アクセスの問題を解決し、ブロック層の IOPS スループットを大幅に向上させます。同時に、ソフトウェア キューをハードウェア ディスパッチ キューにマッピングすることで、さまざまな優先順位の I/O リクエストをより適切に処理し、さまざまな I/O 負荷条件やシステム構成に応じて調整および最適化し、より優れたパフォーマンスと応答性を得ることができます。

おすすめ

転載: blog.csdn.net/zhuzongpeng/article/details/132678480