聊聊linux的文件缓存

本文主要研究一下linux的文件缓存

文件缓存

linux使用page cache来缓存最近读取的文件,也有目录结构(dcache: Directory Entry Cache)缓存及inode缓存,它们都使用了LRU算法来管理这些page及dentries cache

vmstat

复制代码
## vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0 5076692 1664208   1032 35263320    0    0     0     4    0    0  0  0 99  0  0

vmstat显示的memory中的cache部分即是文件缓存,单位为kb

free

复制代码
free -m
              total        used        free      shared  buff/cache   available
Mem:          64038       27974        1619        3208       34444       32370
Swap:         32127        4957       27170

free命令显示的buff/cache部分包含了buffer memory及swap cache

meminfo

复制代码
cat /proc/meminfo | grep ^Cached
Cached:          2942600 kB

/proc/meminfo中的Cached展示了page cache大小

配置

/etc/sysctl.conf包含我们可以在运行时设置的系统范围内的内核参数,sysctl只是临时改动,如果用使得参数变更持久化则需要更改到这个文件。要在不重新启动的情况下应用/etc/sysctl.conf文件中的更改,我们可以使用sysctl的-p开关

复制代码
sudo sysctl -p

vm.vfs_cache_pressure

vm.vfs_cache_pressure用来控制内核回收page与dentries(dcache及inode cache)的倾向性。

  • 默认值100,即内核自己根据情况将二者在一个合理的比例
  • 较低的值(低于100)则使其倾向于回收page cache,来保留dentries cache。
  • 较高的值(高于100)会使内核更倾向于回收dentries cache,来保留page cache。

如下设置则让内核倾向于回收page cache

复制代码
sudo sysctl -w vm.vfs_cache_pressure=50

vm.swappiness

用于控制使用swap分区的倾向性

  • 默认值为60,意味着内核会在RAM使用率达到60%(可用RAM低于40%)时开始使用swap分区
  • 较低的值则倾向使用RAM,尽量少使用swap分区,比如0则表示内核在RAM(Random Access Memory)严重不足时才使用swap分区,即page cache尽可能得缓存在了RAM
  • 较高的值则倾向使用swap分区,比如100则表示内核非常积极使用swap分区,即使还有比较多的RAM可用,即page cache更多的是在swap分区

如下设置则让内核尽可能使用RAM

复制代码
sudo sysctl -w vm.swappiness=10

vm.dirty相关参数

复制代码
sysctl -a | grep dirty
vm.dirty_background_ratio = 10
vm.dirty_background_bytes = 0
vm.dirty_ratio = 20
vm.dirty_bytes = 0
vm.dirty_expire_centisecs = 3000
vm.dirty_writeback_centisecs = 500

这些参数用于控制脏数据(已经被修改但是未写入到硬盘)何时写入硬盘

如果我们用_bytes设置vm.的值,则vm. _ratio变量将变为0,反之亦然

除了通过sysctl -a,也可以通过cat /proc/sys/vm/dirty_background_ratio这样子来查看

vm.dirty_background_ratio与vm.dirty_background_bytes

用于设置内存中可以存储脏数据的最大数量。例如,如果你的系统有32GB的内存,并且vm.dirty_background_ratio设置为10,那么最多可以有3.2GB的脏数据存储在内存中,超过这个数值后,就会触发脏数据的写入操作;而vm.dirty_background_bytes则是指定了绝对值,单位bytes

复制代码
sudo sysctl -w vm.dirty_background_ratio=10
sudo sysctl -w vm.dirty_background_bytes=511870912

vm.dirty_ratio与vm.dirty_bytes

用来设置整个系统可以存储脏数据的最大数量的。例如,如果你的系统有32GB的内存,并且vm.dirty_ratio设置为20,那么最多可以有6.4GB的脏数据存储在整个系统中,超过这个数值后,就会触发脏数据的写入操作;而vm.dirty_bytes则是指定了绝对值,单位bytes;与vm.dirty_background_ratio的区别在于当系统到达此点时,必须将所有脏数据提交到磁盘,同时所有新的I/O块都会被阻塞,直到脏数据被写入磁盘

复制代码
sudo sysctl -w vm.dirty_ratio=20
sudo sysctl -w vm.dirty_bytes=511870912

vm.dirty_writeback_centisecs与vm.dirty_expire_centisecs

在断电的情况下,缓存在系统内存中的数据有丢失的风险。因此,为了保护系统免于数据丢失_centisecs系列的参数决定了将数据写入辅助存储的时间和频率。

vm.dirty_expire_centisecs管理数据在写入驱动器之前在缓存中可以存活多长时间。

如下设置可以在缓存中保留40秒,1s等于100 centisecs,当pdflush/flush/kdmflush在运行的时候,他们会检查是否有数据超过这个时限,如果有则会把它异步地写到磁盘中

复制代码
sudo sysctl -w vm.dirty_expire_centisecs=4000

vm.dirty_writeback_centisecs是后台进程检查是否有数据要写入辅助存储的频率,即指定多长时间pdflush/flush/kdmflush这些进程会唤醒一次,然后检查是否有缓存需要清理。该值越低,频率越高。

如下配置为每5秒检查一次缓存

复制代码
sudo sysctl -w vm.dirty_writeback_centisecs=500

删除cache

我们可以通过往/proc/sys/vm/drop_caches写入指定的值来指定怎么删除cache

删除示例

复制代码
# 查看当前的drop_caches值
cat /proc/sys/vm/drop_caches

# 将drop_caches值设置为1,释放页缓存
echo 1 > /proc/sys/vm/drop_caches

# 将drop_caches值设置为2,释放目录项和节点缓存
echo 2 > /proc/sys/vm/drop_caches

# 将drop_caches值设置为3,释放页缓存、目录项和节点缓存
echo 3 > /proc/sys/vm/drop_caches

这是一个非破坏性的操作,并且不会释放脏对象的内存。因此,在进行此操作前,需要先运行sync命令,确保所有未写的系统缓冲区都已经被写入到磁盘中,包括已修改的i节点、已延迟的块I/O和读写映射文件

删除失败

vmtouch可以将文件内容锁定在内存中,因而drop cache可能没有效果,比如

复制代码
vmtouch -tl test.dat
LOCKED 492712 pages (1G)

cat /proc/meminfo | grep ^Cached &&
sudo bash -c 'sync; echo 3 > /proc/sys/vm/drop_caches' &&
cat /proc/meminfo | grep ^Cached

Cached:          3336092 kB
Cached:          3169224 kB

可以看到这里无法释放锁定的cache,可以通过memlock来限定每个进程最大锁定的大小(/etc/security/limits.conf)
配置

复制代码
*                hard    memlock     unlimited
*                soft    memlock     unlimited

查看

复制代码
ulimit -Ha | grep locked
max locked memory           (kbytes, -l) 2033684

小结

linux使用page cache来缓存最近读取的文件,也有目录结构(dcacheDirectory Entry Cache)缓存及inode缓存,它们都使用了LRU算法来管理这些page及dentries cache

  • 可以通过vmstat、free、/proc/meminfo来查看
  • 可以通过vm.vfs_cache_pressure、vm.swappiness、vm.dirty_*来配置
  • 可以通过设置/proc/sys/vm/drop_caches的值来进行删除

doc

相关推荐
XH华11 分钟前
Linux系统第二章:常见的Linux指令(上)
linux·运维·服务器
FoldWinCard10 小时前
D5 Linux 网络及端口命令
linux·运维·服务器
零涂毕业设计11 小时前
毕业设计模块开发-OLED显示屏(IIC协议0.96寸)STM32 ESP32 FPGA Linux驱动免费分享
linux·stm32·单片机·嵌入式·esp32·fpga·oled
落落Plus11 小时前
浏览器缓存机制详解
javascript·缓存·浏览器缓存
tedcloud12312 小时前
OmniRoute怎么部署?开源AI模型路由平台Linux部署教程
linux·服务器·人工智能·开源·音视频
霸道流氓气质12 小时前
KMS 密钥管理服务(Key Management Service)原理与实践
linux·服务器·数据库
SakitamaX12 小时前
LVS(Linux Virtual Server)概念详解
linux·运维·lvs
小张同学a.12 小时前
Linux系统管理
linux·运维
阿龙的工作记录13 小时前
深入理解Linux设备驱动模型
linux·嵌入式硬件·工作记录
代码村新手13 小时前
Linux的基本指令
linux·运维·服务器