Alibaba Cloud Linux 2系统的ECS实例中Ext4文件系统的Buffer I/O写性能不及预期

Alibaba Cloud Linux 2系统的ECS实例中Ext4文件系统的Buffer I/O写性能不及预期

更新时间:2020-08-28 09:47:07

免责声明: 本文档可能包含第三方产品信息,该信息仅供参考。阿里云对第三方产品的性能、可靠性以及操作可能带来的潜在影响,不做任何暗示或其他形式的承诺。

问题描述

在Ext4文件系统中执行常规的缓存异步I/O(Buffer I/O)写操作时,可能会观察到性能表现不符合预期的情形。存在该问题的ECS实例有以下特征:

  • 镜像:aliyun-2.1903-x64-20G-alibase-20190327.vhd及之后所有的镜像版本。
  • 内核:kernel-4.19.24-9.al7及之后所有的内核版本。
  • 通过dioread_nolocknodelalloc两个选项挂载Ext4的文件系统。
    说明:关于如何查看文件系统类型及挂载选项,请参见更多信息

验证性能表现不符合预期的典型场景如下:

说明:关于ECS块存储的性能,请参见块存储性能

  • 场景一:使用cp命令拷贝大文件到Ext4的文件系统中,耗时很久,每秒拷贝速度只能达到30MB/s左右。
  • 场景二:使用类似如下不带同步标志(Sync Flag)的dd命令写文件到Ext4的文件系统中,耗时很久。
    dd if=/dev/zero of=/mnt/badfile bs=10M count=1000
    且在额外的终端中通过iostat -xm 1命令观察对应磁盘的写入速度时,wMB/s列的值只有30MB/s左右。系统显示类似如下。
    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

问题原因

cp命令和不带同步标志(Sync Flag)的dd命令均采用异步缓存I/O写入的方式,对文件进行写入。文件写入到文件系统时,会经过以下两个步骤:

  1. 页面缓存(Page Cache)写入暂存。由于写入操作只进行到内存层面,其写入速度极快,该步骤不存在问题。
  2. 页面缓存写回到文件系统。该步骤出现异常。

从文件系统代码层面分析,该问题的根本原因是当文件系统以dioread_nolocknodelalloc组合选项挂载时,产生了大量内核中被称为“unwritten extents”、大小为4KB的脏页(Dirty Page);由于Ext4文件系统处理逻辑的缺陷,这些4KB的脏页在写回的时候并不会被合并成若干个大页进行写回,而是直接以小页的形式被处理。从Perf工具观察内核写回页面缓存的过程,发现处理过程主要发生在Ext4文件系统的ext4_writepages()函数内部,在查找和映射4K脏页的逻辑中耗费了大量的时间,从而造成文件写入性能极低。

解决方案

阿里云提醒您:

  • 如果您对实例或数据有修改、变更等风险操作,务必注意实例的容灾、容错能力,确保数据安全。
  • 如果您对实例(包括但不限于ECS、RDS)等进行配置与数据修改,建议提前创建快照或开启RDS日志备份等功能。
  • 如果您在阿里云平台授权或者提交过登录账号、密码等安全信息,建议您及时修改。

该问题为Ext4社区已知问题,暂无固化解决方案。您可以参考以下步骤临时解决此问题:

  1. 参考以下命令,重新挂载Ext4文件系统,取消同时使用dioread_nolocknodelalloc的挂载选项组合。
    sudo mount -o remount,delalloc [$Device] [$Mount_Ponit]
    说明
    • [$Device]:指挂载Ext4文件系统的设备名。
    • [$Mount_Ponit]:指Ext4文件系统的挂载点。
  2. 修改/etc/fstab文件,删除Ext4文件系统的nodelalloc选项(默认为delalloc),以确保系统开机自动挂载。

更多信息

检查目录所在磁盘的文件系统类型及挂载选项,参考步骤如下:

  1. 登录ECS实例,参考以下命令,确认目录所在的磁盘分区。
    df [$DIR] | grep -v Filesystem | awk '{ print $1 }'
    说明:[$DIR]指写操作的目标目录。
  2. 参考以下命令,检查目标磁盘分区的文件系统类型以及挂载选项。
    mount | grep -w [$Partition] | grep ext4 | grep -w dioread_nolock | grep -w nodelalloc
    说明:[$Partition]指上一步获取的磁盘分区名。

适用于

  • 云服务器ECS

如果您的问题仍未解决,您可以在阿里云社区免费咨询,或提交工单联系阿里云技术支持。