cache=none不等于最高安全性,它仅绕过宿主机页缓存、提供低延迟随机I/O,但若未配合aio=native、discard=on及virtio-scsi等配置,且Guest未执行fsync或遇断电,仍会导致数据丢失。

直接结论:cache=none 本身不提供“最高安全性”,它提供的是高一致性 + 高性能随机 I/O,但需配合其他配置才能避免数据丢失风险。单独设为 cache=none 不等于“最安全”,反而可能因忽略刷盘指令导致意外丢数据。
为什么 cache=none 不等于最高安全性
cache=none 的本质是启用 O_DIRECT 标志,绕过宿主机 page cache,让 QEMU 直接读写块设备。它不缓存、不重排、不合并写请求,所以:
- 写入延迟低(数据进内核队列即返回),但不保证落盘完成;
- 若 Guest 内核没发
fsync或BLKFLSBUF,或宿主机突然断电,未刷入磁盘的数据会丢失; - 它比
writethrough快,但安全性略低——writethrough强制每次写都等物理落盘,none只等进设备队列。
要让 cache=none 真正可靠,必须配齐这三项
单设 cache=none 是半截子优化。真正落地时,缺一不可:
-
aio=native:启用 Linux io_uring 或 POSIX AIO,避免线程池阻塞,保障 I/O 路径不引入额外延迟和缓存; -
discard=on(或discard=unmap):让 Guest 发出 TRIM/UNMAP 指令能透传到底层 SSD,维持长期写性能与寿命; -
cache=none,aio=native,discard=on必须和virtio-scsi控制器搭配使用——IDE 和 virtio-blk 对 discard 支持不完整,容易静默失效。
在 PVE8 / libvirt 中实际怎么写配置
不要依赖 Web 界面默认值。PVE8 的 /etc/pve/qemu-server/100.conf 或 libvirt 的 XML,必须显式声明驱动参数:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
<disk type="block" device="disk"><driver name="qemu" type="raw" cache="none" io="native" discard="unmap"></driver><source dev="/dev/vg0/vm100-disk"></source><target dev="sda" bus="scsi"></target></disk>
注意点:
- 后端必须是裸块设备(如
/dev/vg0/lv或/dev/nvme0n1p1),不能是文件(如/var/lib/vz/images/100/disk-0.qcow2); -
type='raw'是硬性要求:qcow2 在cache=none下无法保证元数据原子性,易损坏; - 如果用 LVM,确保逻辑卷已禁用 write barrier:
lvchange --discards passdown /dev/vg0/vm100-disk。
最容易被忽略的底层陷阱
很多人调完 cache=none 就以为万事大吉,结果压测时发现 IOPS 上不去、延迟抖动大。问题往往出在:
- 宿主机文件系统层没绕开:镜像放在 ext4 上,即使
cache=none,仍要走 VFS 层、journal、ext4 buffer head,I/O 路径没真正变短; - NVMe 设备调度器没关:
echo none > /sys/block/nvme0n1/queue/scheduler,否则 mq-deadline 会引入排队延迟; - Guest 内没装
qemu-guest-agent:无法响应 host 的 fsync 请求,cache=none下的 flush 行为可能被跳过。
真正的“安全”不是靠一个参数,而是整条 I/O 路径上每个环节都明确知道自己的责任边界——Host 不缓存,Guest 主动刷,设备不耍花招。










