
Linux VFSのページキャッシュと調整可能なパラメータに関する記事を読んだ後、ページキャッシュは読み取りと書き込みのdirty_ratio
キャッシュ層として機能するという印象を受けました。
ただし、以下の簡単なテストを使用すると、ページキャッシュにあるが書き込みには使用できないファイルの読み取り速度を向上させるのに効果的です。
例えば
キャッシュを消去してファイルに書き込みます。
# swapoff -a
# echo 3 > /proc/sys/vm/drop_caches
# dd if=/dev/zero of=/home/flo/test bs=1M count=30
30+0 records in
30+0 records out
31457280 bytes (31 MB) copied, 0.182474 s, 172 MB/s
ファイルが実際にページキャッシュにあることを確認する
# vmtouch /home/flo/test
Files: 1
Directories: 0
Resident Pages: 7680/7680 30M/30M 100%
Elapsed: 0.000673 seconds
ファイルを読み、実際にキャッシュから出ていることを確認してください。
# dd if=/home/flo/test of=/dev/null bs=1M count=30
30+0 records in
30+0 records out
31457280 bytes (31 MB) copied, 0.00824169 s, 3.8 GB/s
キャッシュを削除して再読み込みして速度の違いを確認してください。
# echo 3 > /proc/sys/vm/drop_caches
# dd if=/home/flo/test of=/dev/null bs=1M count=30
30+0 records in
30+0 records out
31457280 bytes (31 MB) copied, 0.132531 s, 237 MB/s
dd で DIRECT_IO を使用しないので、ページキャッシュを書き込みストレージタイプのキャッシュとして使用したいと思います。そしてdirty_ratio
それに基づいて、dirty_expire_centiseconds
最終データがディスクにコミットされます。
特に、書き込み中にVFSが読み取りおよび書き込みプロセスを異なる方法で処理する方法とスピードアップがない理由を説明できる人はいますか?
書き込みキャッシュを使用してvfsをさらに積極的に作成し、RAIDコントローラの書き換えキャッシュのように動作させる方法はありますか?
ありがとう
ルオ
答え1
man ext4には(no)オプションが導入されていますauto_da_alloc
。
多くの破損したアプリケーションはfsync()を使用しません...
これの後には長い話があるようです(データ損失に対する悲劇)。これは以下に関連しています。遅延割り当てファイルシステムブロック。 Ext2/3にはこの機能はありませんが、ext4だけでなく非常に重要な機能です。
アプリケーションが同期されておらず、ユーザーが手動で同期せず、カーネルが30秒後にも同期されない場合は、一部のファイルを再構築するときにファイルシステムがすぐに同期を実行する方が良いでしょう。そうしないと、DAを使用すると停電中に悪いことが起こりやすくなります。最後の変更を失うよりも悪いことがあります。
conv=notruncate
ddコマンドがなければ、上書きは「アプリケーション」と同じです。新しいファイルを作成するには、既存のファイルを削除する必要があります。それ以外の場合、既存のファイルが長い場合は混合ファイルが生成されます。
mount -o remount,noauto_da_alloc ...
ext4ではこの動作をオフにできます。これで、ブロック書き込みは切り捨てられた後も長い間完了することができます。
Next攻撃性レベル定期的な書き込み保存(/proc/sys/vm/のdirty_..._centisecs値)の有効期限30秒と確認間隔5秒が増えます。デフォルトの30/5では、非常に早く削除しない限り、30分後にいくつかの新しいファイルが記録されます。
VFSが使用されていないページに対してより積極的であるほど、ファイルシステムはデバイスをブロックするのにあまり積極的ではありません。
マウントオプションと書き込み保存パラメータ
]# findmnt --real
TARGET SOURCE FSTYPE OPTIONS
/ /dev/sda3 ext4 rw,relatime,noauto_da_alloc
|-/root/sda1 /dev/sda1 ext2 rw,relatime
`-/root/16 /dev/sda16 ext4 rw,relatime
これらの設定では、オーバーレイはsda16ですぐに同期されますが、他の2つでは同期されません。
現在、私は定期的な書き込み保存を完全に解放しています。
]# grep '' /proc/sys/vm/*centisecs
/proc/sys/vm/dirty_expire_centisecs:720000
/proc/sys/vm/dirty_writeback_centisecs:0
最後にダーティページを収集します。
]# grep nr_dirty /proc/vmstat
nr_dirty 10077
nr_dirty_threshold 437320
nr_dirty_background_threshold 174671
私努力するこれを収集し、何とか基本的な10%の背景比率に近づきました。昨日、メモリスリープモードに切り替えたときに同期を受けました。これは意味があります。誰がMBのダーティーページを持って寝たいですか?
mm/writeback.c
詳細は複雑で、レビュー自体がこれを示しています。 1つの問題は、「1000 ddがすぐに汚れ始める」という調整ポイントを見逃さないことです。長期的に「書き込み保存」目標は10%程度のようです。上記の例に示すように、通常の(最小)使用量でこの10%(合計/利用可能なRAM)を満たすのに長い時間がかかります。ナビゲーション1分に約1,000ページが汚れます。
理論終了後、具体的な証明
上記の2つのファイルシステムで10個のブロックをテストしました。
]# dd if=/dev/zero of=test10 bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 0.0076396 s, 1.4 GB/s
]# dd if=/dev/zero of=test10 bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 0.00514406 s, 2.0 GB/s
->ルートパーティション(sda3、上記)でnoauto_da_allocを使用すると、上書きが高速になります。
ext4(上記のsda16)のデフォルトインストールでは速度が遅くなります。
]# rm test10
]# dd if=/dev/zero of=test10 bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 0.00800839 s, 1.3 GB/s
]# dd if=/dev/zero of=test10 bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 0.0740824 s, 142 MB/s
...図のように全体の適用範囲が同期しているためですvmstat 1 |cut...
。
0 0
0 0
0 0
-----io----
bi bo
0 10240
0 0
0 0
手動遅延sync
割り当て
良いことは、必要に応じて実行でき、単一のファイルまたはドライブ全体で実行できることです。
プラス:削除、終了(および中断)も含まれます。
悪いことは、書き込み(上書き)と同期の間に衝突/停電が発生したときに長さ0の「損傷」の危険があることです。これは、実際には1つまたは2つの外部ストレージに保存されているコンテンツのみを安全に保存できることを意味します。
結論が見つかりません。簡単な解決策はなく、長い(しかし少なくとも論理的な)説明しかありません。
答え2
迅速な行動を見るには、rm test
まずそれを行う必要があります。たとえば、dd
150MB/s ではなく 1GB/s が報告されました。
引用:
auto_da_alloc
存在する人々 ext4。- LWN.net記事」ext4とデータ損失」。
- この場合、XFSは同じことを行いますが、ext4は他の場合(既存のファイルの名前変更)では行いません。https://www.spinics.net/lists/xfs/msg36717.html。
この参照では、この操作を試みる理由だけを説明しますが、実際にIOブロックが発生する理由については説明しません。
私のコンピュータでは、2016年に追加された新しいWBT(「Write Back Limits」)コードでのみブロックが発生しているようです。後ろに質問しました。まだ分析したことはありません。なぜこれにより発生する可能性があります。 WBTが無効になると消えます。
私のカーネルバージョンは4.18.16-200.fc28.x86_64
。
strace -T
すべての時間がclose()で費やされることを示すことは私にとって最も意味があります。を試してみましたperf
。期待どおりに動作しませんが、次のスタックトレースが表示されます。
dd 17068 [003] 475165.381526: sched:sched_switch: dd:17068 [120] T ==> kworker/3:1H:19326 [100]
ffffffffa390c172 __sched_text_start+0x352 ([kernel.kallsyms])
ffffffffa390c172 __sched_text_start+0x352 ([kernel.kallsyms])
ffffffffa390c6a8 schedule+0x28 ([kernel.kallsyms])
ffffffffa30def32 io_schedule+0x12 ([kernel.kallsyms])
ffffffffa3461ed7 wbt_wait+0x337 ([kernel.kallsyms])
ffffffffa342ee33 blk_queue_bio+0x123 ([kernel.kallsyms])
ffffffffa342d114 generic_make_request+0x1a4 ([kernel.kallsyms])
ffffffffa342d3c5 submit_bio+0x45 ([kernel.kallsyms])
ffffffffa3377d78 ext4_io_submit+0x48 ([kernel.kallsyms])
ffffffffa335da2c ext4_writepages+0x70c ([kernel.kallsyms])
ffffffffa3209311 do_writepages+0x41 ([kernel.kallsyms])
ffffffffa31f808e __filemap_fdatawrite_range+0xbe ([kernel.kallsyms])
ffffffffa334b9ec ext4_release_file+0x6c ([kernel.kallsyms])
ffffffffa32a9d4e __fput+0xae ([kernel.kallsyms])
ffffffffa30cf474 task_work_run+0x84 ([kernel.kallsyms])
ffffffffa3003e6e exit_to_usermode_loop+0xce ([kernel.kallsyms])
ffffffffa300425d do_syscall_64+0x14d ([kernel.kallsyms])
ffffffffa3a00088 entry_SYSCALL_64_after_hwframe+0x44 ([kernel.kallsyms])
7fcca3a60654 __close+0x14 (/usr/lib64/libc-2.27.so)
deadline
これは、現在 WBT ("writeback throttling") がアクティブな I/O スケジューラをテストしていることを思い出させます。 WBTを無効にすると(互換性のないCFQへの切り替えを含む)、再びすぐに動作するようになりました!
perf
これを見るために使用するコマンドは次のとおりです。
sudo perf record -e sched:sched_stat_sleep -e sched:sched_switch -e sched:sched_process_exit -gP -o ~/perf.data dd if=/dev/zero of=test bs=1M count=30
sudo perf script -i ~/perf.data | cat
答え3
ただ使用しないでくださいdd
。たとえば、を使用すると、書き込み用のcp
ページキャッシュを取得します。