以前のQ&Aでdirty_ratioの実験を示したことがあります。
書き込みストレージキャッシュ(「ダーティ」)はdirty_Background_ratioよりはるかに小さいものに制限されているようです。その限界は何ですか?この制限はどのように計算されますか?
汚い料金計算の理解を正し、問題を解決したと思います。しかし、私は実験を繰り返しましたが、書き換えキャッシュは以前に見たものよりも低く調整されました。この問題を解決できませんでした。問題を制限するものは何ですか?
sysctlのデフォルト値がありますvm.dirty*
。 dirty_background_ratio
10、20dirty_ratio
です。 「比率」は、MemFree
+のパーセントで表されるダーティページキャッシュ(つまり、書き換えキャッシュ)のサイズを表しますCached
。彼らいいえパーセンテージMemTotal
- 上記の質問で私が混乱しているのはこれです。
この割合は、10%に達するとバックグラウンド書き込みストアが開始され、20%は書き込みストレージキャッシュの最大サイズであることを意味します。また、後者のキャッシュには「I / Oなしダーティ制限」が適用されることがわかります。書き込みストレージキャッシュが15%以上に増加すると、ダーティページを生成するためにwrite()を使用するプロセスが「制限」されます。つまり、カーネルは write() 呼び出し内でプロセスを休止状態にします。したがって、カーネルはスリープ期間を制御して、後書きキャッシュのサイズを制御できます。参考までに、前の質問に対する回答をご覧ください。
しかし、私が観察した「比率」は、15%の制限しきい値よりはるかに低いようです。私が見逃したいくつかの要素が必要です!なぜこれが起こるのですか?
以前のテストでは15〜17.5%程度の値を見ました。
私のカーネルはLinuxです4.18.16-200.fc28.x86_64
。
テストは次のとおりです。私はdd if=/dev/zero of=~/test bs=1M status=progress
。同時に達成された汚れの割合を監視しました。dd
15GB以降にコマンドを中断しました。
$ while true; do grep -E '^(Dirty:|Writeback:|MemFree:|Cached:)' /proc/meminfo | tr '\n' ' '; echo; sleep 1; done
...
MemFree: 139852 kB Cached: 3443460 kB Dirty: 300240 kB Writeback: 135280 kB
MemFree: 145932 kB Cached: 3437220 kB Dirty: 319588 kB Writeback: 112080 kB
MemFree: 134324 kB Cached: 3448776 kB Dirty: 237612 kB Writeback: 160528 kB
MemFree: 134012 kB Cached: 3449004 kB Dirty: 169064 kB Writeback: 143256 kB
MemFree: 133760 kB Cached: 3449024 kB Dirty: 105484 kB Writeback: 119968 kB
MemFree: 133584 kB Cached: 3449032 kB Dirty: 49068 kB Writeback: 104412 kB
MemFree: 134712 kB Cached: 3449116 kB Dirty: 80 kB Writeback: 78740 kB
MemFree: 135448 kB Cached: 3449116 kB Dirty: 8 kB Writeback: 0 kB
たとえば、出力の最初の行を引用するには、次のようにします。
avail = 139852 + 3443460 = 3583312
dirty = 300240 + 135280 = 435520
ratio = 435520 / 3583312 = 0.122...
私はそれを制限するものを見つけましたが、これらの結果を見るのに十分ではありませんでした。私はそれを設定しようとしました/sys/class/bdi/*max_ratio
。質問のテスト結果は、max_ratio = 1で実行した結果です。
上記のテストを繰り返すと、max_ratio = 100
より高いダーティ比(例えば0.142)が得られます。
MemFree: 122936 kB Cached: 3012244 kB Dirty: 333224 kB Writeback: 13532 kB
書き込みテストはこれを安定して観察するのにかなり長い時間がかかります(たとえば、8GB)。このテストには約100秒かかります。回転するハードドライブを使用しています。
4GBでテストしようとしましたが、ダーティ比はわずか0.129でした。
MemFree: 118388 kB Cached: 2982720 kB Dirty: 249020 kB Writeback: 151556 kB
私が言ったように、これは私を驚かせました。専門家のソースがあります。2013年dd
、システムがダーティレート0.15に達するまでダーティページを作成するには、「フリーラン」が必要です。それはそれについて明示的に話しますmax_ratio
。
答え1
MemFree
「比率」は、+のパーセントで表されるダーティページキャッシュ(つまり、書き換えキャッシュ)のサイズを表しますCached
。これは MemTotal のパーセンテージではありません。上記の質問で、私が混乱していた部分がここにあります。
いいえ、その説明はまだ正確ではありません。
Cached
tmpfs
、およびその他のディストリビューションShmem
のすべてのファイルが含まれています。ページキャッシュを使用して実装されているため計算されます。ただし、これは永続ストレージのキャッシュではありません。ただ捨てることはできません。 tmpfs
ページは交換できますが、交換可能ページは計算に含まれません。
私はそのうち500-600MBを持っていますShmem
。トレースポイントをもう一度見ようとした場合(以前の質問に対する回答を参照)、これはおおよそ適切な量であり、/ limit
0.20が予想よりも低い理由を説明します。
また、Cached
除外するBuffers
ことができます。一部の設定では驚くほど大量に発生します。
実装を詳しく見なければならないと思いました。global_dirtyable_pages()私のカーネルバージョンでは/proc/vmstat
。
答え2
ext2/4では、5秒ごとにデフォルトのリフレッシュが行われ、data=ordered
これはデフォルトでもあります。
commit=nrsec
Start a journal commit every nrsec seconds. The default value is 5 seconds. Zero means de-
fault.
したがって、ページが汚れた状態を維持したくない場合(またはあまりにも長い間汚れたままになっている場合)、最初に調整する必要がある場所はここです。
ここにジレンマがあります。数年前、ext4データの損失に関連する大きな問題です(参照:noauto_da_allocインストールオプション):
カーネルは必要な場合にのみ書き込む準備ができています。したがって、サイズと期間、または制限に基づいて制限できます。 VMはプライマリストレージのキャッシュとして機能します。
「デスクトップ」ユーザーは、ほとんどこの追加レイヤーを使用する準備ができていません。彼がするとき救うファイルを除外すると、すぐにストレージに物理的にファイルが存在します。これがvim
fsまたはfsyncオプションがある理由です。
有効にすると、ファイルに書き込まれ、ライブラリ関数fsync()が呼び出されます。これにより、ファイルをディスクにフラッシュして、メタデータのロギングのみを実行するファイルシステムにも安全に書き込むことができます。これにより、ノートブックモードで実行されているLinuxシステムでハードドライブが強制的に回転するため、場合によっては望ましくない可能性があります。
git repoで500,000のダーティページがありましたが、background
サイズ制限に達して完全に消えました。また、gitがrepack / garbageコレクションを決定すると、同期しているようです。vim
setに似ています。fs
(他のパーティションの)マウントも同期されます。
しかし、ext4 logの長くてratio
長いコミット時間のため、expire_centisecs
5秒もなく、誰も(vim、git)同期されません。RAMの半分が数時間汚れることがあります。
答え3
ddのサイズを数ページに縮小しました。
dd if=/dev/zero of=zerooo count=250 bs=4096
スクリプトには重要なパラメータが表示されます。
grep dirty /proc/vmstat
grep '' /proc/sys/vm/*centi*
grep '' /proc/sys/vm/dirt*ratio
有効期限は実際に解放されており、しきい値は250ddページより高いです。
nr_dirty 0
nr_dirty_threshold 2398
nr_dirty_background_threshold 1199
/proc/sys/vm/dirty_expire_centisecs:360000
/proc/sys/vm/dirty_writeback_centisecs:360000
/proc/sys/vm/dirty_background_ratio:0
/proc/sys/vm/dirty_ratio:0
比率はゼロで、これは絶対パラメータをエコーしていることを示します。
/proc/sys/vm/dirty_background_bytes:9819200
/proc/sys/vm/dirty_bytes:9819200
先行9は819200バイト= 200ページを約1000ページに変換します。上記の「しきい値」を参照してください。
これでインストールオプションが重要です。残念ながら、「data = writeback」もインストールしていましたが、一部のリフレッシュが間接的に妨げられたかどうかはわかりません。しかし、ddが直接ダーティページのみを生成するには、noauto、長いコミット、および「書き込み」がすべて必要なようです。
TARGET SOURCE FSTYPE OPTIONS
/ /dev/sda3 ext4 rw,relatime,noauto_da_alloc,data=writeback
`-/mnt/sda/4 /dev/sda4 ext4 rw,relatime,noauto_da_alloc,commit=3600,data=writeback
今:
$ time dd if=/dev/zero of=zerooo count=150 bs=4096
150+0 records in
150+0 records out
614400 bytes (614 kB, 600 KiB) copied, 0.00106973 s, 574 MB/s
real 0m0.003s
user 0m0.000s
sys 0m0.003s
オリジナル版もあります。並列に実行するスクリプト:
Dirty: 0 kB Writeback: 0 kB
Dirty: 0 kB Writeback: 0 kB
Dirty: 0 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 600 kB Writeback: 0 kB
Dirty: 0 kB Writeback: 0 kB
Dirty: 0 kB Writeback:
ゼロに降りるのが私がZerooooでやったことです。賞味期限が長く、ここまで残っています。
後ろに:
echo 25600 > /proc/sys/vm/dirty_bytes
しきい値は非常に小さいです。背景値は自動的に50%に調整されます。 :
nr_dirty 0
nr_dirty_threshold 7
nr_dirty_background_threshold 3
今私は次を得ます:
$ time dd if=/dev/zero of=zerooo count=150 bs=4096
150+0 records in
150+0 records out
614400 bytes (614 kB, 600 KiB) copied, 0.0258571 s, 23.8 MB/s
real 0m0.028s
user 0m0.003s
sys 0m0.000s
もっと長く、もっと長く!コントロールパネル!そして残りの12kBのダーティデータだけがあります。
Dirty: 0 kB Writeback: 0 kB
Dirty: 0 kB Writeback: 0 kB
Dirty: 0 kB Writeback: 0 kB
Dirty: 12 kB Writeback: 0 kB
Dirty: 12 kB Writeback: 0 kB
Dirty: 12 kB Writeback: 0 kB
Dirty: 12 kB Writeback: 0 kB
... snip
Dirty: 12 kB Writeback: 0 kB
Dirty: 12 kB Writeback: 0 kB
Dirty: 0 kB Writeback: 0 kB
Dirty: 0 kB Writeback: 0 kB
rm Zerooo は nr_dirty を 0 に戻します。
DD#3:
上限は150ページよりはるかに高いですが、背景はまだ3つです。
nr_dirty 0
nr_dirty_threshold 2448
nr_dirty_background_threshold 3
ddが最高速度に戻った。 ddは、このページが正確にどこにあるのか気にしません。すでに書かれています。
$ time dd if=/dev/zero of=zerooo count=150 bs=4096
150+0 records in
150+0 records out
614400 bytes (614 kB, 600 KiB) copied, 0.0011005 s, 558 MB/s
real 0m0.003s
user 0m0.003s
sys 0m0.000s
結果は2番目の実行に似ています。一部のkBは「バックグラウンド」にフラッシュされませんが、数字が低いため、おそらく人工的な噴水です。私の経験では、起動すると「0」にフラッシュされます。
Dirty: 0 kB Writeback: 0 kB
Dirty: 0 kB Writeback: 0 kB
Dirty: 36 kB Writeback: 0 kB
Dirty: 36 kB Writeback: 0 kB
Dirty: 36 kB Writeback: 0 kB
Dirty: 36 kB Writeback: 0 kB
Dirty: 36 kB Writeback: 0 kB
Dirty: 36 kB Writeback: 0 kB
Dirty: 36 kB Writeback: 0 kB
Dirty: 0 kB Writeback: 0 kB
Dirty: 0 kB Writeback: 0 kB
それでは、次のように変更してください。
mount -o remount,commit=13 /mnt/sda/4
背景が150ページを超えると(最初の実行を参照)、data = writebackを使用しても13秒後に追加のダーティ情報が得られます。
Dirty: 0 kB
Dirty: 0 kB
Dirty: 0 kB
Dirty: 456 kB ??? seems to appear always
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 600 kB
Dirty: 620 kB !!! after 13 seconds commit= mount option
Dirty: 620 kB
Dirty: 620 kB
Dirty: 620 kB
Dirty: 620 kB
Dirty: 620 kB
Dirty: 620 kB
Dirty: 620 kB
Dirty: 620 kB
Dirty: 620 kB rm zeroooo
Dirty: 20 kB
Dirty: 20 kB
Dirty: 20 kB
Dirty: 20 kB
Dirty: 20 kB
Dirty: 20 kB sync
Dirty: 0 kB
この5秒データとメタデータパケットは、/ proc / sys / vm /の "centsecs"パラメータによって30秒ごとに更新する必要があります。でも一緒だけ。これがdata=ordered
働くところです。
nr_dirty
タイトル:もちろん、ctrl-c ddを押した後に監視スクリプトを起動すると、/ proc / vmstatの内容は上限しきい値を超えることはできません。