文档

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

更新时间:

问题描述

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

问题原因

造成该问题的原因如下:

  • 受多种原因影响,读写NVMe磁盘的IO操作可能会出现较大的延迟。NVMe驱动中的 io_timeout参数控制了最大能够容忍的IO超时时间,在大部分Linux发行版本中默认配置为30秒。如果IO读写操作的延迟过高,超过了该参数的配置值,则NVMe驱动会返回IO失败。在特定情况下,系统或者应用程序可以对IO操作进行重试。但在某些情况下,可能导致NVMe磁盘上的文件系统从原来挂载的可读、写的状态,切换为只读不可写的状态,后续的写操作均失败,从而导致系统和应用程序异常或者业务中断。

  • 为了减少NVMe磁盘的IO操作超时出现的异常情况,通常会将 io_timeout参数设置为可能的最大值,提高对于IO延迟的容忍度。在新版本的内核中,io_timeout参数的最大值为4,294,967,295,较早版本中为255。不同的版本的内核中,NVMe驱动的内核模块也有所不同,部分内核模块为nvme.ko ,或者部分内核模块为nvme_core.ko,从而完整的参数名称也存在nvme.io_timeoutnvme_core.io_timeout两种可能。

  • 阿里云的NVMe磁盘的Linux系统镜像中均已进行该配置,详情请参见Linux自定义镜像如何适配NVMe系统盘。如果设置被修改或者没有配置该项,就有可能出现上述问题。

您可以通过执行以下命令,查看NVMe驱动中的IO超时参数io_timeout是否为默认的30秒。

cat /sys/module/nvme_core/parameters/io_timeout

内核版本较低的Linux发行版本,NVMe驱动的内核模块只有nvme.ko而没有nvme_core.ko,可通过执行以下命令,查看NVMe驱动中的IO超时参数io_timeout是否为默认的30秒。

cat /sys/module/nvme/parameters/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. 检查io_timeout参数是否可以接受4,294,967,295的最大值。执行以下命令,尝试将最大值写入到上述步骤获取的路径。

     echo 4294967295 > /sys/module/nvme_core/parameters/io_timeout

    如果写入成功且没有报错,表明写入成功,其最大值为4,294,967,295。若出现类似于Numerical result out of range的错误,请使用255作为最大值,重新执行该步骤。

固化配置手动修改GRUB中的内核启动参数

Linux系统存在不同的发行版本,不同发行版本中修改GRUB中的内核启动参数方法不同,请根据现场环境匹配下列发行版本的操作命令。

CentOS

  1. 远程连接CentOS实例。

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

  2. 执行以下命令,查看系统内核是否已经加载了NVMe驱动。

    cat /boot/config-`uname -r` | grep -i nvme | grep -v "^#"

    系统显示类似如下,如果存在CONFIG_BLK_DEV_NVME=y,则表示该镜像已经加载NVMe驱动。

    CONFIG_NVME_CORE=m
    CONFIG_BLK_DEV_NVME=m
    CONFIG_NVME_MULTIPATH=y
    CONFIG_NVME_FABRICS=m
    CONFIG_NVME_RDMA=m
    CONFIG_NVME_FC=m
    CONFIG_NVME_TCP=m
    CONFIG_NVME_TARGET=m
    CONFIG_NVME_TARGET_LOOP=m
    CONFIG_NVME_TARGET_RDMA=m
    CONFIG_NVME_TARGET_FC=m
    CONFIG_NVME_TARGET_FCLOOP=m
    CONFIG_NVME_TARGET_TCP=m
    CONFIG_RTC_NVMEM=y
    CONFIG_NVMEM=y
  3. 在GRUB中添加NVMe相关的nvme timeout参数。

    1. 执行以下命令,打开grub文件。

      vi /etc/default/grub
    2. i键进入编辑模式,请参见临时配置io_timeout参数的值,确认io_timeout参数的完整参数名称和所能接受的最大值。例如,完整参数名称为nvme_core.io_timeout,所能接受的最大值为 4,294,967,295。则请在GRUB_CMDLINE_LINUX=一行中,添加nvme_core.io_timeout=4294967295 nvme_core.admin_timeout=4294967295参数信息。 添加参数后,文件内容如下图所示:

      Dingtalk_20220420172859.jpg
    3. Esc键退出编辑模式,输入:wq并按Enter键,保存退出文件。

    4. 根据操作系统的启动方式不同,执行以下适用于您的操作系统的命令,使配置的GRUB生效:

      • Legacy启动方式

        grub2-mkconfig -o /boot/grub2/grub.cfg
      • UEFI启动方式

        grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg
    5. 执行以下命令,重启实例,使配置生效。

      reboot
    6. 执行以下命令,确认相关配置已正确传递给内核。

       cat /proc/cmdline

      系统显示类似如下。

      ... nvme_core.io_timeout=4294967295 nvme_core.admin_timeout=4294967295

    7. 执行以下命令,确认NVMe驱动参数已正确配置IO超时参数。

      cat /sys/module/nvme_core/parameters/io_timeout

      系统显示类似如下。

      4294967295

Debian

  1. 远程连接Debian实例。

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

  2. 执行以下命令,查看initrd中包含的NVMe驱动。

    lsinitramfs /boot/initrd.img-`uname -r` | grep -i nvme

    系统显示类似如下信息。 默认Debian操作系统的initrd中已经加载了NVMe驱动。

    usr/lib/modules/4.19.0-18-amd64/kernel/drivers/nvme
    usr/lib/modules/4.19.0-18-amd64/kernel/drivers/nvme/host
    usr/lib/modules/4.19.0-18-amd64/kernel/drivers/nvme/host/nvme-core.ko
    usr/lib/modules/4.19.0-18-amd64/kernel/drivers/nvme/host/nvme-fabrics.ko
    usr/lib/modules/4.19.0-18-amd64/kernel/drivers/nvme/host/nvme-fc.ko
    usr/lib/modules/4.19.0-18-amd64/kernel/drivers/nvme/host/nvme-rdma.ko
    usr/lib/modules/4.19.0-18-amd64/kernel/drivers/nvme/host/nvme.ko
    usr/lib/modules/4.19.0-18-amd64/kernel/drivers/nvme/target
    usr/lib/modules/4.19.0-18-amd64/kernel/drivers/nvme/target/nvmet-fc.ko
    usr/lib/modules/4.19.0-18-amd64/kernel/drivers/nvme/target/nvmet-rdma.ko
    usr/lib/modules/4.19.0-18-amd64/kernel/drivers/nvme/target/nvmet.ko
  3. 在GRUB中添加NVMe相关的nvme timeout参数。

    1. 执行以下命令,打开grub文件。

      vi /etc/default/grub
    2. i键进入编辑模式,请参见,确认io_timeout参数的完整参数名称和所能接受的最大值。例如,完整参数名称为nvme_core.io_timeout,所能接受的最大值为 4,294,967,295。则请在GRUB_CMDLINE_LINUX=一行中,添加nvme_core.multipath=n nvme_core.io_timeout=4294967295 nvme_core.admin_timeout=4294967295参数信息。 添加参数后,文件内容如下所示:

      GRUB_DEFAULT=0
      GRUB_TIMEOUT=1
      GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
      GRUB_CMDLINE_LINUX_DEFAULT="quiet"
      GRUB_CMDLINE_LINUX=" vga=792 console=tty0 console=ttyS0,115200n8 net.ifnames=0 noibrs nvme_core.multipath=n nvme_core.io_timeout=4294967295 nvme_core.admin_timeout=4294967295"
    3. Esc键退出编辑模式,输入:wq并按Enter键,保存退出文件。

    4. 根据操作系统的启动方式不同,执行以下适用于您的操作系统的命令,使配置的GRUB生效。

      • Legacy启动方式

        grub-mkconfig -o /boot/grub/grub.cfg
      • UEFI启动方式

        grub-mkconfig -o /boot/efi/EFI/debian/grub.cfg
        说明

        除以上方式外,您还可以选择Debian系统提供的脚本使配置的GRUB生效,运行脚本的命令如下所示。该脚本不区分操作系统的启动方式,适用于Legacy或UEFI启动方式。

        update-grub2
    5. 执行以下命令,重启实例,使配置生效。

      reboot
    6. 执行以下命令,确认相关配置已正确传递给内核。

      cat /proc/cmdline

      系统显示类似如下。

      ... nvme_core.multipath=n nvme_core.io_timeout=4294967295 nvme_core.admin_timeout=4294967295
    7. 执行以下命令,确认NVMe驱动参数已正确配置IO超时参数,

      cat /sys/module/nvme_core/parameters/io_timeout

      系统显示类似如下。

      4294967295

Ubuntu

  1. 远程连接Ubuntu实例。

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

  2. 执行以下命令,查看initrd中包含的NVMe驱动。

    lsinitramfs /boot/initrd.img-`uname -r` | grep -i nvme

    系统显示类似如下, 默认Ubuntu操作系统的initrd中已经加载了NVMe驱动。

    usr/lib/modules/5.4.0-86-generic/kernel/drivers/nvme
    usr/lib/modules/5.4.0-86-generic/kernel/drivers/nvme/host
    usr/lib/modules/5.4.0-86-generic/kernel/drivers/nvme/host/nvme-core.ko
    usr/lib/modules/5.4.0-86-generic/kernel/drivers/nvme/host/nvme-fabrics.ko
    usr/lib/modules/5.4.0-86-generic/kernel/drivers/nvme/host/nvme-fc.ko
    usr/lib/modules/5.4.0-86-generic/kernel/drivers/nvme/host/nvme-rdma.ko
    usr/lib/modules/5.4.0-86-generic/kernel/drivers/nvme/host/nvme-tcp.ko
    usr/lib/modules/5.4.0-86-generic/kernel/drivers/nvme/host/nvme.ko
    usr/lib/modules/5.4.0-86-generic/kernel/drivers/nvme/target
    usr/lib/modules/5.4.0-86-generic/kernel/drivers/nvme/target/nvme-loop.ko
    usr/lib/modules/5.4.0-86-generic/kernel/drivers/nvme/target/nvmet-fc.ko
    usr/lib/modules/5.4.0-86-generic/kernel/drivers/nvme/target/nvmet-rdma.ko
    usr/lib/modules/5.4.0-86-generic/kernel/drivers/nvme/target/nvmet-tcp.ko
    usr/lib/modules/5.4.0-86-generic/kernel/drivers/nvme/target/nvmet.ko
  3. 在GRUB中添加NVMe相关的nvme timeout参数。

    1. 执行以下命令,打开grub文件。

      vi /etc/default/grub
    2. i键进入编辑模式,请参见临时配置io_timeout参数的值,确认io_timeout参数的完整参数名称和所能接受的最大值。例如,完整参数名称为nvme_core.io_timeout,所能接受的最大值为 4294967295。则请在GRUB_CMDLINE_LINUX=一行中,添加nvme_core.multipath=n nvme_core.io_timeout=4294967295 nvme_core.admin_timeout=4294967295参数信息。 添加参数后,文件内容如下所示:

      GRUB_DEFAULT=0
      GRUB_TIMEOUT=1
      GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
      GRUB_CMDLINE_LINUX_DEFAULT="quiet"
      GRUB_CMDLINE_LINUX=" vga=792 console=tty0 console=ttyS0,115200n8 net.ifnames=0 noibrs nvme_core.multipath=n nvme_core.io_timeout=4294967295 nvme_core.admin_timeout=4294967295"
    3. Esc键退出编辑模式,输入:wq并按Enter键,保存退出文件。

    4. 根据操作系统的启动方式不同,执行以下适用于您的操作系统的命令,使配置的GRUB生效:

      • Legacy启动方式

        grub-mkconfig -o /boot/grub/grub.cfg
      • UEFI启动方式

        grub-mkconfig -o /boot/efi/EFI/ubuntu/grub.cfg
        说明

        除以上方式外,您还可以选择Ubuntu系统提供的脚本使配置的GRUB生效,运行脚本的命令如下所示。该脚本不区分操作系统的启动方式,适用于Legacy或UEFI启动方式。

        update-grub2
    5. 执行以下命令,重启实例,使配置生效。

      reboot
    6. 执行以下命令,确认相关配置已正确传递给内核。

      cat /proc/cmdline

      系统显示类似如下信息。

      ... nvme_core.multipath=n nvme_core.io_timeout=4294967295 nvme_core.admin_timeout=4294967295
    7. 执行以下命令,确认NVMe驱动参数已正确配置IO超时参数。

      cat /sys/module/nvme_core/parameters/io_timeout

      系统显示类似如下信息。

      4294967295

OpenSUSE/SUSE Linux

  1. 远程连接OpenSUSE或SUSE Linux实例。

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

  2. 执行以下命令,查看系统内核是否已经加载了内核驱动。

    cat /boot/config-`uname -r` | grep -i nvme | grep -v "^#"

    系统显示类似如下,如果存在CONFIG_BLK_DEV_NVME=y,则表示该镜像已经加载NVMe驱动。

    CONFIG_NVME_CORE=m
    CONFIG_BLK_DEV_NVME=m
    CONFIG_NVME_MULTIPATH=y
    CONFIG_NVME_HWMON=y
    CONFIG_NVME_FABRICS=m
    CONFIG_NVME_RDMA=m
    CONFIG_NVME_FC=m
    CONFIG_NVME_TCP=m
    CONFIG_NVME_TARGET=m
    CONFIG_NVME_TARGET_PASSTHRU=y
    CONFIG_NVME_TARGET_LOOP=m
    CONFIG_NVME_TARGET_RDMA=m
    CONFIG_NVME_TARGET_FC=m
    CONFIG_NVME_TARGET_FCLOOP=m
    CONFIG_NVME_TARGET_TCP=m
    CONFIG_RTC_NVMEM=y
    CONFIG_NVMEM=y
    CONFIG_NVMEM_SYSFS=y
  3. 在GRUB中添加NVMe相关的nvme timeout参数。

    1. 执行以下命令,打开grub文件。

      vi /etc/default/grub
    2. i键进入编辑模式,请参见临时配置io_timeout参数的值,确认io_timeout参数的完整参数名称和所能接受的最大值。例如,完整参数名称为nvme_core.io_timeout,所能接受的最大值为 4,294,967,295。则请在GRUB_CMDLINE_LINUX=一行中,添加nvme_core.multipath=n nvme_core.io_timeout=4294967295 nvme_core.admin_timeout=4294967295参数信息。 添加参数后,文件内容如下所示:

      GRUB_DISTRIBUTOR=
      GRUB_DEFAULT=saved
      GRUB_HIDDEN_TIMEOUT=0
      GRUB_HIDDEN_TIMEOUT_QUIET=true
      GRUB_TIMEOUT=1
      GRUB_CMDLINE_LINUX_DEFAULT="splash=silent mitigations=auto quiet"
      GRUB_CMDLINE_LINUX=" net.ifnames=0 console=tty0 console=ttyS0,115200n8 nvme_core.multipath=n nvme_core.io_timeout=4294967295 nvme_core.admin_timeout=4294967295"
      GRUB_TERMINAL="console"
      GRUB_GFXMODE="auto"
      GRUB_BACKGROUND=/boot/grub2/themes/SLE/background.png
      GRUB_THEME=/boot/grub2/themes/SLE/theme.txt
      SUSE_BTRFS_SNAPSHOT_BOOTING="true"
      GRUB_DISABLE_OS_PROBER="true"
      GRUB_ENABLE_CRYPTODISK="n"
      GRUB_CMDLINE_XEN_DEFAULT="vga=gfx-1024x768x16"
    3. Esc键退出编辑模式,输入:wq并按Enter键,保存退出文件。

    4. 根据操作系统的启动方式不同,执行以下适用于您的操作系统的命令,使配置的GRUB生效。

      • Legacy启动方式

        grub2-mkconfig -o /boot/grub2/grub.cfg
      • UEFI启动方式

        grub2-mkconfig -o /boot/efi/EFI/sles/grub.cfg
    5. 执行以下命令,重启实例,使配置生效。

      reboot
    6. 执行以下命令,确认相关配置已正确传递给内核。

      cat /proc/cmdline

      系统显示类似如下信息。

      ... nvme_core.multipath=n nvme_core.io_timeout=4294967295 nvme_core.admin_timeout=4294967295
    7. 执行以下命令,确认NVMe驱动参数已正确配置IO超时参数。

      cat /sys/module/nvme_core/parameters/io_timeout

      系统显示类似如下信息。

      4294967295

使用云助手插件自动化配置

云助手提供了ecs_nvme_config插件,帮助您快速完成操作系统内NVMe相关的配置。

ecs_nvme_config插件目前支持以下操作系统:

  • Alibaba Cloud Linux

  • Anolis OS

  • CentOS/CentOS Stream

  • Debian

  • Ubuntu

  • OpenSUSE

  • SUSE Linux Enterprise Server

  • Red Hat Enterprise Linux

  • Fedora

  • Rocky Linux

  • AlmaLinux

ecs_nvme_config插件不支持以下操作系统:

  • CentOS/Red Hat Enterprise Linux:低于6.6的操作系统版本

  • Debian:低于9的操作系统版本

  • Ubuntu:低于16的操作系统版本

  • OpenSUSE:42操作系统版本

  • SUSE Linux Enterprise Server:低于11.4的操作系统版本

  1. 登录ECS实例。

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

  2. 执行以下命令,检查实例内是否已安装云助手Agent,并检查客户端内是否提供了ecs_nvme_config插件。

    acs-plugin-manager --list

    系统显示类似如下,表示已安装云助手Agent。如果您运行命令后没有返回云助手相关信息,则需要先在实例内安装云助手Agent。具体操作,请参见安装云助手Agent

    +---------------------------------------------------------------+
    |                          Name|   version| publisher|        os|
    +---------------------------------------------------------------+
    |                       oosutil|      1.11|    aliyun|     LINUX|
    |                         sysak|      0.38|    aliyun|     LINUX|
    |                  ecsgo-helper|      0.11|    aliyun|     LINUX|
    |       ecs_tools_sysak-iosdiag|       2.3|    aliyun|     LINUX|
    |         ecs-metrics-collector|      0.13|    aliyun|     LINUX|
    |                ecs-utils-ipv6|       1.3|    aliyun|     LINUX|
    |                 patch_manager|      1.10|    aliyun|     LINUX|
    |               ecs_nvme_config|       1.0|    aliyun|     LINUX|
    |             kms-rotate-secret|       1.0|    aliyun|     LINUX|
    |           app-snapshot-plugin|       1.8|    aliyun|     LINUX|
    |           ecs-hibernate-linux|       0.3|    aliyun|     LINUX|
    |             smc-client-plugin|       1.1|    aliyun|     LINUX|
    |ecs_disable_intel_hyper-threading|       1.0|    aliyun|     LINUX|
    |                multi-nic-util|       1.0|    aliyun|     LINUX|
    |          ecs_tools_multiqueue|       1.2|    aliyun|     LINUX|
    |               ecs_dump_config|       1.0|    aliyun|     LINUX|
    |      bare_metal_shutdown_util|       1.0|    aliyun|     LINUX|
    |            ecs_inventory_test|       3.3|    aliyun|     LINUX|
    +---------------------------------------------------------------+

    如果您可以查看到返回的云助手插件列表,但插件列表中没有ecs_nvme_config插件,则表示该插件在当前的地域和可用区下没有发布。您需要根据不同的操作系统,选择适用的手动配置方式,进行NVMe相关的配置操作。

    如果您的实例内已安装云助手Agent,且存在ecs_nvme_config插件,请继续下一步。

  3. 使用ecs_nvme_config插件,完成NVMe相关的配置。

    1. 执行以下命令,使用ecs_nvme_config插件检查当前实例内是否有NVMe模块,以及是否可以配置NVMe模块。

      acs-plugin-manager --exec --plugin ecs_nvme_config --params --check

      返回结果说明:

      • 如果返回结果中存在如下提示,则表示您无需进行NVMe相关的配置。

        [SUCCESS]  Summary: Your image can Runnig on nvme instance
      • 如果返回结果中存在[ERROR]相关提示,则您需要继续执行下一步操作。

    2. 根据检查结果中的提示信息,配置NVMe驱动以及相关参数信息。

      例如,检查结果中提示如下信息:

      acs-plugin-manager --exec --plugin ecs_nvme_config --params --check

      则您需要根据提示内容,执行以下命令,完成NVMe相关的配置。

      acs-plugin-manager --exec --plugin ecs_nvme_config --params --fix
    3. 完成配置后,执行以下命令,重启实例。

      reboot
    4. 重启实例后,重新检查NVMe模块是否配置成功。

      acs-plugin-manager --exec --plugin ecs_nvme_config --params --check

      配置成功的返回示例如下:

      [OK]  1.initrd/initramfs already contain nvme module;
      
      
      [OK]  2.fstab file looks fine and does not contain any device names;
      
      
      [OK]  3.The nvme parameters already included.
      
      
      [SUCCESS]  Summary: Your image can Runnig on nvme instance

  • 本页导读 (1)