了解无交换的只读文件系统上的 buff/cache 和 tmpfs 关系

了解无交换的只读文件系统上的 buff/cache 和 tmpfs 关系

我们发现了非常奇怪的错误,在 Raspberry Pi 上运行的 Yocto 操作系统会因为磁盘 IO 等待而“锁定”。

设想:

  • 操作系统以只读方式运行,无交换
  • 有一个 tmpfs 文件系统,用于存放操作系统需要写入的内容(/var、/log 等)
  • tmpfs 默认使用可用 RAM 的一半(2GB)
  • 连接了 USB 硬盘,用于存储大型 MP4 文件

运行与 Google Coral USB 加速器交互的 Python 程序一段时间后,输出如下top

top 命令的输出

因此 CPU 负载很大,但 CPU 使用率却很低。我们认为这是因为它正在等待 USB 硬盘的 IO。

其他时候我们会看到更高的缓存使用率:

Mem: 1622744K used, 289184K free, 93712K shrd, 32848K buff, 1158916K cached
CPU:   0% usr   0% sys   0% nic  24% idle  74% io   0% irq   0% sirq
Load average: 5.00 4.98 4.27 1/251 2645

文件系统看起来很正常:

root@ifu-14:~# df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/root                 3.1G    528.1M      2.4G  18% /
devtmpfs                804.6M      4.0K    804.6M   0% /dev
tmpfs                   933.6M     80.0K    933.5M   0% /dev/shm
tmpfs                   933.6M     48.6M    884.9M   5% /run
tmpfs                   933.6M         0    933.6M   0% /sys/fs/cgroup
tmpfs                   933.6M     48.6M    884.9M   5% /etc/machine-id
tmpfs                   933.6M      1.5M    932.0M   0% /tmp
tmpfs                   933.6M     41.3M    892.3M   4% /var/volatile
tmpfs                   933.6M     41.3M    892.3M   4% /var/spool
tmpfs                   933.6M     41.3M    892.3M   4% /var/lib
tmpfs                   933.6M     41.3M    892.3M   4% /var/cache
/dev/mmcblk0p1           39.9M     28.0M     11.9M  70% /uboot
/dev/mmcblk0p4          968.3M      3.3M    899.0M   0% /data
/dev/mmcblk0p4          968.3M      3.3M    899.0M   0% /etc/hostname
/dev/mmcblk0p4          968.3M      3.3M    899.0M   0% /etc/NetworkManager
/dev/sda1               915.9G     30.9G    838.4G   4% /mnt/sda1

当一切都“锁定”时,我们注意到 USB 硬盘完全没有响应(ls什么也不做,只是冻结)。

在 dmesg 日志中,我们注意到以下几行(粘贴为图像以保留颜色):

dmesg 输出

这是我们开始收到这些错误后 dmesg 的完整输出: https://pastebin.com/W7k4cp35

我们推测,当系统运行的软件尝试对大文件(50MB +)执行某些操作(将其在 USB 硬盘上移动)时,系统会以某种方式耗尽内存。

我们真的不知道该怎么做。我们发现了这个博客:https://www.blackmoreops.com/2014/09/22/linux-kernel-panic-issue-fix-hung_task_timeout_secs-blocked-120-seconds-problem/这看起来像是同样的问题,并建议修改vm.dirty_ratiovm.dirty_background_ratio更频繁地将缓存刷新到磁盘。

这是正确的做法吗?

当前设置vm.dirty_ratio = 20vm.dirty_background_ratio = 10

速度相对较慢的 USB 硬盘是否需要更改此项?有人能解释一下发生了什么吗?

答案1

[sda] tag#0 timing out command, waited 180s
blkupdate_request: I/O error, dev sda1
INFO:  task jbd2/sda1 blocked for more than 122 seconds.

块设备 /dev/sda 出现故障。请更换它并恢复数据。

Linux 的任务阻塞警告是指某项任务在一段时间内没有进展分钟。这对于计算机,甚至存储系统来说都是一个漫长的过程。触发 I/O 问题并不正常。要么是存储出现故障,要么是存在大量争用,要么是某些资源严重匮乏。由于其他消息包含 I/O 错误的证据,因此前者似乎是可能的。

如果存储设备已更换,则该型号可能运行缓慢且不适合此应用程序。请尝试使用高性能 SSD,例如 USB 3 适配器中的 NVMe 或类似产品。

还可以进行综合负载测试,像应用程序一样测试存储,并获取一些性能数据。小型随机写入、长顺序写入,或许是混合。在 Linux 上,菲奥是一个非常灵活的 I/O 测试器。

最后,其他硬件组件也可能出现故障。如果是 Raspberry Pi,请尝试更换整个组件。

答案2

作为对这个问题的更新,这里之前的答案几乎都是正确的。

问题实际上是 Raspberry Pi 4 无法从其 USB 端口提供足够的电力来长时间同时驱动 USB 硬盘和 Google Coral。一段时间后,USB 硬盘开始表现得非常奇怪,如上面的日志所示,这让它看起来像是出现故障了。

切换到 SSD 后问题立即消失。

相关内容