Linux系统的ECS实例中NVMe磁盘IO超时参数配置不当, 导致NVMe磁盘不可用如何处理?

本文介绍Linux系统的ECS实例中NVMe磁盘IO超时参数配置不当,导致NVMe磁盘不可用时的问题原因及解决方案。

问题描述

Linux系统的ECS实例使用NVMe系统盘后,出现非预期的慢I/O读写,导致系统或者应用程序对于NVMe磁盘的I/O操作失败。NVMe磁盘上的文件系统从原来挂载的可读、写的状态,切换为只读不可写的状态,后续的写操作均失败,从而导致系统和应用程序异常或者业务中断。

说明

慢I/O读写是指在磁盘读写过程中,输入/输出操作的执行速度低于期望或需要的时间。

问题原因

NVMe驱动中的 io_timeout参数控制了最大能够容忍的I/O超时时间,如果I/O读写操作的延迟过高,超过了该参数的配置值,则NVMe驱动会返回I/O失败,可能导致NVMe磁盘上的文件系统从原来挂载的可读、写的状态,切换为只读不可写的状态,后续的写操作均失败,从而导致系统和应用程序异常或者业务中断。

说明
  • 大部分Linux发行版本中io_timeout参数默认配置为30秒。为了减少NVMe磁盘的IO操作超时出现的异常情况,通常需要将 io_timeout参数设置为最大值。在新版本的内核中,io_timeout参数的最大值为4,294,967,295秒,较早版本中为255秒。

  • 不同的版本内核中,NVMe驱动的内核模块也不同,部分内核模块为nvme.ko ,部分内核模块为nvme_core.ko,所以完整的超时参数名称存在nvme.io_timeoutnvme_core.io_timeout两种可能。

解决方案

配置io_timeout参数(临时配置)

您可以通过以下操作临时配置NVMe驱动的io_timeout参数。该方式仅单次生效,重启实例后需要重新配置。

  1. 远程连接ECS实例。

    具体操作,请参见连接方式概述

  2. 检查io_timeout参数所在的内核模块路径。

    • 执行以下命令,检查/sys/module/nvme_core/parameters/io_timeout路径是否存在,如果存在则表示完整的参数名称为nvme_core.io_timeout

      cat /sys/module/nvme_core/parameters/io_timeout
    • 如果不存在以上路径,请执行以下命令,检查/sys/module/nvme/parameters/io_timeout路径是否存在,如果存在则表示完整的参数名称为nvme.io_timeout

       cat /sys/module/nvme/parameters/io_timeout
  3. 执行以下命令,尝试将最大值4,294,967,295写入到内核模块路径。

    内核模块为nvme.ko

    sudo sh -c 'echo 4294967295 > /sys/module/nvme/parameters/io_timeout'

    内核模块为nvme_core.ko

    sudo sh -c 'echo 4294967295 > /sys/module/nvme_core/parameters/io_timeout'
    • 如果写入成功且没有报错,表明写入成功,io_timeout参数的最大值修改为4,294,967,295。

    • 如果出现类似于Numerical result out of range的错误,重新执行该步骤,将io_timeout参数的最大值修改为255。

手动修改GRUB中的内核启动参数(永久配置)

您也可以手动在GRUB中修改io_timeout参数或通过云助手的ecs_nvme_config插件帮助您快速完成操作系统内NVMe相关的配置。具体操作,请参见如何为已有自定义镜像安装NVMe驱动?该方式永久生效,不受实例启动等因素影响。