通常,提高磁盘缓存性能不只是增加文件系统缓存大小,除非整个系统都适合RAM,在这种情况下,您应该使用RAM驱动器(tmpfs
这很好,因为在某些情况下,如果需要RAM,它可以回退到磁盘)用于运行时存储(可能还有一个initrd脚本,用于在启动时将系统从存储复制到RAM驱动器)。
您没有告诉您存储设备是SSD还是HDD。这是我发现对我有用的东西(在我的情况下sda
是HDD安装在/home
,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
)毫秒(如果我正确理解了内核的行为)。异步方式主要用于写入,因为你愿意推迟写入磁盘,同时设置slice_async_rq
和slice_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
提供最佳(最低)总体延迟。
有关这些可调参数的更多信息,请参见http://www.linux-mag.com/id/7572/。
既然我们已经配置了内核,以合理的性能将内容从磁盘加载到缓存,那么该调整缓存行为了:
根据我已经完成的基准测试,我根本不会打扰任何预先设置的情况blockdev
。内核默认设置很好。
将系统设置为优先于交换文件数据而不是应用程序代码(如果您有足够的RAM来保持整个文件系统以及所有应用程序代码和应用程序分配的所有虚拟内存在RAM中,这无关紧要)。这样可以减少在不同应用程序之间交换的延迟,而不是从单个应用程序访问大文件的延迟:
echo 15 > /proc/sys/vm/swappiness
如果您希望将应用程序几乎总是保留在RAM中,则可以将其设置为1。如果将其设置为零,除非绝对有必要避免OOM,否则内核将根本不会交换。如果您的内存有限并且要处理大文件(例如,高清视频编辑),那么将其设置为接近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的文件,则可能是明智的。仅当您没有足够的RAM且无法将整个目录结构保留在RAM中并且仍然有足够的RAM用于常规文件缓存和进程(例如,具有大量存档内容的公司范围内的文件服务器)时,这才适用。如果您觉得需要增加到vfs_cache_pressure
100以上,则说明运行时没有足够的RAM。增加vfs_cache_pressure
可能会有所帮助,但唯一真正的解决方法是获得更多的RAM。已经vfs_cache_pressure
设置为高数平均牺牲性能为整体具有更稳定的性能(即,你能避免非常糟糕的最坏情况的行为,但不得不面对较差总体性能)。
最后告诉内核放缓是的写作过程之前,使用最多的RAM作为高速缓存写入,99%和指示内核使用最多的RAM 50%(默认为dirty_background_ratio
是10
)。警告:我个人不会这样做,但是您声称有足够的RAM并且愿意丢失数据。
echo 99 > /proc/sys/vm/dirty_ratio
echo 50 > /proc/sys/vm/dirty_background_ratio
并告诉您1h的写延迟甚至可以开始在磁盘上写东西(再次,我不会这样做):
echo 360000 > /proc/sys/vm/dirty_expire_centisecs
echo 360000 > /proc/sys/vm/dirty_writeback_centisecs
如果将所有这些放在/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)&