it-swarm.cn

我可以配置Linux系统以获得更积极的文件系统缓存吗?

我既不担心RAM使用情况(我已经足够了)),也不担心因意外关机而丢失数据(因为我的电源得到了支持,系统可靠并且数据并不是很关键),但是我做了很多文件处理,可能会提高性能。

这就是为什么我想设置系统以使用更多RAM用于文件系统读写缓存,以便积极地预取文件(例如,预先读取应用程序访问的整个文件,以防万一)文件的大小是否合理,或者至少预读了很大一部分),并减少了刷新缓冲区的频率,如何实现(可能)?

我在XUbuntu 11.10 x86上使用ext3和ntfs(我经常使用ntfs!)文件系统。

124
Ivan

通常,提高磁盘缓存性能不仅仅只是增加文件系统缓存大小,除非whole系统适合RAM,在这种情况下,您应该使用RAM驱动器(tmpfs很好,因为如果在某些情况下需要[RAM,则允许回退到磁盘)进行运行时存储(也许还有一个initrd脚本,可将系统从存储复制到RAM驱动器启动时)。

您没有告诉您存储设备是SSD还是HDD。这是我发现对我有用的东西(在我的情况下sda是安装在/home的HDD,而sdb是安装在/的SSD)。

首先优化从存储到缓存的加载部分:

这是我的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(通常为写入)和长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_rqslice_async设置为非常低的数字。但是,将slice_async_rq的值设置得太低可能会阻止读取,因为无法在读取之后再延迟写入。我的配置将在数据传递到内核后最多10秒钟后尝试将数据写入磁盘,但是由于您可以忍受掉电造成的数据丢失,因此请将fifo_expire_async设置为3600000可以告诉这1个小时可以延迟磁盘。不过,只需将slice_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_idle,必须将其设置为0-1。将其设置为零会将所有排序决策移至本机NCQ,而将其设置为1则允许内核对请求进行排序(但如果NCQ处于活动状态,则硬件可能会部分覆盖内核排序)。测试两个值以查看是否可以看到差异。对于Intel 320系列,似乎将slide_idle设置为0可以提供最佳吞吐量,但是将其设置为1则可以提供最佳(最低)总体延迟。

有关这些可调参数的更多信息,请参见 https://www.kernel.org/doc/Documentation/block/cfq-iosched.txt

现在我们已经将内核配置为以合理的性能从磁盘加载内容到缓存,现在该调整缓存行为了:

根据我已经完成的基准测试,我根本不会理会通过blockdev进行预读。内核默认设置很好。

将系统设置为优先于应用程序代码交换文件数据(这是否无关紧要,如果您有足够的RAM来保留整个文件系统and所有应用程序代码- and RAM中应用程序分配的所有虚拟内存)。这样可以减少在不同应用程序之间进行交换的等待时间,而不是从单个应用程序访问大文件的等待时间:

echo 15 > /proc/sys/vm/swappiness

如果您希望将应用程序几乎始终保持在RAM中,则可以将其设置为1。如果将其设置为零,除非绝对有必要避免OOM,否则内核将根本不会交换。如果您的内存有限并且要处理大文件(例如HD视频编辑),那么将其设置为接近100可能是有道理的。

如今(2017年),我希望如果有足够的RAM,则完全不进行交换。如果没有交换,则在长时间运行的台式机上通常会丢失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

vfs_cache_pressure设置为较低的值很有意义,因为在大多数情况下,内核需要先了解目录结构,然后才能使用高速缓存中的文件内容,并且过早刷新目录高速缓存将使文件高速缓存几乎一文不值。如果您有很多小文件(我的系统大约有150K 10兆像素的照片并算作“很多小文件”系统),请考虑使用此设置将其降至1。永远不要将其设置为零,否则即使系统内存不足,目录结构也始终保留在内存中。仅当您只需要不断重新读取几个大文件时,将此值设置为大值才有意义(再次,没有足够的[RAM_的高清视频编辑将是一个示例)。官方内核文档说“将vfs_cache_pressure显着增加到100以上可能会对性能造成负面影响”。

例外:如果您拥有大量文件和目录,并且很少触摸/读取/列出所有设置vfs_cache_pressure大于100的文件,明智点吧。仅当您没有足够的RAM且无法将整个目录结构保留在RAM中并且仍然有足够的RAM用于常规文件缓存和进程(例如公司)时,这才适用具有很多存档内容的文件服务器)。如果您认为需要将vfs_cache_pressure增加到100以上,则说明运行时没有足够的RAM。增加vfs_cache_pressure可能会有所帮助,但唯一真正的解决方法是获得更多的RAM。将vfs_cache_pressure设置为高数值会牺牲总体性能,因为它们总体上具有更稳定的性能(也就是说,您可以避免真正糟糕的最坏情况下的行为,但必须处理更差的总体性能)。

最后,在减慢正在写入的进程之前,告诉内核将RAM的99%用作写缓存,并指示内核在RAM的50%的缓存中使用(默认为dirty_background_ratio10)。 警告:我个人不会这样做,但是您声称拥有足够的RAM并愿意丢失数据。

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

并且告诉1h写入延迟是可以的,即使start在磁盘上写入内容(同样,我不会这样做):

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/usr,仅当/home/usr确实适合RAM时才这样做):

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

首先,我不建议您继续使用NTFS,因为在Linux中执行ntfs随时可能会导致性能和安全问题。

您可以执行以下几项操作:

  • 使用一些较新的fs,例如ext4btrfs
  • 尝试更改您的io调度程序,例如bfq
  • 关闭交换
  • 使用一些自动预加载器,例如preload
  • 在启动时使用systemd之类的东西进行预加载
  • ...还有更多

也许您想尝试一下:-)

16
Felix Yan

提前阅读:

在32位系统上:

blockdev --setra 8388607 /dev/sda

在64位系统上:

blockdev --setra 4294967295 /dev/sda

写在缓存后面:

echo 100 > /proc/sys/vm/dirty_ratio

这将最多使用100%的可用内存作为写缓存。

或者,您可以全力以赴并使用tmpfs。仅当您有RAM=。将其放在/etc/fstab。将100G替换为物理RAM的数量。

tmpfs /mnt/tmpfs tmpfs size=100G,rw,nosuid,nodev 0 0

然后:

mkdir /mnt/tmpfs; mount -a

然后使用/ mnt/tmpfs。

8
Ole Tange

您可以使用blockdev --setra sectors /dev/sda1设置预读大小,其中扇区是您想要的512字节扇区的大小。

6
psusi

我的杀手设置非常简单而且非常有效:

echo "2000" > /proc/sys/vm/vfs_cache_pressure

内核文档 中的解释:

vfs_cache_pressure

控制内核回收用于缓存目录和inode对象的内存的趋势。

在默认值vfs_cache_pressure = 100时,内核将尝试以相对于页面缓存和swapcache回收的“合理”速率回收牙科和索引节点。减少vfs_cache_pressure会导致内核倾向于保留dentry和inode缓存。当vfs_cache_pressure = 0时,内核将永远不会由于内存压力而回收内存和索引节点,这很容易导致内存不足的情况。将vfs_cache_pressure增加到100以上会导致内核更喜欢回收牙科和索引节点。

vfs_cache_pressure在2000年导致大多数计算发生在RAM)中,并且磁盘写入非常晚。

2
user55518

与写缓存无关,但与写有关:

  • 对于ext4系统,您可以 完全禁用日记功能

    这将减少任何特定更新的磁盘写入次数,但在意外关闭后可能需要使fsck或更糟,从而使文件系统处于不一致状态。

要阻止磁盘读取触发磁盘写入:

  • 使用 relatimenoatime 选项安装

    读取文件时,通常会更新该文件的“上次访问时间”元数据。 noatime选项将禁用该行为。这样可以减少不必要的磁盘写入,但是您将不再拥有该元数据。一些发行版本(例如Manjaro)已将其作为所有分区的默认设置(可能会延长早期型号SSD的寿命)。

    根据帮助支持确实使用atime的应用程序的启发式方法,relatime较少地更新访问时间。这是Red Hat Enterprise Linux上的默认设置。

其他选项:

  • 在上面的评论中,Mikko分享了使用 nobarrier 选项安装的可能性。但是Ivailo 引用RedHat 谁对此持谨慎态度。您多么想要这额外的3%?
1
joeytwiddle