• 聊聊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
    
    • 1
    • 2
    • 3
    • 4

    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
    
    • 1
    • 2
    • 3
    • 4

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

    meminfo

    cat /proc/meminfo | grep ^Cached
    Cached:          2942600 kB
    
    • 1
    • 2

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

    配置

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

    sudo sysctl -p
    
    • 1

    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
    
    • 1

    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
    
    • 1

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    这些参数用于控制脏数据(已经被修改但是未写入到硬盘)何时写入硬盘
    如果我们用_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
    
    • 1
    • 2

    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
    
    • 1
    • 2

    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
    
    • 1

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

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

    sudo sysctl -w vm.dirty_writeback_centisecs=500
    
    • 1

    删除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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    这是一个非破坏性的操作,并且不会释放脏对象的内存。因此,在进行此操作前,需要先运行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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

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

    配置

    *                hard    memlock     unlimited
    *                soft    memlock     unlimited
    
    • 1
    • 2

    查看

    ulimit -Ha | grep locked
    max locked memory           (kbytes, -l) 2033684
    
    • 1
    • 2

    小结

    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

  • 相关阅读:
    打印日志遇到的问题,logback与zookeeper冲突
    win10+RTX3050ti+TensorFlow+cudn+cudnn配置深度学习环境
    Java集合(Collection List Set Map)
    ALV细节再梳理2022.8.5
    【校招VIP】测试方案之测试需求分析
    数据库数据恢复-SQL SERVER数据库分区被格式化的数据恢复方案
    WTG Windows系统安装到U盘/移动硬盘
    分享8款人声分离的软件,总有一款你喜欢的
    Kotlin学习笔记-Kotlin基础-01
    P1966 [NOIP2013 提高组] 火柴排队
  • 原文地址:https://blog.csdn.net/hello_ejb3/article/details/137866849