解决Linux下SSD写入过高的问题

问题

上周六拷贝磁盘数据顺带看了下用了快一年的970 EVO Plus 500GB,发现了一个不得了的事情。通过smartctl -a /dev/nvme0n1看到读取数据单元为1.51 TB, 写入数据单元为70.9 TB。为何写入会比读取高这么多!

分析

具体看看smartctl返回了些什么

这个磁盘通电7880小时,大概是328天,通断电47次,比较符合实际。机器一般都一直开着,除非遇到更新与断电的情况。那么接下来应该如何查看写入高的问题呢?

这个磁盘平时我在执行业务时并不会进行大的写入,都是日常操作,所以这样分析看来,观察一段时间实际写入的情况会比较有效。于是我打开了iotop,关注持续写入的动作,发现大概有这么两个地方会不断的写入到磁盘

  • etcd基本上每隔几秒钟就会写入大概100KB+的数据
  • jbd2会每隔5s进行写入,数据量与etcd的量类似

经过搜索,jbd2其实是一个内核线程,专门给ext4分区提供已写入脏缓冲数据定期的强制同步写入的服务。这个服务默认的频率是5s一次,与我们的观察类似。而写入的数据,基本就是从etcd产生的。

我们根据已知数据估算下平均写入的IOPS大概是多少。3,360,464,283次写入在7880小时内完成,所以平均一下每秒钟是118次写入。经过搜索etcd典型单连接情况下需要每秒钟50次IO,这么看量级是对的,所以基本可以确定是etcd的问题了。

解决

接下来就比较简单了。看了下etcd的启动和使用者,居然是microk8s,一个我之前安装上用来学习k8s的组件。。。于是果断用snap禁用掉这个microk8s。。。然后使用iotop观察,写入明显降低,仅剩5s一次的jbd2同步写入,但是数据量远小于之前。

延伸

这里提到了jbd2会定时的同步脏缓冲数据到磁盘,默认是5s一次。由于这个盘我平时不经常写入,由于未及时同步导致丢数据的概率不大,所以我这里可以通过延长强制同步的间隔来再次减少写入的频率。这里是通过修改/etc/fstab,在mount options一列加入commit=600,即

然后保存后重启,再次通过iotop查看,jbd2的写入频率也明显降低。本次问题解决。

参考