ESXi误将SSD识别为机械盘?底层原理与修复指南
1. 一块SSD被ESXi认成机械盘这事到底卡在哪如果你在ESXi里给虚拟机配了SSD数据存储结果打开存储设备列表一看设备类型那一栏赫然写着“非SSD”或者虚拟机里跑数据库时延迟高得离谱那基本可以确定——ESXi没有正确识别这块盘的介质类型。这个问题在运维圈子里出现的频率远比想象中高尤其是用白牌盘、消费级SSD、或者某些OEM定制盘搭ESXi的时候。先把结论摆在前面ESXi判断一块盘是不是SSD靠的不是“猜”而是读取磁盘上报的介质类型标识。如果这个标识没被正确上报或者ESXi的SATSCSI Address Translation层把它翻译错了那不管你的盘实际读写有多快ESXi都会把它当机械盘处理。而一旦被当成机械盘影响的不只是显示——ESXi的存储调度策略、虚拟机I/O队列深度、以及某些高级功能的启用条件都会跟着变。这篇文章面向的是正在用ESXi做虚拟化、手里有SSD但发现识别异常的朋友。不管你是刚装完ESXi发现盘类型不对还是跑了很久之后突然发现某块盘“退化”成了非SSD下面这套排查和修复思路都能直接用。我会从ESXi识别磁盘类型的底层逻辑讲起然后一步步带你定位问题、验证结果最后给出几种不同场景下的处理方案。需要提前说明的是ESXi的版本差异在这个问题上影响很大。ESXi 6.x和7.x、8.x在设备识别和SAT层处理上有明显区别有些在6.7上需要手动干预的情况到了7.0 U2之后可能已经自动处理了。所以下面的操作我会标注适用的版本范围你对照自己的环境来。2. ESXi判断SSD与非SSD的底层逻辑2.1 磁盘介质类型是怎么被上报的一块磁盘告诉主机“我是SSD”还是“我是机械盘”走的是SCSI协议里的一个字段。在SCSI Primary Commands标准中有一个叫Block Device Characteristics VPD PageB1h的页里面有一个Medium Rotation Rate字段。这个字段的值如果是1表示非旋转介质也就是SSD如果是7200、10000、15000这样的数值表示转速也就是机械盘如果是0表示“未报告”。ESXi在启动时或者扫描存储适配器时会向每块盘发送INQUIRY命令读取这个VPD页。读到Medium Rotation Rate为1就标记为SSD读到0或者读不到这个页就默认按非SSD处理。问题就出在这里很多消费级SSD、某些白牌盘、以及通过USB或某些RAID卡转接的盘要么根本不返回这个VPD页要么返回的Medium Rotation Rate是0。ESXi拿不到“我是SSD”的证据就只能把它归到非SSD那一类。2.2 SAT层在中间做了什么ESXi的存储栈里有一个SATSCSI Address Translation层它的作用是在不同的SCSI命令集之间做翻译。比如你的盘接在SATA控制器上ESXi通过AHCI驱动发下去的SCSI命令需要SAT层做一层转换。在这个过程中如果SAT层的翻译规则没有把Medium Rotation Rate正确传递上来ESXi上层拿到的就是“未知”或“非SSD”。ESXi 6.5之前SAT层对VPD页B1h的处理比较粗糙很多SATA SSD的介质类型信息在翻译过程中就丢了。从ESXi 6.7开始VMware逐步完善了SAT层的处理逻辑但直到7.0 U1之后才相对稳定。这也是为什么同一块盘在6.7上显示为非SSD换到7.0 U3上可能就正常识别了。2.3 为什么ESXi这么在意SSD标识你可能会想盘快就行了ESXi管它是不是SSD干嘛实际上这个标识直接影响好几件事。第一存储I/O调度。ESXi对SSD和机械盘采用不同的I/O调度策略。机械盘需要做寻道优化I/O合并和排序的逻辑偏向减少磁头移动SSD没有寻道开销调度策略更偏向低延迟和高队列深度。如果一块SSD被当成机械盘ESXi会用机械盘的调度逻辑来处理它的I/O延迟会明显上升。第二虚拟机存储策略。vSphere的存储策略里有一些规则依赖介质类型比如基于存储的I/O控制、以及某些VSAN的缓存层判定。如果SSD被标成非SSD这些策略可能不会按预期生效。第三告警和监控。vCenter里基于介质类型的告警和报表会失真你看到的存储性能数据可能和实际硬件能力对不上。注意ESXi把SSD识别为非SSD不会导致数据丢失或虚拟机无法运行但会影响性能和部分高级功能的可用性。如果你的环境对存储延迟敏感这个问题值得花时间处理。3. 从ESXi命令行确认磁盘的真实介质类型3.1 用esxcli定位设备标识排查的第一步是确认ESXi到底把这块盘认成了什么。SSH登录到ESXi主机或者通过DCUI打开Shell执行esxcli storage core device list这条命令会列出所有存储设备。找到你关心的那块盘看它的Device Type字段。如果显示的是“disk”而不是“SSD”那说明ESXi确实没把它当SSD。更精确的做法是直接查介质类型esxcli storage core device list -d 设备名把设备名替换成实际的设备标识比如naa.5000c500a1b2c3d4。输出里会有一行Is SSD: false或者Is SSD: true这就是ESXi当前的判定结果。3.2 用smartctl读取磁盘自己怎么说ESXi自带的功能有限如果你想看磁盘自己上报的介质类型可以用smartctl。ESXi的默认镜像里不一定有但很多社区版本或者通过vSphere Installation Bundle安装的ESXi会带这个工具。如果没有可以临时从可信来源获取静态编译版本放到/tmp下执行。./smartctl -i /dev/disks/naa.5000c500a1b2c3d4在输出里找Rotation Rate这一行。如果显示“Solid State Device”说明磁盘自己认为自己是SSD。如果显示“7200 rpm”或者干脆没有这一行那磁盘就没有正确上报介质类型。这一步很关键它能帮你区分是“磁盘没上报”还是“ESXi没识别”。如果smartctl显示磁盘自己是SSD但ESXi显示非SSD那问题出在ESXi的SAT层或驱动层如果smartctl也显示非SSD那问题在磁盘固件或转接卡上。3.3 查看SAT层翻译结果ESXi提供了一个命令来查看SAT层的翻译详情esxcli storage core device satp rule list这条命令列出当前生效的SAT规则。不过更直接的方式是看设备的物理信息esxcli storage core device physical get -d 设备名输出里会包含设备上报的各类VPD页信息。如果你看到Medium Rotation Rate字段是0或者缺失那就印证了前面的判断。另外ESXi的日志里也会有线索。在/var/log/vmkernel.log里搜索设备标识看看SAT层在翻译时有没有报错或警告。常见的相关日志关键词包括Medium Rotation Rate、VPD B1h、SAT等。4. 让ESXi重新识别SSD的几种实操路径4.1 方法一通过esxcli标记设备为SSD这是最直接的方式。ESXi允许你手动覆盖设备的介质类型判定esxcli storage core device set -d 设备名 -t 1其中-t 1表示把设备类型设为SSD。执行完之后再用esxcli storage core device list -d 设备名确认Is SSD是否变成了true。这个设置的原理是ESXi在设备属性里加了一个用户覆盖标记后续的存储调度会按SSD来处理。但要注意这个标记是运行时生效的重启ESXi之后可能会丢失。如果你希望持久化需要把它写进启动脚本或者用Host Profile来管理。提示在ESXi 7.0及更高版本中esxcli storage core device set的-t参数支持0非SSD、1SSD、2未指定。设置之后可以用esxcli storage core device list的Is SSD字段验证。4.2 方法二调整SATP规则让翻译层正确传递如果问题出在SAT层没有正确翻译Medium Rotation Rate可以通过添加SAT规则来干预。ESXi的SAT规则用esxcli storage core claimrule来管理。先查看当前的规则esxcli storage core claimrule list然后添加一条针对特定设备或特定控制器的规则。比如如果你知道某款SATA控制器在SAT翻译时会丢失介质类型信息可以添加一条规则强制指定esxcli storage core claimrule add -r 500 -t vendor -V ATA -M 某型号 -P SATP --satp VMW_SATP_SATA --satp-option enable_ssd这里的--satp-option enable_ssd就是告诉SAT层对于匹配的设备直接按SSD处理。不过这个选项在不同ESXi版本里的支持情况不一样6.7上可能需要用--force-ssd之类的参数具体要看esxcli storage core claimrule add --help的输出。添加规则后需要重新加载esxcli storage core claimrule load esxcli storage core claimrule run -u然后重新扫描存储esxcli storage core adapter rescan --all4.3 方法三更新驱动和固件有些情况下ESXi识别错误是因为存储控制器的驱动版本太旧或者磁盘固件有bug。比如某些早期的SATA控制器驱动在传递VPD页时会把B1h页丢掉更新到最新版驱动后问题就消失了。在ESXi上查看当前驱动版本esxcli software vib list | grep -i scsi\|sata\|ahci\|nvme然后对照硬件厂商的兼容性列表看看有没有更新的驱动版本。ESXi的驱动更新一般通过esxcli software vib update来操作但要注意驱动和ESXi版本的兼容性不要盲目升级。磁盘固件方面如果smartctl显示磁盘自己都没有正确上报Rotation Rate那可能需要用厂商工具更新固件。这一步风险较高建议在非生产环境先验证。4.4 方法四换接口或换转接方式如果你用的是USB转SATA、或者某些RAID卡下的单盘RAID 0模式ESXi很可能拿不到磁盘的原始VPD信息。这种情况下最彻底的解决办法是换一种连接方式。比如把盘从USB转接盒里拿出来直接接到主板的SATA口上或者把RAID卡配置从RAID模式改成HBA直通模式。直通模式下ESXi能直接看到物理盘SAT层翻译路径最短介质类型信息最不容易丢失。这个方法的代价是需要停机操作但对于长期运行的ESXi主机来说一次调整能省掉后续很多麻烦。5. 不同ESXi版本下的差异与坑点5.1 ESXi 6.5/6.7SAT层的老问题ESXi 6.5和6.7在SAT层对SATA SSD的介质类型处理上存在已知缺陷。具体表现是某些SATA SSD在通过AHCI驱动接入时VPD页B1h的Medium Rotation Rate字段在翻译过程中被置为0导致ESXi上层判定为非SSD。VMware在6.7 U2之后发布过几个补丁来修复这个问题但并不是所有硬件组合都覆盖到了。如果你还在用6.5或6.7的早期版本建议先升级到该大版本的最新Update然后再看问题是否仍然存在。另外6.7上esxcli storage core device set -t 1的行为和7.0略有不同。6.7上设置之后Is SSD字段可能不会立即刷新需要重新扫描存储或者重启管理代理/etc/init.d/hostd restart /etc/init.d/vpxa restart5.2 ESXi 7.0/8.0NVMe和SATA的识别差异到了ESXi 7.0NVMe设备的识别逻辑和SATA是分开的。NVMe盘一般不需要通过SAT层ESXi直接通过NVMe驱动读取控制器信息介质类型判定相对准确。但SATA SSD仍然可能遇到老问题尤其是通过第三方SATA控制器接入的时候。ESXi 8.0进一步收紧了硬件兼容性要求很多消费级SATA控制器直接被移出了兼容列表。如果你在8.0上遇到SSD识别为非SSD先确认你的控制器是否在兼容列表里。不在的话换控制器比折腾驱动更省事。5.3 版本升级后设置丢失的应对前面提到esxcli storage core device set -t 1是运行时设置重启后会丢失。如果你有多台ESXi主机或者经常重启手动设置就不太现实。一个可行的做法是写一个启动脚本放在/etc/rc.local.d/目录下让ESXi每次启动时自动执行。脚本内容大致如下#!/bin/sh # 等待存储服务就绪 sleep 30 # 遍历所有设备把符合条件的标记为SSD for device in $(esxcli storage core device list | grep -o naa\.[0-9a-f]*); do # 这里可以加判断条件比如只处理特定型号 esxcli storage core device set -d $device -t 1 done不过这个脚本比较粗暴会把所有设备都标成SSD包括真正的机械盘。更稳妥的方式是用Host Profile或者PowerCLI在vCenter层面做配置管理。6. 验证修复效果与长期监控6.1 确认Is SSD字段已变更设置完成之后第一件事是确认ESXi的判定已经变了esxcli storage core device list -d 设备名 | grep -i Is SSD如果输出是Is SSD: true说明设置生效。然后可以进一步看设备的其他属性有没有跟着变比如队列深度、调度器类型等。6.2 用虚拟机实测I/O延迟变化光看字段变了还不够实际性能有没有改善才是关键。在虚拟机里跑一个简单的I/O测试对比设置前后的延迟。在Linux虚拟机里可以用fiofio --namerandread --ioenginelibaio --rwrandread --bs4k --numjobs4 --size1G --runtime60 --time_based --group_reporting重点看lat (usec)那一行的平均值和P99值。如果设置之前P99延迟在毫秒级设置之后降到了几百微秒说明ESXi的调度策略确实变了。在Windows虚拟机里可以用Diskspd或者CrystalDiskMark做类似对比。注意测试时尽量让虚拟机独占存储避免其他虚拟机的I/O干扰。6.3 把设备类型纳入日常巡检对于生产环境建议把ESXi的SSD识别状态纳入日常巡检。可以用PowerCLI写一个简单的检查脚本Connect-VIServer -Server vcenter地址 -User 用户名 -Password 密码 Get-VMHost | Get-EsxCli -V2 | ForEach-Object { $esxcli $_ $esxcli.storage.core.device.list.Invoke() | Where-Object { $_.IsSSD -eq $false -and $_.DeviceType -eq disk } | Select-Object Device, IsSSD, DeviceType }这个脚本会列出所有被判定为非SSD的磁盘设备。如果发现预期应该是SSD的盘出现在列表里就及时处理。注意PowerCLI的Get-EsxCli -V2需要ESXi 6.0以上版本且vCenter和ESXi的版本要匹配。如果环境里有多个ESXi版本建议分开处理。7. 几个容易踩的坑和我的实际经验7.1 别把所有非SSD都当成故障有些盘被ESXi标为非SSD其实是正常的。比如某些企业级SAS盘虽然性能接近SSD但介质类型确实是旋转的又比如某些混合盘SSHDESXi可能按机械盘处理。在动手改之前先用smartctl确认磁盘自己怎么说。如果磁盘自己都认为自己是机械盘那ESXi的判定没错强行改成SSD反而可能引发调度异常。7.2 改完之后记得重新扫描存储esxcli storage core device set -t 1执行之后有些ESXi版本不会自动刷新存储拓扑。你需要手动触发一次重新扫描esxcli storage core adapter rescan --all或者针对特定适配器esxcli storage core adapter rescan -a 适配器名不重新扫描的话vCenter里看到的设备属性可能还是旧的。7.3 消费级SSD在ESXi上的长期稳定性我见过不少人用消费级SSD搭ESXi做实验环境短期跑没问题但长期跑虚拟机的话消费级SSD的写入寿命和掉速问题会比较明显。ESXi的日志写入、虚拟机交换文件、快照操作都会产生大量随机写入。如果盘本身没有断电保护异常断电后还可能掉盘。所以如果你的环境对稳定性有要求建议用企业级SSD或者至少是带断电保护的型号。7.4 记录原始状态再动手在改任何设置之前先把当前的设备列表和属性完整记录下来esxcli storage core device list /tmp/device_list_before.txt esxcli storage core device list -d 设备名 /tmp/device_detail_before.txt这样万一改出问题可以对照原始状态回滚。ESXi的存储配置不像网络配置那么容易恢复多留一份记录没坏处。7.5 多路径环境下的注意事项如果你的ESXi主机通过多路径比如iSCSI或FC连接存储SSD识别问题可能出现在路径层面而不是设备层面。这种情况下esxcli storage core device set可能只影响其中一条路径的判定。你需要检查每条路径对应的设备标识分别处理。更稳妥的方式是在存储阵列侧确认LUN的介质类型上报是否正确而不是在ESXi侧硬改。8. 什么时候该放弃折腾直接换硬件折腾ESXi的SSD识别问题有时候投入产出比并不高。如果你已经试过命令行标记、SAT规则调整、驱动更新但问题依然存在而且你的盘本身也不是什么高端型号那我的建议是换一块ESXi兼容性列表里明确支持的SSD。VMware的兼容性列表里会标注每款SSD在ESXi下的支持状态包括介质类型识别是否正常。选一块列表里的盘插上去就能正确识别省下来的时间够你干很多别的事了。尤其是生产环境稳定性比省那点硬件钱重要得多。另外如果你用的是白牌服务器或者自己攒的机器主板SATA控制器往往不在ESXi兼容列表里。这种情况下加一张LSI/Broadcom的HBA卡比如9300-8i系列走直通模式比在板载SATA上折腾SAT规则要靠谱得多。HBA直通模式下ESXi能直接看到物理盘介质类型识别基本不会出问题。最后说一个我自己的习惯每次给ESXi主机加新盘之前先查一下这块盘在社区里的反馈看看有没有人遇到过识别问题。如果已经有人踩过坑并且没有好的解决办法那就直接换型号不浪费时间去试。这个习惯帮我省了不少事。