..
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