..

linux 系统缓存

linux系统为了增加系统的IO能力,会缓存磁盘的读写操作,将数据缓存在内存中。通过free命令可以看到系统的缓存信息


              总计         已用        空闲      共享    缓冲/缓存    可用
内存:       15894        3817        7196        1120        4880       10747
交换:        9011           0        9011

包含写入缓存和读取缓存两个部分:

缓冲(buff)  : 写缓存
缓存(cache) : 读缓存

buff

因为硬盘写入的速度有限,为了避免程序卡顿和IO等待,有时候写入数据都是被临时写入到了系统内存(也可以强制存盘),然后等到IO不繁忙的时候写入到磁盘,这样的做法也有丢失数据的风险,linux下有手动同步数据到磁盘的命令:

sync

我就被这个问题坑过,在使用dd命令制作启动优盘的时候,一定要等待数据完全刷新到优盘在拔除优盘,否则启动盘会丢失数据,可以给dd命令加上写入磁盘的选项强制要求写入磁盘oflag=sync

sudo dd if=manjaro-xfce-20.0.3-200606-linux56.iso of=/dev/sdb4 bs=4M status=progress oflag=sync

同时,我们写程序的时候,写入文件结束以后记得调用flush来确保文件已经持久化成功。

cache

cache 是从磁盘读取文件时候的缓存,第一次读文件的时候因为内存种没有缓存这个文件,所以去读比较慢,当第二次读取的时候,已经有一部分缓存信息在内存中,这个时候速度会比较快,我们做个测试,读取一个大文件

# 第一次
hellojukay@local ~ $ time cat large_file >> /dev/null

real    0m10.221s
user    0m0.059s
sys     0m2.338s
# 第二次
hellojukay@local ~ $ time cat large_file >> /dev/null

real    0m1.451s
user    0m0.057s
sys     0m1.322s
hellojukay@local ~ $

可以看到第二次读取文件的速度明显加快了

              总计         已用        空闲      共享    缓冲/缓存    可用
内存:       15894        2898       11334         490        1660       12317
交换:        9011           5        9005
# 第一次读取
[local hellojukay]# time cat large_file > /dev/null

real    1m26.948s
user    0m0.492s
sys     0m15.640s
[local hellojukay]# free
              总计         已用        空闲      共享    缓冲/缓存    可用
内存:       15894        2761        4618         490        8514       12454
交换:        9011           5        9005
# 第二次读取
[local hellojukay]# time cat large_file > /dev/null

real    0m1.215s
user    0m0.030s
sys     0m1.184s
# 释放缓存
[local hellojukay]#  echo 1 > /proc/sys/vm/drop_caches
# 第三次读取
[local hellojukay]# time cat large_file > /dev/null

real    1m28.599s
user    0m0.490s
sys     0m14.677s
# 第四次读取
[local hellojukay]# time cat large_file > /dev/null

real    0m1.225s
user    0m0.067s
sys     0m1.157s

可以看到第一次读取会自动缓存数据,后面再次读取速度就会加速,如果清理缓存以后,速度又会变慢。

缓存带来的问题

对于文件服务器或者代理服务来说可能会缓存数据比较量比较大,缓存占用了内存,导致系统的某些应用无法申请内存,造成OOM,解决这个问题有2种方式清理缓存

  • 配置 swap
  • 清理缓存

swap

当内存不够用的时候,系统会将缓存中的数据移动到 swap 中,释放出可用内存。

mkswap /dev/hda4 # 设置分为 swap 分区
swapon /dev/hda4 # 开启 swap

设置 swap 的大小也比较讲究,太小或者太大都不合适。

清理缓存

可以通过向系统内核写入配置来清理缓存

# 清理 cache
echo 1 > /proc/sys/vm/drop_caches
# 清理 buff
echo 2 > /proc/sys/vm/drop_caches
# 清理 cache 和 buff
echo 3 > /proc/sys/vm/drop_caches