本文介绍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_timeout
和nvme_core.io_timeout
两种可能。
解决方案
配置io_timeout
参数(临时配置)
您可以通过以下操作临时配置NVMe驱动的io_timeout
参数。该方式仅单次生效,重启实例后需要重新配置。
远程连接ECS实例。
具体操作,请参见连接方式概述。
检查
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
执行以下命令,尝试将最大值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驱动?该方式永久生效,不受实例启动等因素影响。