美文网首页
【Linux】Linux Page Cache

【Linux】Linux Page Cache

作者: Bogon | 来源:发表于2023-05-03 14:33 被阅读0次

    1、什么是Page Cache?

    Page Cache是针对文件系统的缓存,通过将磁盘中的文件数据缓存到内存中,从而减少磁盘I/O操作提高性能。

    对磁盘的数据进行缓存从而提高性能主要是基于两个因素:

    1. 磁盘访问的速度比内存慢好几个数量级(毫秒和纳秒的差距);

    2. 被访问过的数据,有很大概率会被再次访问。

    文件读写流程如下所示:


    image.png

    2、读Cache

    当内核发起一个读请求时(例如进程发起read()请求),首先会检查请求的数据是否缓存到了Page Cache中。

    如果有,那么直接从内存中读取,不需要访问磁盘,这被称为cache命中(cache hit);

    如果cache中没有请求的数据,即cache未命中(cache miss),就必须从磁盘中读取数据。然后内核将读取的数据缓存到cache中,这样后续的读请求就可以命中cache了。

    page可以只缓存一个文件部分的内容,不需要把整个文件都缓存进来。

    3、写Cache

    当内核发起一个写请求时(例如进程发起write()请求),同样是直接往cache中写入,后备存储中的内容不会直接更新(当服务器出现断电关机时,存在数据丢失风险)。

    内核会将被写入的page标记为dirty,并将其加入dirty list中。内核会周期性地将dirty list中的page写回到磁盘上,从而使磁盘上的数据和内存中缓存的数据一致。

    当满足以下两个条件之一将触发脏数据刷新到磁盘操作:

    1. 数据存在的时间超过了dirty_expire_centisecs(默认300厘秒,即30秒)时间;

    2. 脏数据所占内存 > dirty_background_ratio,也就是说当脏数据所占用的内存占总内存的比例超过dirty_background_ratio(默认10,即系统内存的10%)的时候会触发pdflush刷新脏数据。

    4、Page Cache缓存查看工具

    我们如何查看缓存命中率呢?在这里我们可以借助一个缓存命中率查看工具 cachestat。

    (1)下载安装

    #  mkdir /opt/bigdata/app/cachestat
    #  cd  /opt/bigdata/app/cachestat
    #  git clone --depth 1 https://github.com/brendangregg/perf-tools
    

    (2)启动执行


    image.png

    (3)输出内容说明

    image.png

    5、如何回收Page Cache

    # root 用户执行
    sync && echo 1 > /proc/sys/vm/drop_caches
    sync && echo 2 > /proc/sys/vm/drop_caches
    sync && echo 3 > /proc/sys/vm/drop_caches
    
    image.png

    这三个命令都是用于清空Linux系统中的缓存,以便释放内存空间。

    Linux上的sync命令是用来将文件系统中的数据同步到磁盘中,确保数据的持久化存储,避免数据丢失或损坏。

    当我们对文件系统进行修改时,数据并不是实时写入磁盘的,而是先缓存在内存中,等到一定时间或缓存空间满了再写入磁盘。但是如果在这个过程中系统崩溃了,这些缓存中的数据就会丢失,导致文件系统的不一致性或数据的损坏。因此,使用sync命令可以将缓存中的数据立即写入磁盘,保证数据的安全性。

    sync命令的使用非常简单,只需要在命令行中输入“sync”即可。
    在大多数情况下,我们不需要手动使用sync命令,因为Linux系统会自动定期执行sync操作,确保数据的安全性。但是在一些特殊情况下,比如在进行重要文件的修改或备份操作时,可以手动执行sync命令,以确保数据的及时保存。

    第一个命令“sync && echo 1 > /proc/sys/vm/drop_caches”表示先执行sync命令,将所有缓存数据写入磁盘中,然后将“1”写入到/proc/sys/vm/drop_caches文件中,表示清空页缓存。

    第二个命令“sync && echo 2 > /proc/sys/vm/drop_caches”表示先执行sync命令,将所有缓存数据写入磁盘中,然后将“2”写入到/proc/sys/vm/drop_caches文件中,表示清空目录缓存和页缓存。

    第三个命令“sync && echo 3 > /proc/sys/vm/drop_caches”表示先执行sync命令,将所有缓存数据写入磁盘中,然后将“3”写入到/proc/sys/vm/drop_caches文件中,表示清空目录缓存、页缓存和inode缓存。

    需要注意的是,这些命令可能会导致系统变慢,因为它们会强制清空缓存,而下次读取相同的数据时需要重新加载到缓存中,会消耗更多的时间和资源。因此,建议在必要时才使用这些命令。

    6. 调优参数

    注:不同硬件配置的服务器可能效果不同,所以,具体的参数值设置需要考虑自己集群硬件配置。
    考虑的因素主要包括:CPU核数、内存大小、硬盘类型、网络带宽等。

    6.1 、如何查看Page Cache参数

    #  sysctl -a | grep dirty 
    
    image.png
    vm.dirty_background_ratio = 10
    
    
    # 和参数vm.dirty_background_ratio实现相同功能,但两个参数只会有其中一个生效,表示脏页大小达到多少字节后开始触发刷磁盘
    vm.dirty_background_bytes = 0 
    
    
    
    vm.dirty_ratio = 20
    
    # 和参数vm.dirty_ratio实现相同功能,但两个参数只会有其中一个生效,表示脏页达到多少字节后停止接收写请求,开始触发刷磁盘
    vm.dirty_bytes = 0 
    
    
    #这里表示30秒(时间单位:厘秒)
    vm.dirty_expire_centisecs = 3000 
    
    #这里表示5秒(时间单位:厘秒)
    vm.dirty_writeback_centisecs = 500 
    
    

    Linux Page Cache 调优参数包括:

    1. vm.dirty_ratio:表示内存中脏页占总内存的比例阈值。当脏页占用内存超过该阈值时,系统会开始写回脏页到磁盘。默认值为 20%,可以根据实际情况进行调整。

    2. vm.dirty_background_ratio:表示内存中脏页占总内存的后台写入比例阈值。当脏页占用内存超过该阈值时,系统会后台写回脏页到磁盘。默认值为 10%,可以根据实际情况进行调整。

    3. vm.dirty_expire_centisecs:表示脏页在内存中的最长停留时间,单位为毫秒。当脏页在内存中停留时间超过该值时,系统会将其写回到磁盘。默认值为 3000(即 30 秒),可以根据实际情况进行调整。

    4. vm.dirty_writeback_centisecs:表示脏页写回到磁盘的时间间隔,单位为毫秒。系统会每隔该时间间隔将一部分脏页写回到磁盘。默认值为 500(即 5 秒),可以根据实际情况进行调整。

    5. vm.swappiness:表示系统倾向于使用交换空间的程度。取值范围为 0 到 100,值越大表示系统越倾向于使用交换空间。默认值为 60,可以根据实际情况进行调整。

    这些参数的调整可以根据实际情况进行优化,以提高系统性能和稳定性。
    例如,可以根据系统的内存大小和负载情况,调整脏页占用内存的比例阈值,以避免内存耗尽导致系统崩溃。
    同时,可以调整脏页写回到磁盘的时间间隔,以避免频繁的磁盘写入影响系统性能。

    6.3、如果系统中cached大量数据可能存在的问题

    缓存的数据越多,丢数据的风险越大;

    会定期出现IO峰值,这个峰值时间会较长,在这期间所有新的写IO性能会很差(极端情况直接被hang住)。

    后一个问题对写负载很高的应用会产生很大影响。

    6.4、如何调整内核参数来优化IO性能?

    (1)vm.dirty_background_ratio参数优化

    当cached中缓存当数据占总内存的比例达到这个参数设定的值时将触发刷磁盘操作。

    把这个参数适当调小,这样可以把原来一个大的IO刷盘操作变为多个小的IO刷盘操作,从而把IO写峰值削平。

    对于内存很大和磁盘性能比较差的服务器,应该把这个值设置的小一点。

    #设置方法1:
    sysctl -w vm.dirty_background_ratio=1(临时生效,重启服务器后失效)
     
    #设置方法2(永久生效):
    echo vm.dirty_background_ratio=1 >> /etc/sysctl.conf
    sysctl -p /etc/sysctl.conf
     
    #设置方法3(永久生效):
    #当然你还可以在/etc/sysctl.d/目录下创建一个自己的参数优化文件,把系统优化参数进行归类存放,然后设置生效,如:
    touch /etc/sysctl.d/kafka-optimization.conf
    echo vm.dirty_background_ratio=1 >> /etc/sysctl.d/kafka-optimization.conf
    sysctl --system
    

    (2)vm.dirty_ratio参数优化

    对于写压力特别大的,建议把这个参数适当调大;
    对于写压力小的可以适当调小;

    如果cached的数据所占比例(这里是占总内存的比例)超过这个设置,系统会停止所有的应用层的IO写操作,等待刷完数据后恢复IO。所以万一触发了系统的这个操作,对于用户来说影响非常大的。

    (3)vm.dirty_expire_centisecs参数优化

    这个参数会和参数vm.dirty_background_ratio一起来作用,一个表示大小比例,一个表示时间;
    即满足其中任何一个的条件都达到刷盘的条件。

    为什么要这么设计呢?
    我们来试想一下以下场景:

    • 如果只有参数 vm.dirty_background_ratio ,也就是说cache中的数据需要超过这个阀值才会满足刷磁盘的条件;

    • 如果数据一直没有达到这个阀值,那相当于cache中的数据就永远无法持久化到磁盘,这种情况下,一旦服务器重启,那么cache中的数据必然丢失。

    结合以上情况,所以添加了一个数据过期时间参数。
    当数据量没有达到阀值,但是达到了我们设定的过期时间,同样可以实现数据刷盘。

    这样可以有效的解决上述存在的问题,其实这种设计在绝大部分框架中都有。

    (4)vm.dirty_writeback_centisecs参数优化

    理论上调小这个参数,可以提高刷磁盘的频率,从而尽快把脏数据刷新到磁盘上,但一定要保证间隔时间内一定可以让数据刷盘完成!

    (5)vm.swappiness参数优化

    禁用swap空间,设置vm.swappiness=0

    在 Linux 上将 vm.swappiness 设置为 0 并不能完全禁止使用 swap。
    vm.swappiness 参数是用来控制系统在内存不足时使用交换空间的程度,取值范围为 0 到 100,值越大表示系统越倾向于使用交换空间,值为 0 时表示系统不使用交换空间。但是,即使将 vm.swappiness 设置为 0,Linux 系统仍然会使用交换空间来满足特定的需求,例如:

    1. 内核需要在交换空间中存储一些不活跃的进程或页面,以腾出内存供其他进程使用。

    2. 内核需要在交换空间中存储一些内存映射文件,以避免内存耗尽。

    3. 内核需要在交换空间中存储一些内存缓存或页面,以避免系统崩溃。

    因此,将 vm.swappiness 设置为 0 只能减少系统使用交换空间的程度,而不能完全禁止使用交换空间。
    如果要完全禁止使用交换空间,可以通过禁用交换分区或卸载交换文件系统来实现。

    参考

    Linux Page Cache调优在Kafka中的应用
    https://zhuanlan.zhihu.com/p/190983603

    相关文章

      网友评论

          本文标题:【Linux】Linux Page Cache

          本文链接:https://www.haomeiwen.com/subject/plctsdtx.html