ファイルシステムのキャッシュにLinuxシステムをより積極的に構成できますか?

ファイルシステムのキャッシュにLinuxシステムをより積極的に構成できますか?

RAMの使用量(メモリが十分なため)や予期しないシャットダウン時のデータの損失(電源がバックアップされ、システムが安定しており、データが重要ではないため)について心配しません。ただし、ファイル処理が多いため、パフォーマンスの向上が必要です。

これは、ファイルシステムの読み書きキャッシュにもっと多くのRAMを使用し、積極的にファイルを事前にインポートするようにシステムを設定する理由です。場合は、ファイルを読む場合)。大きなチャンクの前に)書き込みバッファがフラッシュされる頻度を減らします。これを達成する方法は?

私はXUbuntu 11.10 x86でext3とntfs(ntfsをたくさん使う!)ファイルシステムを使用しています。

ベストアンサー1

通常、ディスクキャッシュのパフォーマンスを向上させるには、ファイルシステムのキャッシュサイズを増やす必要があります。みんなシステムはRAMに適しています。この場合は、RAMドライブ(tmpfs場合によってはRAMが必要な場合はディスクに置き換えることができるため、推奨)をランタイムストアとして使用する必要があります(システムをストレージから別のストレージにコピーするinitrdスクリプトでもあります)。起動時にRAMドライブ))。

ストレージデバイスがSSDかHDDかを教えてくれませんでした。私が見つけた方法は次のとおりです(私の場合はsdaHDDがにマウントされ、/homeSSDsdbがにマウントされました/)。

まず、ストレージからキャッシュにコンテンツをロードする部分を最適化します。

私のHDD設定は次のとおりです(切り替えられている場合は、BIOSでAHCI + NCQが有効になっていることを確認してください)。

    echo cfq > /sys/block/sda/queue/scheduler
    echo 10000 > /sys/block/sda/queue/iosched/fifo_expire_async
    echo 250 > /sys/block/sda/queue/iosched/fifo_expire_sync
    echo 80 > /sys/block/sda/queue/iosched/slice_async
    echo 1 > /sys/block/sda/queue/iosched/low_latency
    echo 6 > /sys/block/sda/queue/iosched/quantum
    echo 5 > /sys/block/sda/queue/iosched/slice_async_rq
    echo 3 > /sys/block/sda/queue/iosched/slice_idle
    echo 100 > /sys/block/sda/queue/iosched/slice_sync
    hdparm -q -M 254 /dev/sda

単一プロセスが高いスループットを得るためにHDDケースが高い(通常は書き込みfifo_expire_async)と長く設定されていることは注目に値します(または複数のプロセスがディスク番号の一部のデータを並列に待機する状況が発生した場合は低)。 。これは常にHDDとのトレードオフですが、ディスク使用量とディスクファームウェアに応じて3〜20の範囲に設定することをお勧めします。私はより低い値を目指すことを好みますが、低すぎるとスループットが破壊されます。この設定はスループットに大きな影響を与えるようですが、待ち時間を合理的なレベルに保つためにはできるだけ低くしてください。低すぎるとスループットが破壊されます。 3〜8の範囲の値がHDDに適しているようです。カーネルの動作を正しく理解している場合、最悪の読み取り待ち時間は(*)+(*)ミリ秒です。非同期は主に書き込み用で、ディスクへの書き込みを遅らせるには、両方とも非常に低い数字に設定します。ただし、値が低すぎると、読み込み後に書き込みが遅れることがなくなり、読み込みができなくなる可能性があります。私の設定では、データがカーネルに渡されてから最大10秒間ディスクにデータを書き込もうとしますが、停電時にデータが失われる可能性があるため、ディスクに1が発生したことを通知するように設定されています。 1時間遅れは大丈夫です。ただし、値を低くしてください。そうしないと、読み取り待ち時間が長くなる可能性があります。slice_syncslice_syncslice_idlequantumquantumquantumslice_syncslice_async_rqslice_asyncslice_async_rqslice_asyncslice_async_rqfifo_expire_async3600000slice_async

このhdparmコマンドは、AAMがAHCI + NCQによって許容されるほとんどのパフォーマンスを破壊するのを防ぐために必要です。ディスクにノイズが多すぎる場合は、この手順をスキップしてください。

私のSSD(Intel 320シリーズ)設定は次のとおりです。

    echo cfq > /sys/block/sdb/queue/scheduler
    echo 1 > /sys/block/sdb/queue/iosched/back_seek_penalty
    echo 10000 > /sys/block/sdb/queue/iosched/fifo_expire_async
    echo 20 > /sys/block/sdb/queue/iosched/fifo_expire_sync
    echo 1 > /sys/block/sdb/queue/iosched/low_latency
    echo 6 > /sys/block/sdb/queue/iosched/quantum
    echo 2 > /sys/block/sdb/queue/iosched/slice_async
    echo 10 > /sys/block/sdb/queue/iosched/slice_async_rq
    echo 1 > /sys/block/sdb/queue/iosched/slice_idle
    echo 20 > /sys/block/sdb/queue/iosched/slice_sync

ここで注目すべき点は、さまざまなスライス設定の低い値です。 SSDの最も重要な設定はslice_idle0-1に設定する必要があります。 0に設定すると、すべての順序決定がデフォルトのNCQに移動し、1に設定するとカーネルは要求の順序を指定できます(ただし、NCQが有効になっている場合、ハードウェアは部分的にカーネル順序を上書きできます)。両方の値をテストし、違いがあることを確認してください。 Intel 320シリーズでは、最高のスループットを提供するようにslide_idle設定されているように見えますが、全体的な遅延時間が最良(最低)0設定ではありません。1十分に新しいカーネルがある場合は、slide_idle_usミリ秒ではなくマイクロ秒単位で値を設定でき、echo 14 > slice_idle_us代わりに同様のものを使用できます。良い値は、ストレージデバイスがサポートできる最大実際のIOPSで割った700000に近いと思われるので、合理的に高速なSSDデバイスの場合は14が大丈夫でしょう。

これらの調整可能パラメータの詳細については、次を参照してください。https://www.kernel.org/doc/Documentation/block/cfq-iosched.txt

Update 2020、カーネルバージョン5.3(cfqは使用できなくなりました):

#!/bin/bash
modprobe bfq
for d in /sys/block/sd?; do
  # HDD (tuned for Seagate SMR drive)
  echo bfq >"$d/queue/scheduler"
  echo 4 >"$d/queue/nr_requests"
  echo 32000 >"$d/queue/iosched/back_seek_max"
  echo 3 >"$d/queue/iosched/back_seek_penalty"
  echo 80 >"$d/queue/iosched/fifo_expire_sync"
  echo 1000 >"$d/queue/iosched/fifo_expire_async"
  echo 5300 >"$d/queue/iosched/slice_idle_us"
  echo 1 >"$d/queue/iosched/low_latency"
  echo 200 >"$d/queue/iosched/timeout_sync"
  echo 0 >"$d/queue/iosched/max_budget"
  echo 1 >"$d/queue/iosched/strict_guarantees"

  # additional tweaks for SSD (tuned for Samsung EVO 850):
  if test $(cat "$d/queue/rotational") = "0"; then
    echo 36 >"$d/queue/nr_requests"
    echo 1 >"$d/queue/iosched/back_seek_penalty"
    # slice_idle_us should be ~ 0.7/IOPS in µs
    echo 16 >"$d/queue/iosched/slice_idle_us"
    echo 10 >"$d/queue/iosched/fifo_expire_sync"
    echo 250 >"$d/queue/iosched/fifo_expire_async"
    echo 10 >"$d/queue/iosched/timeout_sync"
    echo 0 >"$d/queue/iosched/strict_guarantees"
  fi
done

設定は非常に似ていますが、後者が最新のカーネルでは機能しないため、今ではbfq代わりに使用しています。私はスケジュールをより正確に制御するためにできるだけ低くcfq保つよう努めます。少なくともSamsung SSDドライブは、高いIOPSで実行するにはかなり深いキューが必要なようです。nr_requestsbfq修正する:nr_requests多くのサムスンSSDにはファームウェアバグがあり、ファームウェアバグが高すぎてオペレーティングシステムが多数の要求をすばやく送信すると、デバイス全体がハングアップする可能性があります。高い値(32または36など)を使用すると、約2ヶ月ごとにランダムに凍結することがわかりますが、これまではnr_requests値が安定していました。6正式な修正はに設定することですが、1これはパフォーマンスに大きな影響を与えます!詳細については、次を参照してください。https://bugzilla.kernel.org/show_bug.cgi?id=203475そしてhttps://bugzilla.kernel.org/show_bug.cgi?id=201693- デフォルトでは、Samsung SSDデバイスを使用していてfailed command: WRITE FPDMA QUEUEDカーネルログにこの内容が表示されている場合は、すでにこのエラーが発生しています。

linux-lowlatency-hwe-18.04-edgeモジュールとしてのみ提供されるカーネルパッケージでUbuntu 18.04を使用しているため、bfq切り替える前にそれをロードする必要があります。

私も今zramを使用していますが、zramRAMの5%しか使用していません。これにより、Linuxカーネルはディスクに触れることなくスワップ関連のロジックを使用できます。ただし、ディスクスワップを使用しないことを決定した場合は、アプリケーションがRAMが漏れていないことを確認してください。そうでなければお金を無駄にします。

これで、適切なパフォーマンスでディスクのコンテンツをキャッシュにロードするようにカーネルを設定したので、キャッシュの動作を調整します。

私が行ったベンチマークによれば、事前読み取り設定をまったく気にしませんblockdev。カーネルのデフォルト設定は大丈夫です。

アプリケーションコードよりもスワップファイルデータを優先するようにシステムを設定します。 (データを保存するのに十分なRAMがあるかどうかは問題ではありません。)みんなファイルシステムそしてすべてのアプリケーションコードそしてアプリケーションがRAMに割り当てたすべての仮想メモリ。これにより、単一アプリケーションで大容量ファイルにアクセスするのにかかる待ち時間ではなく、複数のアプリケーション間の交換待ち時間が短縮されます。

echo 15 > /proc/sys/vm/swappiness

アプリケーションをほぼ常にRAMに保持したい場合は、この値を1に設定できます。 0 に設定すると、OOM を避けるために必要な場合を除き、カーネルはまったくスワップしません。メモリが限られていて大容量ファイル(HDビデオ編集など)で作業する必要がある場合は、100に近い設定をするのが合理的かもしれません。

RAMが十分であれば、今(2017)はスワップをまったく使用しないことを好みます。長期間実行されるデスクトップでは、交換しないと通常200〜1000 MBのRAMが失われます。最悪の待ち時間(RAMがいっぱいになったときのアプリケーションコードの交換)を避けるために、その程度を犠牲にすることがあります。実際には、これはSwapよりもOOM Killerを好むという意味です。スワップを許可/要求する場合は、/proc/sys/vm/watermark_scale_factor遅延を避けるためにスワップを増やすことをお勧めします。 100 ~ 500 の値を使用することをお勧めします。この設定は、より低い遷移待ち時間のためにCPU使用率を交換すると考えることができます。デフォルト値は10であり、可能な最大値は1000です。より高い値は(に従って)カーネル文書)kswapdプロセスの CPU 使用量が増加し、トランジション全体の待ち時間が短くなります。

次に、一部のRAMを空にする必要がある場合に備えて、ファイルの内容とページキャッシュの残りの部分よりもメモリのディレクトリ階層を維持することに優先順位を付けるようにカーネルに指示します(つまり、すべてがRAMに適している場合何もしません)。

echo 10 > /proc/sys/vm/vfs_cache_pressure

vfs_cache_pressureほとんどの場合、カーネルはキャッシュ内のファイルの内容を使用する前にディレクトリ構造と他のファイルシステムメタデータを知っておく必要があります。 。ただし、ページキャッシュには他のデータも含まれていますが、ファイルの内容のみが含まれているため、この設定はシステムの残りの部分に対するメタデータキャッシュの全体的な重要性と同じくらい重要であると考える必要があります。小さなファイルが多い場合(私のシステムには約150,000枚の10メガピクセルの写真があり、これは「小さなファイルが多い」システムと見なされます)、この設定を1に下げることをお勧めします。 0に設定しないでください。それ以外の場合、システムメモリが不足してもディレクトリ構造は常にメモリに残ります。継続的に再読み込みする必要がある大容量ファイルが数個しかない場合にのみ、この値をより大きな値に設定してください(十分なRAMを持たないHDビデオ編集はその例です)。公式カーネル文書では、「vfs_cache_Pressureを100以上に大幅に上げると、パフォーマンスに悪影響を及ぼす可能性がある」と述べています。

2021年アップデート:vfs_cache_pressureカーネルバージョン5.4を十分に長時間実行した後、非常に低い設定(長年にわたって実行1)が長時間一時停止/悪い遅延を引き起こす可能性があるという結論に達しました。メモリ圧力が十分に高い場合。しかし、カーネルバージョン5.3以下では、これらの動作を見たことはありません。

2022年アップデート:私は1年間カーネル5.4.xシリーズを使用してきましたが、私の結論はvfs_cache_presure永久に変わりました。カーネルバージョン5.3以下(1..5の範囲の値)を使用して得られたカーネルメモリマネージャの動作は、実際の動作(100..120の範囲の値を持つ5.4)と一致するようです。最新のカーネルではこの調整がより重要であるため、vfs_cache_presure=120全体的な低レイテンシのために今この値を使用することをお勧めします。私の考えでは、カーネルバージョン5.3以下では非常に低いですが、ゼロ以外の値を使用する必要があります。

例外:ファイルやディレクトリが多く、どちらもタッチ/読み取り/表示することがほとんどない場合は、vfs_cache_pressure100より高く設定することをお勧めします。これは、十分なRAMを持たず、完全なディレクトリ構造をRAMに保持することはできませんが、通常のファイルキャッシュとプロセスに十分なRAMがある場合にのみ適用されます。 。 100以上に増やさなければならないと思えばvfs_cache_pressureRAMが不足しているのです。より多くのメモリがvfs_cache_pressure役に立つかもしれませんが、唯一の実際の解決策はより多くのメモリを確保することです。高い数値に設定すると、全体的なパフォーマンスvfs_cache_pressureがより安定したままになるように平均パフォーマンスが犠牲になります。つまり、非常に悪い最悪の動作は避けますが、全体的なパフォーマンスが悪くなる場合に対処する必要があります。

最後に、カーネルに最大99%のRAMを書き込みキャッシュとして使用するように指示し、書き込みプロセスを遅くする前にカーネルに最大50%のRAMを使用するように指示します(デフォルトはdirty_background_ratio10警告: 私は個人的にそうしません。しかし、あなたはRAMが十分でデータを失うことを望んでいると主張します。

echo 99 > /proc/sys/vm/dirty_ratio
echo 50 > /proc/sys/vm/dirty_background_ratio

そして、1時間の書き込み遅延は大丈夫だと思いました。スタートディスクに何かを書く(もう一度言うが、私はこれをしないでしょう):

echo 360000 > /proc/sys/vm/dirty_expire_centisecs
echo 360000 > /proc/sys/vm/dirty_writeback_centisecs

これらの調整可能パラメータの詳細については、次を参照してください。https://www.kernel.org/doc/Documentation/sysctl/vm.txt

このすべてを/etc/rc.local最後に置き、次を含めると、起動後、できるだけ早くすべてがキャッシュに保存されます(ファイルシステムが実際にRAMに適している場合にのみこれを実行してください)。

(nice find / -type f -and -not -path '/sys/*' -and -not -path '/proc/*' -print0 2>/dev/null | nice ionice -c 3 wc -l --files0-from - > /dev/null)&

または、よりうまく機能するより簡単な代替策(合計をキャッシュするだけです。合計が/home実際にRAMに収まる/usr場合にのみこれを実行してください):/home/usr

(nice find /home /usr -type f -print0 | nice ionice -c 3 wc -l --files0-from - > /dev/null)&

おすすめ記事