在Windows实例中调整NVMe硬盘的I/O超时时间

Windows系统为防止因存储I/O无响应而挂起,设定了超时机制,但在高负载下,高性能NVMe云盘的延迟可能超出该默认值而导致系统出错。因此,通过适当延长NVMe驱动的I/O超时时间,可有效增强系统在极限I/O压力下的容错能力和稳定性。

操作步骤

请确保磁盘为NVMe磁盘的情况下执行以下操作。

可在实例内的PoweShell界面执行Get-Disk |select BusType,若回执为NVMe,表示为NVMe云盘。
重要

为防止误操作,请务必在操作前手动创建单个快照,备份数据。

方式一(推荐):使用PowerShell脚本自动修改

  1. 登录ECS实例。

    1. 访问ECS控制台-实例。在页面左侧顶部,选择目标资源所在的资源组和地域。

    2. 进入目标实例详情页,单击远程连接,选择通过Workbench远程连接。选择连接方式为终端连接,输入账号和密码,登录图形化终端页面。

  2. 右键单击开始图标图标,然后单击运行。输入PowerShell ISE,进入PowerShell ISE界面后,复制并执行以下代码。

    此脚本会自动检测系统中正在使用的NVMe控制器驱动程序,并为其添加或修改IoTimeoutValue注册表键值,将其设置为65535
    function Set_Nvme_Reg {
        $os = (Get-WmiObject -Class win32_operatingsystem).Caption 
        $nvmeDevs = Get-WmiObject Win32_PnPEntity | Where-Object {$_.Name -match "nvm" -and  $_.PNPClass -eq 'SCSIAdapter'  -and $_.Status -eq "OK"}
        if($os -match 2012){
            $nvmeDevs = Get-WmiObject Win32_PnPEntity | Where-Object { $_.Name -match "nvm"  -and $_.Status -eq "OK"}
        }
        if ($nvmeDevs) {
            $drvFiles = @()
            foreach ($dev in $nvmeDevs) {
                $regpath = "HKLM:\SYSTEM\CurrentControlSet\Enum\" + ($dev.DeviceID -replace '\\','\\')
                $drvinfo = Get-ItemProperty -Path $regpath
                $driverkey = $drvinfo.Driver          
    
                $driverparts = $driverkey.Split('\')
                $classguid = $driverparts[0]
                $classnum = $driverparts[1]
                $classregpath = "HKLM:\SYSTEM\CurrentControlSet\Control\Class\$classguid\$classnum"
                $drvInf = (Get-ItemProperty -Path $classregpath).Infpath
        
                $dir = "$env:SystemRoot\INF"
                $infPath = Join-Path $dir $drvInf
                $sysList = Select-String -Path $infPath -Pattern "\.sys" | Select-Object -ExpandProperty Line
                $serviceBinValue = $sysList -split "`n" | Where-Object { $_ -match "^ServiceBinary\s*=" }
                if ($serviceBinValue) {
                    $match = $serviceBinValue -match "=\s*(.+)$"
                    $rawPath = $Matches[1]
                    $fileName = [System.IO.Path]::GetFileName($rawPath)
                    if ($fileName) {
                        $drvFiles += $fileName
                    }else{
                        Write-Host "Driver .sys file name NOT found in inf file ($infPath)! "
                    }
                }else {
                    Write-Host "ServiceBinary value NOT found in inf file ($infPath)!"
                }
            }
    
            $uniqDrvFiles = $drvFiles | Select-Object -Unique
            foreach ($fileName in $uniqDrvFiles) {
                try {
                    $drvName = [System.IO.Path]::GetFileNameWithoutExtension($fileName)
                    Write-Host "The nvme driver used is: $drvName"
                    $regpath = "HKLM:\SYSTEM\CurrentControlSet\Services\$drvName\Parameters"
                    New-ItemProperty -Path $regpath -Name "IoTimeoutValue" -Value 65535 -PropertyType DWORD -Force | Out-Null
                    Write-Host "IoTimeoutValue Modified successfully for $drvName"
                } catch {
                    Write-Host "Failed to set registry for ${drvName}: $($_.Exception.Message)"
                }
            }
    
        } else {
            Write-Host 'No NVMe driver found, no need to do anything'
        }
    }
    
    Set_Nvme_Reg

    输出IoTimeoutValue Modified successfully for AliNVMeIoTimeoutValue Modified successfully for stornvme时,表明修改成功。

  3. 重启实例使配置生效。

    重要

    重启实例会中断业务,请谨慎评估重启时间。

    1. 在实例详情页的右上角单击重启

    2. 在弹窗中,单击确定,立即重启实例。

方式二:手动修改注册表

  1. 确定NVMe驱动程序名称。

    1. 右键单击开始图标图标,然后单击设备管理器

    2. 展开存储控制器,右键单击标准NVM Express控制器Alibaba NVMe Elastic Block Storage Adapter后,单击属性

    3. 属性页面,切换至驱动程序选项卡后,单击驱动程序详细信息

    4. 驱动程序文件中,记录驱动程序名称(AliNVMestornvme)。

  2. 调整NVMe硬盘的I/O超时时间。

    根据驱动器名称选择操作。

    AliNVMe

    1. 右键单击开始图标图标,然后单击运行。输入regedit,打开注册表编辑器。

    2. 定位驱动程序服务路径。

      1. 在注册表编辑器左侧的树状目录中,依次展开HKEY_LOCAL_MACHINE > SYSTEM > CurrentControlSet > Services > AliNVMe

      2. 单击Parameters,在右侧窗口的空白处单击右键,选择新建 > DWORD (32 位)值,将新建文件命名为IoTimeoutValueimage

      3. 双击新建文件,在弹框中修改基数为十进制数值数据65535后,单击确定。

    stornvme

    1. 右键单击开始图标图标,然后单击运行。输入regedit,打开注册表编辑器。

    2. 定位驱动程序服务路径。

      1. 在注册表编辑器左侧的树状目录中,依次展开HKEY_LOCAL_MACHINE > SYSTEM > CurrentControlSet > Services > stornvme

      2. 单击Parameters,查看是否存在IoTimeoutValue文件。若不存在,需在右侧窗口的空白处单击右键,选择新建 > DWORD (32 位)值,将新建文件命名为IoTimeoutValueimage

      3. 双击IoTimeoutValue文件,在弹框中修改基数为十进制数值数据65535后,单击确定。

  3. 重启实例使配置生效。

    重要

    重启实例会中断业务,请谨慎评估重启时间。

    1. 在实例详情页的右上角单击重启

    2. 在弹窗中,单击确定,立即重启实例。