Iva*_*van 146 linux performance filesystems fstab sysctl
我既不担心 RAM 使用情况(因为我已经足够了),也不担心在意外关闭的情况下丢失数据(因为我的电源有保障,系统是可靠的,数据并不重要)。但是我做了很多文件处理并且可以使用一些性能提升。
这就是为什么我想将系统设置为使用更多 RAM 进行文件系统读写缓存,积极预取文件(例如,预读应用程序访问的整个文件,以防文件大小合理或至少否则,请提前读取其中的一大块)并减少刷新写入缓冲区的频率。如何实现这一目标(可能)?
我在 XUbuntu 11.10 x86 上使用 ext3 和 ntfs(我经常使用 ntfs!)文件系统。
Mik*_*nen 132
一般来说,提高磁盘缓存性能不仅仅是增加文件系统缓存大小,除非您的整个系统适合 RAM,在这种情况下您应该使用 RAM 驱动器(tmpfs这很好,因为如果您在某些情况下需要 RAM,它允许回退到磁盘)用于运行时存储(可能还有一个 initrd 脚本,用于在启动时将系统从存储复制到 RAM 驱动器)。
您没有说明您的存储设备是 SSD 还是 HDD。这是我发现对我有用的东西(在我的情况下sda是安装在 的 HDD/home和sdb安装在 的 SSD /)。
首先优化load-stuff-from-storage-to-cache部分:
这是我的 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
Run Code Online (Sandbox Code Playgroud)
值得注意的是,对于 HDD 来说,HDD 的情况是高fifo_expire_async(通常是写)和长,slice_sync以允许单个进程获得高吞吐量(slice_sync如果遇到多个进程并行等待来自磁盘的某些数据的情况,则设置为较低的数字)。这slice_idle始终是 HDD 的妥协,但根据磁盘使用情况和磁盘固件,将其设置在 3-20 范围内应该没问题。我更喜欢以低值为目标,但将其设置得太低会破坏您的吞吐量。该quantum设置似乎对吞吐量影响很大,但尽量将其保持在尽可能低的水平,以将延迟保持在合理的水平。设置quantum太低会破坏吞吐量。3-8 范围内的值似乎适用于 HDD。读取的最坏情况延迟是 ( quantum* slice_sync) + (slice_async_rq *slice_async) ms 如果我正确理解了内核行为。异步方式主要用于写入,因为你是愿意延迟写入磁盘,集两者slice_async_rq并slice_async以非常低的数字。但是,设置slice_async_rq太低的值可能会导致读取延迟,因为读取后不能再延迟写入。我的配置将尝试将数据写入磁盘最多10秒后数据已经传递到内核之后,但因为你可以容忍的功率损耗数据也设置的损失fifo_expire_async来3600000告诉大家,1个小时还好耽搁到磁盘。slice_async但是,请保持较低,否则您可能会获得较高的读取延迟。
hdparm需要该命令以防止 AAM 破坏 AHCI+NCQ 允许的大部分性能。如果您的磁盘噪音太大,请跳过此步骤。
这是我对 SSD(英特尔 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
Run Code Online (Sandbox Code Playgroud)
这里值得注意的是不同切片设置的低值。SSD 最重要的设置是slice_idle必须设置为 0-1。将其设置为零会将所有排序决策移至本机 NCQ,而将其设置为 1 允许内核对请求进行排序(但如果 NCQ 处于活动状态,硬件可能会部分覆盖内核排序)。测试这两个值以查看您是否可以看到差异。对于 Intel 320 系列,似乎设置slide_idle为0可提供最佳吞吐量,但将其设置为可1提供最佳(最低)整体延迟。
有关这些可调参数的更多信息,请参阅https://www.kernel.org/doc/Documentation/block/cfq-iosched.txt。
2020 年更新和内核版本 5.3(cfq 已死):
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
Run Code Online (Sandbox Code Playgroud)
设置非常相似,但我现在使用bfq而不是cfq因为后者不适用于现代内核。我尽量保持nr_requests尽可能低,以便bfq更准确地控制调度。至少三星 SSD 驱动器似乎需要相当深的队列才能以高 IOPS 运行。
我正在使用带有内核包的 Ubuntu 18.04,linux-lowlatency-hwe-18.04-edge它bfq只有作为模块,所以我需要先加载它才能切换到它。
我现在也使用,zram但我只将 5% 的 RAM 用于 zram。这允许 Linux 内核在不接触磁盘的情况下使用交换相关逻辑。但是,如果您决定采用零磁盘交换,请确保您的应用程序不会泄漏 RAM 或浪费金钱。
现在我们已经配置内核以合理的性能从磁盘加载内容到缓存,是时候调整缓存行为了:
根据我所做的基准测试,我根本不会费心设置预读blockdev。内核默认设置很好。
将系统设置为更喜欢交换文件数据而不是应用程序代码(如果您有足够的 RAM 来保存整个文件系统和所有应用程序代码以及应用程序在 RAM 中分配的所有虚拟内存,这并不重要)。这减少了在不同应用程序之间交换的延迟,而不是从单个应用程序访问大文件的延迟:
echo 15 > /proc/sys/vm/swappiness
Run Code Online (Sandbox Code Playgroud)
如果您希望将应用程序几乎始终保留在 RAM 中,您可以将其设置为 1。如果您将其设置为 0,内核将根本不会交换,除非绝对有必要避免 OOM。如果您的内存有限并且处理大文件(例如高清视频编辑),那么将其设置为接近 100 可能是有意义的。
如果您有足够的 RAM,我现在(2017 年)更喜欢根本没有交换。在长时间运行的台式机上,没有交换通常会丢失 200-1000 MB 的 RAM。我愿意牺牲那么多以避免最坏情况下的延迟(当 RAM 已满时交换应用程序代码)。实际上,这意味着我更喜欢 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
Run Code Online (Sandbox Code Playgroud)
环境 vfs_cache_pressure设置为低值是有道理的,因为在大多数情况下,内核需要知道目录结构才能使用缓存中的文件内容,而过早刷新目录缓存会使文件缓存几乎毫无价值。如果您有很多小文件(我的系统有大约 150K 10 兆像素的照片并且算作“很多小文件”系统),请考虑使用此设置一直降到 1。切勿将其设置为零或目录结构始终保留在内存中,即使系统内存不足。仅当您只有几个不断被重新读取的大文件时,才将此设置为大值是明智的(同样,没有足够 RAM 的高清视频编辑将是一个示例案例)。官方内核文档说“
2021 年更新:在使用内核版本 5.4 运行足够长的时间后,我得出的结论是,当内存压力足够高时,非常低的vfs_cache_pressure设置(我曾经运行1多年)现在可能会导致长时间停顿/不良延迟。但是,我从未注意到内核版本 5.3 或更低版本的这种行为。
例外:如果你真的有大量的文件和目录并且你很少接触/读取/列出所有文件设置vfs_cache_pressure高于 100 可能是明智的。这仅适用于您没有足够的 RAM 并且无法在 RAM 中保留整个目录结构并且仍然有足够的 RAM 用于正常文件缓存和进程(例如,具有大量存档内容的公司范围的文件服务器)的情况。如果您觉得需要增加到vfs_cache_pressure100 以上,那么您的运行内存不足。增加vfs_cache_pressure可能会有所帮助,但唯一真正的解决方法是获得更多 RAM。拥有vfs_cache_pressure一套以大量牺牲平均业绩整体有更稳定的性能(即,你能避免非常糟糕的最坏情况的行为,但不得不面对较差总体性能)。
最后告诉内核使用到RAM作为缓存写入,并指示内核放缓是的写作过程之前,使用最多的RAM 50%的99%(默认dirty_background_ratio为10)。警告:我个人不会这样做,但您声称有足够的 RAM 并愿意丢失数据。
echo 99 > /proc/sys/vm/dirty_ratio
echo 50 > /proc/sys/vm/dirty_background_ratio
Run Code Online (Sandbox Code Playgroud)
并告诉 1 小时写入延迟甚至可以开始在磁盘上写入内容(同样,我不会这样做):
echo 360000 > /proc/sys/vm/dirty_expire_centisecs
echo 360000 > /proc/sys/vm/dirty_writeback_centisecs
Run Code Online (Sandbox Code Playgroud)
有关这些可调参数的更多信息,请参阅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)&
Run Code Online (Sandbox Code Playgroud)
或者一个更简单的替代方案,它可能会更好(仅缓存/home和/usr,仅当您的/home和/usr真正适合 RAM时才这样做):
(nice find /home /usr -type f -print0 | nice ionice -c 3 wc -l --files0-from - > /dev/null)&
Run Code Online (Sandbox Code Playgroud)
Fel*_*Yan 17
首先,我不建议您继续使用 NTFS,因为在 Linux 中实施 ntfs 随时都会出现性能和安全问题。
您可以执行以下几项操作:
ext4或btrfsbfqpreloadsystemd在启动时使用类似预加载的东西也许你想试一试:-)
提前阅读:
在 32 位系统上:
blockdev --setra 8388607 /dev/sda
Run Code Online (Sandbox Code Playgroud)
在 64 位系统上:
blockdev --setra 4294967295 /dev/sda
Run Code Online (Sandbox Code Playgroud)
写在缓存后面:
echo 90 > /proc/sys/vm/dirty_ratio # too high rates can cause crash
Run Code Online (Sandbox Code Playgroud)
这将使用多达 90% 的可用内存作为写入缓存。
或者你可以全力以赴使用tmpfs。这仅在您有足够的 RAM 时才相关。把这个放在/etc/fstab. 用您选择的数量替换 50%。它始终是整个 RAM 的百分比。此外,8G 可用作 8GB,3M 可用作 3MB
tmpfs /mnt/tmpfs tmpfs size=50%,rw,nosuid,nodev 0 0 # you can do that with more things, as the /tmp folder. The 50% can be replaced with 4G, 5G... 50% is the half of the whole ram. Also higher values work because it will go into swap
Run Code Online (Sandbox Code Playgroud)
然后:
mkdir /mnt/tmpfs; mount -a
Run Code Online (Sandbox Code Playgroud)
然后使用 /mnt/tmpfs。