上一篇 下一篇 分享链接 返回 返回顶部

从普通云硬盘迁移到香港云服务器NVMe盘,如何评估I/O收益、停机窗口与回退条件?

发布人:Minchunlin 发布时间:2026-09-30 13:17 阅读量:2
从普通云硬盘迁移到香港云服务器NVMe盘,如何评估I/O收益、停机窗口与回退条件?

先判断:NVMe 的收益是否能解决当前瓶颈

香港云服务器 NVMe 硬盘优势是什么?通常体现在更适合高并发随机读写、较低存储访问延迟,以及更好的并行 I/O 能力。但“使用 NVMe 接口”不等于业务一定会变快,最终效果还取决于云平台的存储后端、磁盘 IOPS 和吞吐上限、文件系统、队列深度,以及应用是否真的受存储限制。

因此,从普通云硬盘迁移前,建议先满足三个条件:

  1. 已经确认当前业务瓶颈与磁盘读写有关,而不是 CPU、内存、数据库锁、网络或应用代码。
  2. 新盘可以在当前香港云服务器上正常挂载,并确认其数据持久性、快照和备份能力符合业务要求。
  3. 已准备可恢复的旧盘、备份或快照,并且迁移后保留一段不变更的回退路径。

如果当前磁盘的 await、应用写入延迟或数据库提交等待明显偏高,同时新 NVMe 盘在相同测试条件下表现更好,迁移通常有评估价值。若业务只是顺序读取、网络响应慢,或者磁盘利用率长期很低,单纯更换 NVMe 盘可能不会带来明显收益。

迁移前先确认哪些条件

确认新盘的实际属性

在云平台控制台和系统内分别确认以下内容:

  • 新盘是否支持挂载到当前服务器,还是必须创建新的服务器。
  • 新盘是持久化云盘、临时本地盘,还是具有重建后数据可能丢失的限制。
  • 云平台是否对 IOPS、吞吐量、突发性能或容量设置上限。
  • 是否支持快照、备份、扩容和故障恢复。
  • 操作系统内核是否识别 NVMe 设备。
  • 新盘支持的文件系统,以及现有应用需要的挂载参数。
  • 云平台是否要求使用特定的设备标识或控制台操作完成挂载。

NVMe 设备在 Linux 中常见的名称类似 /dev/nvme1n1,但不能仅凭设备名称判断哪块盘是新盘。先执行以下检查:

cat /etc/os-release
uname -r
lsblk -o NAME,MODEL,SERIAL,SIZE,TYPE,FSTYPE,MOUNTPOINTS,UUID
findmnt -R

对照云平台显示的容量、序列号或设备标识确认目标盘。确认前不要执行格式化操作。

如果新盘是空盘,可以查看其是否已经存在文件系统:

sudo blkid /dev/disk/by-id/REPLACE_WITH_NEW_DEVICE
sudo file -s /dev/disk/by-id/REPLACE_WITH_NEW_DEVICE

只有在确认设备为空、没有需要保留的数据,并且已经完成备份或确认不需要回退该盘时,才可以格式化。例如使用 ext4:

sudo mkfs.ext4 -L appdata-nvme /dev/disk/by-id/REPLACE_WITH_NEW_DEVICE

mkfs 会覆盖目标设备上的原有文件系统,设备路径、文件系统类型和业务数据必须再次核对。若业务要求 XFS 或其他文件系统,应按操作系统和应用兼容性选择,不能直接套用上述示例。

记录现有数据和写入规模

停机窗口不能只按照磁盘容量估算。需要同时了解已用空间、文件数量、持续写入量和需要同步的日志目录。

OLD_MOUNT="/srv/app-data"

df -hT "$OLD_MOUNT"
df -ih "$OLD_MOUNT"
sudo du -shx "$OLD_MOUNT"
findmnt -T "$OLD_MOUNT"
findmnt -R "$OLD_MOUNT"

如果文件数量很多,可以在业务低峰期统计:

sudo find "$OLD_MOUNT" -xdev -type f | wc -l

还要确认以下内容是否位于迁移目录中:

  • 数据库主数据目录;
  • 事务日志、归档日志或消息队列数据;
  • 应用上传文件;
  • 定时任务产生的临时文件;
  • 备份程序使用的目录;
  • 通过挂载点嵌套在目录下的其他文件系统。

如果目录下存在嵌套挂载,不能把整个目录简单地当成一个普通目录复制。应分别核对每个挂载点,否则迁移后可能出现目录存在但实际数据未迁移的情况。

用同口径测试判断 I/O 收益

先看业务是否真的受磁盘限制

在当前业务运行期间观察磁盘和应用指标。Linux 上可以使用 iostat:

iostat -xz 1

重点记录业务高峰期间的以下指标:

  • r/s、w/s:每秒读写次数;
  • rkB/s、wkB/s:读写吞吐;
  • await:I/O 平均等待时间;
  • aqu-sz:设备队列长度;
  • %util:设备繁忙程度。

同时记录应用请求延迟、错误率、数据库提交等待、任务处理时间等业务指标。单看 %util 不能证明一定需要迁移,因为应用可能受 CPU、锁或线程数限制;单看 IOPS 也不能证明业务一定受益,必须和实际请求延迟对应起来。

如果当前磁盘已经出现持续排队、等待时间升高,且应用延迟和磁盘高峰同步变化,存储更换的收益更值得验证。若磁盘很空闲,但应用延迟仍然很高,应先排查应用和数据库,不要直接采购更高规格磁盘。

在新盘上进行非生产压测

新盘挂载到临时目录后,可以在新盘上建立独立测试文件。不要直接对生产数据目录执行随机写压测,也不要在没有备份的情况下覆盖现有数据。

先确认 fio 是否可用:

fio --version
fio --enghelp

下面是一个示例测试,测试文件位于新盘,不会直接覆盖业务数据:

STAGE_MOUNT="/mnt/nvme"

sudo fio \
  --name=nvme-randrw \
  --filename="$STAGE_MOUNT/.fio-test" \
  --size=1G \
  --rw=randrw \
  --rwmixread=70 \
  --bs=4k \
  --ioengine=libaio \
  --iodepth=32 \
  --numjobs=1 \
  --direct=1 \
  --runtime=60 \
  --time_based \
  --group_reporting

测试参数需要和业务特征保持一致:

  • 小文件、数据库索引较多时,重点关注小块随机读写和延迟;
  • 日志或备份以连续写入为主时,重点关注顺序吞吐;
  • 并发应用较多时,测试多个队列深度或任务数;
  • 业务依赖持久化提交时,需要关注 fsync 或同步写入延迟;
  • 测试文件应足够覆盖实际工作集,但不能占满新盘。

libaio、io_uring 等 I/O 引擎是否可用取决于系统和 fio 编译方式。如果测试报错,应根据 fio --enghelp 选择当前系统支持的引擎,并保证新旧测试使用相同参数。压测输出中的 IOPS、带宽和平均或百分位延迟只能用于同口径比较,不能直接当作业务承载量承诺。

如果要对普通云硬盘做对照测试,应使用独立测试文件、快照副本或业务允许的低风险窗口。生产盘不建议执行随机写测试。更可靠的方式是记录现有业务高峰指标,再将新盘测试结果与同一业务回放或迁移后的实际指标比较。

判断是否值得迁移

可以按以下条件做判断:

观察结果迁移判断
现有盘等待时间高,应用延迟与磁盘排队同步升高;新盘同口径延迟更低值得进入迁移准备
现有盘吞吐接近上限,新盘吞吐上限和测试结果都更高可评估迁移,但要确认应用能产生足够并发
磁盘利用率低,瓶颈位于 CPU、内存、锁或网络暂不迁移,先处理实际瓶颈
新盘压测好看,但应用请求延迟没有改善不应仅凭压测结果迁移
新盘是临时盘,重建或特定运维操作可能丢失数据不能把它作为唯一持久化副本
需要保留 ACL、扩展属性、稀疏文件或特殊挂载参数,但新文件系统不支持先解决兼容性,再安排迁移

成本判断也不能只看磁盘单价,还要核对容量、性能上限、快照和备份费用、扩容方式,以及迁移期间的人工和停机成本。当前没有这些实际报价时,不应预设具体节省金额。

设计可控的迁移窗口

先完成一次在线初始复制

以下示例假设新盘挂载到 /mnt/nvme,旧数据目录是 /srv/app-data。目标目录必须确认为空或仅包含本次复制的数据。

OLD_MOUNT="/srv/app-data"
STAGE_MOUNT="/mnt/nvme"

sudo mkdir -p "$STAGE_MOUNT"
sudo mount /dev/disk/by-uuid/REPLACE_WITH_NEW_UUID "$STAGE_MOUNT"

df -hT "$OLD_MOUNT" "$STAGE_MOUNT"
findmnt -T "$STAGE_MOUNT"

对于普通文件目录,可以先进行初始复制:

time sudo rsync -aHAXS \
  --numeric-ids \
  --info=progress2 \
  "$OLD_MOUNT"/ "$STAGE_MOUNT"/

这些参数用于尽量保留硬链接、ACL、扩展属性、稀疏文件和数字 UID/GID。使用前确认目标文件系统支持这些属性;如果 rsync 报告 ACL 或扩展属性不支持,不要直接忽略错误,应先核对应用是否依赖这些属性。

在线初始复制只适合能够接受文件短暂不一致、并且可以在最终阶段停止写入的普通文件业务。不要把正在运行的数据库主数据目录当成普通文件目录持续复制。数据库应使用自身的备份、物理复制、快照或干净停库方案,以保证事务一致性。

初始复制结束后,再进行一次演练式检查,估计最终同步需要处理多少变更:

sudo rsync -aHAXS \
  --numeric-ids \
  --dry-run \
  --stats \
  "$OLD_MOUNT"/ "$STAGE_MOUNT"/

通过初始复制耗时、第二次同步的变更量,以及业务实际写入速度,可以估算最终停机阶段的同步时间。停机窗口可按以下方式拆分:

停机窗口 =
停止写入与服务耗时
+ 最终同步耗时
+ 卸载旧盘与挂载新盘耗时
+ 服务启动耗时
+ 数据与业务验证耗时

最终同步的关键不是总数据量,而是停机时仍然变化的数据量。如果业务持续写入的速度高于同步速度,最终同步可能无法收敛,此时应先启用维护模式、暂停任务生产、停止写入进程,或改用数据库复制方案。

进入最终同步前停止所有写入者

不要只停止主应用,还要核对后台任务、队列消费者、定时任务和备份程序是否仍会写入目录。以 systemd 服务为例:

APP_SERVICE="your-app.service"

sudo systemctl stop "$APP_SERVICE"
sudo systemctl is-active "$APP_SERVICE" || true

systemctl stop 会中断指定服务,执行前应确认已经有可用备份,并记录服务当前状态。若停止失败,不要立即强制终止进程,先查看服务日志和进程状态。

确认服务和写入任务都停止后,再执行最终同步。只有当新目录是旧目录的准确镜像,并且已经确认目标盘内容可以被覆盖或删除时,才使用 --delete:

sudo rsync -aHAXS \
  --numeric-ids \
  --delete \
  --info=progress2 \
  "$OLD_MOUNT"/ "$STAGE_MOUNT"/

--delete 会删除目标目录中源目录不存在的文件,影响范围仅限于目标路径,但误选路径会造成数据丢失。执行前必须核对源、目标、备份和目录末尾的 /。如果不需要同步源端删除记录,可以去掉 --delete,但目标盘可能保留源端已经删除的旧文件。

最终同步完成后,可以做内容和元数据核对:

sudo rsync -aHAXS \
  --numeric-ids \
  --checksum \
  --dry-run \
  --itemize-changes \
  "$OLD_MOUNT"/ "$STAGE_MOUNT"/

--checksum 会读取文件内容进行比较,数据量较大时可能增加 I/O 和校验时间。重要数据还应使用应用自身的校验、数据库一致性检查或备份恢复验证,不要只依赖目录大小相同。

切换挂载点并保持旧盘可回退

先保存挂载配置

在改动 /etc/fstab 前,先保存副本,并记录旧盘 UUID:

sudo cp -a /etc/fstab /etc/fstab.before-nvme-migration

lsblk -f
findmnt -no SOURCE,FSTYPE,OPTIONS /srv/app-data

然后使用 sudoedit 修改挂载配置,将业务挂载点指向新盘 UUID。示例仅表示格式,文件系统类型和挂载选项必须替换为实际值:

UUID=REPLACE_WITH_NEW_UUID /srv/app-data ext4 defaults 0 2

不要直接套用旧盘的设备名,因为设备名可能在重启或重新挂载后发生变化。也不要在不了解含义的情况下复制旧盘的全部挂载选项。修改后先检查配置:

sudo findmnt --verify --verbose

执行切换

确认服务已停止、最终同步完成,并且新旧盘的 UUID 都已记录。先卸载临时挂载,再卸载旧盘:

sudo umount /mnt/nvme
sudo umount /srv/app-data

如果卸载提示目录繁忙,先查找占用进程:

sudo fuser -vm /srv/app-data

不要在没有确认进程和数据状态的情况下使用强制卸载。处理完占用后重新卸载。强制卸载可能让应用看到不完整的数据状态,也会增加回退难度。

挂载新盘:

sudo mount /srv/app-data
findmnt -T /srv/app-data
df -hT /srv/app-data

如果挂载失败,不要格式化新盘,也不要删除旧盘。先检查 UUID、文件系统类型、挂载参数和内核日志:

lsblk -f
sudo journalctl -k -b --no-pager -n 100

只有确认挂载点显示的是新盘,并且文件系统容量、可用空间和挂载参数正确后,才进入服务启动阶段。

切换后的成功验证

验证顺序建议从存储层、权限层、应用层到性能层逐步进行。

存储和权限验证

findmnt -T /srv/app-data
lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINTS,UUID
df -hT /srv/app-data
df -ih /srv/app-data

检查关键目录的属主、权限、ACL 和扩展属性:

sudo stat /srv/app-data
sudo namei -l /srv/app-data

应用使用的账号必须能够按原有方式读取和写入。可以使用业务账号创建临时文件进行验证,但路径和文件名必须是明确的测试对象:

APP_USER="app"
TEST_FILE="/srv/app-data/.migration-write-test"

sudo -u "$APP_USER" sh -c "printf '%s\n' migration-test > '$TEST_FILE'"
sudo -u "$APP_USER" cat "$TEST_FILE"
sudo rm -f -- "$TEST_FILE"

上述删除命令只应在确认变量指向本次创建的测试文件后执行。如果应用账号、目录或权限模型不同,应使用实际业务账号和测试路径,不要用 root 写入来代替应用权限验证。

应用和数据验证

启动服务前,先确认配置中的数据路径没有变化,或者新挂载点已经保持原路径:

sudo systemctl start "$APP_SERVICE"
sudo systemctl is-active "$APP_SERVICE"
sudo journalctl -u "$APP_SERVICE" -n 100 --no-pager

随后验证:

  • 应用能否正常启动;
  • 既有文件是否可读取;
  • 新文件是否能写入;
  • 数据库或应用自身的一致性检查是否通过;
  • 后台任务是否能正常执行;
  • 备份程序是否仍能找到目录;
  • 监控是否识别新设备和新挂载点。

如果应用有内部健康检查,应使用实际的本地检查地址,例如:

curl -fsS http://127.0.0.1:REPLACE_WITH_PORT/health

端口和路径必须替换为业务真实配置,不能把示例地址当成通用接口。

重新记录性能

服务恢复后,在与迁移前相近的业务负载下重新观察:

iostat -xz 1

对比迁移前后的应用延迟、错误率、数据库提交等待、I/O 等待和任务完成时间。只有在真实业务指标改善,或者已明确解决原有存储瓶颈时,才能认为迁移收益成立。新盘的 fio 结果高于旧盘,并不代表所有业务都会按相同比例提升。

失败时如何回退

适合立即回退的情况

出现以下情况时,应优先停止写入并考虑回退:

  • 新盘无法稳定挂载或出现 I/O 错误;
  • 文件数量、关键文件校验或数据库一致性检查不通过;
  • 应用启动失败,且原因明确与路径、权限或文件系统有关;
  • 迁移后延迟和错误率明显恶化;
  • 新盘的持久化、快照或备份能力不满足业务要求;
  • 业务观察期内出现持续的读写异常。

回退前先停止应用和所有写入任务:

sudo systemctl stop "$APP_SERVICE"
sudo fuser -vm /srv/app-data

确认没有写入进程后,卸载当前挂载的新盘:

sudo umount /srv/app-data

然后将 /etc/fstab 中的挂载项恢复为旧盘 UUID,再挂载旧盘:

sudoedit /etc/fstab
sudo findmnt --verify --verbose
sudo mount /srv/app-data
findmnt -T /srv/app-data
df -hT /srv/app-data

最后进行关键文件、权限和应用检查,确认旧盘可用后再启动服务。旧盘在确认迁移成功前不要格式化、删除或交还平台。

明确回退截止点

回退并不是任意时刻都能无损完成。新盘切换后,如果应用已经在新盘产生了新订单、新文件、日志或数据库事务,旧盘就会落后于新盘。此时直接挂回旧盘会丢失切换后的新增数据。

因此,迁移前应预先确定回退截止点:

  • 在服务启动前发现挂载或校验问题,通常可以直接回退;
  • 服务启动但尚未接受业务写入时,仍可快速回退;
  • 服务已经产生新写入后,必须先保留新盘,结合数据库备份、业务导出或一致性复制方案处理数据差异;
  • 不要同时让新旧两块盘以可写方式承载同一份业务数据,避免形成无法判断的双向差异。

如果回退过程中发现目录繁忙、数据校验失败或设备异常,不要反复强制卸载和覆盖写入。先保留现场,记录内核日志、应用日志、挂载状态和新旧盘 UUID,再决定是恢复旧盘、从备份恢复,还是重新执行一次受控迁移。

什么时候应继续升级,而不是停在 NVMe 迁移

迁移完成后,如果磁盘等待时间下降但业务延迟没有改善,说明瓶颈可能已经转移到 CPU、内存、数据库锁、连接池、应用线程或网络,此时继续提高磁盘规格未必有效。

如果新盘仍然出现队列堆积,应进一步核对云平台公布的 IOPS、吞吐和并发限制,以及应用实际的并发度和 I/O 模式。若业务数据持续增长、日志和临时文件挤占空间,升级容量或重新规划目录也应与性能升级分开评估。

只有在以下条件同时成立时,才适合扩大迁移范围或继续提升配置:

  • 新 NVMe 盘在实际业务中稳定改善了关键延迟指标;
  • 备份、快照和恢复流程已经验证;
  • 应用、数据库和文件系统兼容性没有异常;
  • 停机窗口能够覆盖最终同步和验证;
  • 旧盘或可恢复备份仍然保留;
  • 新增的性能和容量确实对应业务增长,而不是只根据接口名称或压测峰值采购。
目录结构
全文