使用Alibaba Cloud Linux 2镜像的ECS实例中ext4文件系统Buffer I/O写性能不符合预期解决方案
本文介绍了使用Alibaba Cloud Linux 2系统的ECS实例中ext4文件系统的Buffer I/O写性能不符合预期的原因及解决方案。
问题描述
在ext4文件系统中执行常规的缓存异步I/O(Buffer I/O)写操作时,可能会观察到性能表现不符合预期的问题。存在该问题的ECS实例具有以下特征:
镜像:
aliyun-2.1903-x64-20G-alibase-20190327.vhd
(包含)~aliyun_2_1903_x64_20G_alibase_20220525.vhd
(不含)之间的镜像版本。内核:
kernel-4.19.24-9.al7
(包含)~4.19.91-26.al7.x86_64
(不含)之间的内核版本。您可以通过uname -r
命令来查看内核版本。通过
dioread_nolock
和nodelalloc
两个选项挂载ext4文件系统。说明查看块存储性能。
关于如何查看文件系统类型及挂载选项,请参考如下步骤:
满足以上特征的ECS,在进行如下两个数据写入场景时会出现写入性能不符合预期的问题。
场景一:使用cp
命令拷贝大文件
执行以下命令,将大文件拷贝到满足上述特征的ext4
文件系统。
<$LargeFiles>
需替换为您本地的一个大文件。为复现写入性能不符合预期的问题,建议该文件的大小应大于2 GiB。
cp <$LargeFiles> /mnt/badfile
场景二:使用不带同步标志的dd
命令写入文件
执行以下命令,使用不带同步标志的dd
命令写文件到满足上述特征的ext4
文件系统。
dd if=/dev/zero of=/mnt/badfile bs=10M count=1000
在进行以上两个场景操作时,您可以在终端中通过iostat -xm 1
命令观察对应磁盘的写入速度,wMB/s列的值只有30 MB/s左右,远低于ECS的块存储性能。系统显示示例如下所示:
avg-cpu: %user %nice %system %iowait %steal %idle
0.00 0.00 12.77 0.00 0.00 87.23
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
vda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
vdb 0.00 7194.00 0.00 57.00 0.00 28.05 1008.00 0.02 17.81 0.00 17.81 0.39 2.20
问题原因
当文件系统以dioread_nolock
和nodelalloc
组合选项挂载时,产生了大量内核中被称为unwritten extents
、大小为4 KB的脏页(Dirty Page),由于ext4文件系统处理逻辑的缺陷,这些4 KB的脏页并不会被合并成若干个大页再进行写回,而是直接以小页的形式被处理。通过Perf
工具观察内核写回页面缓存的过程,发现处理过程主要发生在ext4
文件系统的ext4_writepages
函数内部,在查找和映射4 KB脏页的逻辑中耗费了大量的时间,从而造成文件写入性能极低。
解决方案
方案一:取消同时使用dioread_nolock
和nodelalloc
挂载ext4文件系统
执行以下命令,重新挂载ext4文件系统,取消同时使用
dioread_nolock
和nodelalloc
的挂载选项组合。<$Device>
需替换为ext4文件系统的设备名。可通过lsblk
命令获取,回显信息中的NAME列即为设备名。<$MountPoint>
需替换为ext4文件系统的挂载点。挂载点可以是已有空目录,或执行sudo mkdir -p <新目录>
命令创建新目录作为挂载点。
sudo mount -o remount,delalloc <$Device> <$MountPoint>
修改
/etc/fstab
文件,删除ext4文件系统的nodelalloc
选项(默认为delalloc
),以确保系统开机自动挂载。
方案二:升级内核版本
升级内核可能会出现兼容性和稳定性问题,建议您查看Alibaba Cloud Linux 2镜像发布记录了解具体内核功能后谨慎进行操作。
重启实例将导致您的实例暂停运行,这可能引发业务中断和数据丢失。因此,建议您在执行此操作之前备份关键数据,并选择在非业务高峰期进行。
执行以下命令,升级内核到最新版本。
sudo yum update kernel
执行以下命令,重启实例使配置生效。
sudo reboot