NFS Azure ファイル共有のパフォーマンスを向上させる

適用対象: ✔️ NFS ファイル共有

この記事では、ネットワークファイルシステム(NFS)Azureファイル共有のパフォーマンスを向上させるさまざまな方法を紹介します。 トピックには、Linux read_ahead_kb カーネルパラメータの設定による順次読み取りスループットの向上、 nconnect マウントオプションを使ってクライアントマシン数を減らしてスループットを拡大すること、ストレージアカウントをクライアントと同じ可用性ゾーンに配置してレイテンシを減らすことなどが含まれます。

先行読み取りサイズを増やして読み取りスループットを向上させる

Linux の read_ahead_kb カーネル パラメーターは、シーケンシャル読み取り操作中に "先行読み取り" またはプリフェッチする必要があるデータの量を表します。 Linux カーネル バージョン 5.4 より前では、先行読み取り値が、マウントされたファイル システムの rsize の 15 倍 (読み取りバッファー サイズのクライアント側マウント オプション) に相当するように設定されます。 これにより、先行読み取り値が十分に高く設定され、ほとんどの場合にクライアントのシーケンシャル読み取りスループットが向上します。

ただし、Linux カーネル バージョン 5.4 以降の Linux NFS クライアントでは、既定の read_ahead_kb 値である 128 KiB を使います。 この小さな値が大きなファイルの読み取りスループットを減少させる可能性があります。 ユーザーが、リードアヘッド値が高いLinuxリリースからデフォルト128 KiBのリリースにアップグレードすると、連続読み取り性能が低下する可能性があります。

Linuxカーネル5.4以降では、パフォーマンス向上のために read_ahead_kb を15 MiBに一貫して設定していました。

この値を変更するには、Linux カーネル デバイス マネージャーである udev にルールを追加して、先行読み取りサイズを設定します。 次の手順に従います。

  1. テキスト エディターで、次のテキストを入力し、保存して、/etc/udev/rules.d/99-nfs.rules ファイルを作成します。

    SUBSYSTEM=="bdi" \
    , ACTION=="add" \
    , PROGRAM="/usr/bin/awk -v bdi=$kernel 'BEGIN{ret=1} {if ($4 == bdi) {ret=0}} END{exit ret}' /proc/fs/nfsfs/volumes" \
    , ATTR{read_ahead_kb}="15360"
    
  2. コンソールで、udevadm コマンドをスーパーユーザーとして実行し、ルール ファイルとその他のデータベースを再読み込みして、udev ルールを適用します。 このコマンドは一度だけ実行すれば、udevが新しいファイルを認識できるようにできます。

    sudo udevadm control --reload
    

NFS nconnect(NFS nconnect)

NFS nconnectは、クライアント側のマウントオプションで、クライアントとNFSファイルシェア間で複数のTCP接続を作成するために使います。 特に、単一のTCP接続がボトルネックになる大規模なワークロードに特に役立ちます。

nconnectの利点

nconnect を使用すると、少数のクライアント マシンを使用して大規模なパフォーマンスを向上させ、総保有コスト (TCO) を削減できます。 nconnect 機能は、1 つまたは複数の NIC で複数の TCP チャネルを使用し、単一または複数のクライアントを使用することでパフォーマンスを向上させます。 nconnectがなければ、最大SSDファイルシェアプロビジョニングサイズの帯域幅スケール制限(10 GiB/sec)を達成するには、約20台のクライアントマシンが必要です。 nconnect を使用すると、6 ~ 7 個のクライアントのみを使用してこれらの制限を実現でき、コンピューティング コストを 70% 近く削減しながら、1 秒あたりの I/O 操作 (IOPS) とスループットを大幅に向上させることができます。 次の表を参照してください。

メトリック (操作) I/O サイズ パフォーマンス改善
IOPS (書き込み) 64 KiB、1,024 KiB 3x
IOPS (読み取り) すべての I/O サイズ 2 - 4 倍
スループット (書き込み) 64 KiB、1,024 KiB 3x
スループット (読み取り) すべての I/O サイズ 2 - 4 倍

nconnectの前提条件

  • 最新の Linux ディストリビューションでは、nconnect が完全にサポートされています。 古い Linux ディストリビューションの場合は、Linux カーネルのバージョンが 5.3 以降であることを確認してください。
  • マウントごとの構成は、プライベート エンドポイント経由でストレージ アカウントごとに 1 つのファイル共有が使用される場合にのみサポートされます。

パフォーマンスへの影響

以下のパフォーマンス結果は、Linuxクライアント上で大規模にNFS Azureファイル共有を用いてnconnectマウントオプションを用いて測定されました。 これらの結果がどのように達成されたかについては、 パフォーマンステスト構成を参照してください。

NFS Azure ファイル共有で nconnect を使用するときの IOPS の平均改善を示すスクリーンショット。

NFS Azure ファイル共有で nconnect を使用するときのスループットの平均改善を示すスクリーンショット。

NCONNECTのおすすめ

nconnect から最適な結果を得るには、これらの推奨事項に従います。

nconnect=4 を設定します

Azure Filesはnconnectを最大設定16まで設定できますが、マウントオプションはnconnect=4の最適設定で設定してください。 現時点では、nconnect の Azure Files 実装では、4 つのチャネルを超える利益はありません。 実際、1 つのクライアントから 1 つの Azure ファイル共有に対してチャネルが 4 つを超えると、TCP ネットワークの飽和が原因でパフォーマンスに悪影響を及ぼす可能性があります。

仮想マシンのサイズを慎重に設定する

ワークロードの要件に応じて、 予想されるネットワーク帯域幅によって制限されないように、クライアント仮想マシン (VM) のサイズを正しく設定することが重要です。 予想されるネットワーク スループットを実現するために複数の NIC が必要になることはありません。 Azure Files で汎用 VM を使用するのが一般的ですが、ワークロードのニーズとリージョンの可用性に応じて、さまざまな種類の VM を使用できます。 詳しくは、Azure VM セレクターに関する記事をご覧ください。

キューの深さを 64 以下に保つ

キューの深さは、ストレージ リソースがサービスを提供できる未処理の I/O 要求の数です。 それ以上のパフォーマンス向上は見込まれないため、最適なキューの深さを 64 を超えて設定することはお勧めしません。 詳細については、「キューの深さ」を参照してください。

マウントごとの構成

もしワークロードが1つのクライアントから異なるnconnect設定を持つ複数のストレージアカウントで複数の共有をマウントする必要がある場合、パブリックエンドポイント上でマウントしても設定が永続する保証はありません。 マウントごとの構成は、シナリオ1で説明されているように、プライベートエンドポイント上でストレージアカウントごとに1つのAzureファイルシェアのみをサポートします。

シナリオ 1: 複数のストレージ アカウントを持つプライベート エンドポイント経由でのマウントごとの構成 (サポートされています)

  • StorageAccount.file.core.windows.net = 10.10.10.10
  • StorageAccount2.file.core.windows.net = 10.10.10.11
    • Mount StorageAccount.file.core.windows.net:/StorageAccount/FileShare1 nconnect=4
    • Mount StorageAccount2.file.core.windows.net:/StorageAccount2/FileShare1

シナリオ 2: パブリック エンドポイント上でのマウント構成ごと (サポートされていません)

  • StorageAccount.file.core.windows.net = 52.239.238.8
  • StorageAccount2.file.core.windows.net = 52.239.238.7
    • Mount StorageAccount.file.core.windows.net:/StorageAccount/FileShare1 nconnect=4
    • Mount StorageAccount.file.core.windows.net:/StorageAccount/FileShare2
    • Mount StorageAccount2.file.core.windows.net:/StorageAccount2/FileShare1

たとえストレージアカウントが別のIPアドレスに解決しても、パブリックエンドポイントは静的アドレスではないため、そのアドレスが永続する保証はありません。

シナリオ 3: 1 つのストレージ アカウントに複数の共有がある環境で、マウント構成ごとの設定をプライベート エンドポイントを通じて行う場合 (サポートされていません)

  • StorageAccount.file.core.windows.net = 10.10.10.10
    • Mount StorageAccount.file.core.windows.net:/StorageAccount/FileShare1 nconnect=4
    • Mount StorageAccount.file.core.windows.net:/StorageAccount/FileShare2
    • Mount StorageAccount.file.core.windows.net:/StorageAccount/FileShare3

パフォーマンス テストの構成

この記事で述べた結果を達成し測定するために、以下のリソースとベンチマークツールをご利用ください。

  • 単一クライアント: 単一 NIC を使用した Azure VM (DSv4-Series)
  • OS: Linux(Ubuntu 20.04)
  • NFS ストレージ: SSD ファイル共有 (30 TiB をプロビジョニング済み、nconnect=4 の設定)
[サイズ] vCPU [メモリ] 一時ストレージ (SSD) 最大データ ディスク数 最大 NIC 数 必要なネットワーク帯域幅
Standard_D16_v4 16 64ギベット リモート ストレージのみ 32 8 12,500 Mbps

ベンチマーク ツールとテスト

これらのテストは、ベンチマークやストレス・ハードウェア検証の両方に使われる無料のオープンソースディスクI/OツールであるFlexible I/O Tester(FIO)を使用します。 FIOをインストールするには、 FIO READMEファイルの バイナリパッケージセクションをご確認いただき、選択したプラットフォームの指示に従ってください。

これらのテストはランダムな I/O アクセス パターンに焦点を当てていますが、シーケンシャル I/O を使用するときも同様の結果が得られます。

高い IOPS: 100% 読み取り

I/O サイズ 4k - ランダム読み取り - キューの深さ 64

fio --ioengine=libaio --direct=1 --nrfiles=4 --numjobs=1 --runtime=1800 --time_based --bs=4k --iodepth=64 --filesize=4G --rw=randread --group_reporting --ramp_time=300

I/O サイズ 8k - ランダム読み取り - キューの深さ 64

fio --ioengine=libaio --direct=1 --nrfiles=4 --numjobs=1 --runtime=1800 --time_based --bs=8k --iodepth=64 --filesize=4G --rw=randread --group_reporting --ramp_time=300

高スループット: 100% 読み取り

64 KiB I/O サイズ - ランダム読み取り - 64 キューの深さ

fio --ioengine=libaio --direct=1 --nrfiles=4 --numjobs=1 --runtime=1800 --time_based --bs=64k --iodepth=64 --filesize=4G --rw=randread --group_reporting --ramp_time=300

I/O サイズ 1,024 KiB - 100% ランダム読み取り - キューの深さ 64

fio --ioengine=libaio --direct=1 --nrfiles=4 --numjobs=1 --runtime=1800 --time_based --bs=1024k --iodepth=64 --filesize=4G --rw=randread --group_reporting --ramp_time=300

高い IOPS: 100% 書き込み

I/O サイズ 4 KiB - 100% ランダム書き込み - キューの深さ 64

fio --ioengine=libaio --direct=1 --nrfiles=4 --numjobs=1 --runtime=1800 --time_based --bs=4k --iodepth=64 --filesize=4G --rw=randwrite --group_reporting --ramp_time=300

I/O サイズ 8 KiB - 100% ランダム書き込み - キューの深さ 64

fio --ioengine=libaio --direct=1 --nrfiles=4 --numjobs=1 --runtime=1800 --time_based --bs=8k --iodepth=64 --filesize=4G --rw=randwrite --group_reporting --ramp_time=300

高スループット: 100% 書き込み

I/O サイズ 64 KiB - 100% ランダム書き込み - キューの深さ 64

fio --ioengine=libaio --direct=1 --nrfiles=4 --numjobs=1 --runtime=1800 --time_based --bs=64k --iodepth=64 --filesize=4G --rw=randwrite --group_reporting --ramp_time=300

I/O サイズ 1024 KiB - 100% ランダム書き込み - キューの深さ 64

fio --ioengine=libaio --direct=1 --nrfiles=4 --numjobs=1 --runtime=1800 --time_based --bs=1024k --iodepth=64 --filesize=4G --rw=randwrite --group_reporting --ramp_time=300

nconnect のパフォーマンスに関する考慮事項

nconnect マウント オプションを使用する場合は、次の特性を持つワークロードを厳密に評価する必要があります。

  • シングル スレッドであるか、低いキューの深さ (16 未満) を使用する、待機時間の影響を受けやすい書き込みワークロード
  • シングル スレッドであるか、小さい I/O サイズと組み合わせて低いキューの深さを使用する、待機時間の影響を受けやすい読み取りワークロード

すべてのワークロードが大規模なIOPSやスループット性能を必要とするわけではありません。 小規模な作業量には nconnect があまり役立たないかもしれません。 次の表を使って、nconnect が自分のワークロードに役立つかどうかを判断します。 緑色で強調表示されているシナリオは推奨されていますが、赤で強調表示されているシナリオは推奨されていません。 黄色で強調表示されているのは中立的なシナリオです。

nconnect が推奨される場合を示すために、さまざまな読み取りと書き込みの I/O シナリオと、対応する待機時間を示したスクリーンショット。

ゾーン配置を使用する

Microsoft.Storage リソース プロバイダーで作成されたクラシック ファイル共有の場合は、 ゾーン配置 を使用して、ストレージ アカウントが存在する特定の可用性ゾーンを選択することをお勧めします。 これにより、VM をストレージと同じ可用性ゾーンに配置できるため、待機時間を最大 30% 短縮できます。 現在、この機能は、 サポートされているリージョンでローカル冗長ストレージ (LRS) を使用している SSD ストレージ アカウントでのみ使用できます。

関連項目