news 2026/10/20 22:52:26

Linux VDO 去重压缩实战:原理、搭建与避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux VDO 去重压缩实战:原理、搭建与避坑指南

1. 从一块总是写满的磁盘说起

如果你管过几台跑着数据库或者日志服务的机器,大概率遇到过这种场景:一块 2TB 的盘,实际存进去的业务数据也就三四百个 G,但df -h一看,使用率已经飙到 80% 以上了。删了一批旧文件,空间释放得又慢又少,最后只能加盘或者迁移。这种"空间去哪儿了"的问题,很多时候不是数据真的多,而是重复数据和稀疏文件在悄悄吃掉容量。

VDO,全称 Virtual Data Optimizer,就是冲着这个问题来的。它是 Linux 平台上的一套存储层技术,工作在块设备之上、文件系统之下,核心干两件事:去重和压缩。你可以把它理解成一个"存储空间的中间商"——上层文件系统以为自己在往一块大硬盘里写,实际上 VDO 在背后把重复的块合并、把能压的块压掉,最终落到物理盘上的数据量可能只有原来的几分之一。

这篇内容适合谁看?一类是手里有虚拟化平台、容器镜像仓库、备份存储的运维,这类场景重复数据多,VDO 收益最明显;另一类是刚接触 Linux 存储栈、想搞清楚 LVM、设备映射、文件系统之间还能插进什么层的人。我会从 VDO 到底怎么工作讲起,然后一步步带你把它搭起来、用起来,最后重点聊那些文档里不太写、但实际会踩的坑。全程基于常见的 RHEL 系发行版实践,命令可以直接抄。

需要先说明一点:VDO 不是"免费的午餐",它用 CPU 换空间,用一层抽象换容量。搞清楚它的边界,比会敲几条命令重要得多。

2. VDO 到底在存储栈的哪一层动手

2.1 去重和压缩是两件不同的事

很多人把 VDO 简单理解成"压缩",这不太准确。它内部其实是两条独立的流水线:

去重(Deduplication)针对的是"内容相同的块"。VDO 把落到它上面的数据切成固定大小的块(默认 4KB),对每个块算一个指纹(哈希),然后拿指纹去索引里查:这个块之前是不是存过?存过就直接引用已有的物理块,不再写一份。所以去重的前提是数据有重复——同一份镜像被复制了十次、同一批日志模板反复出现,这种场景去重率能到 10:1 甚至更高;反过来,如果存的全是加密后的随机数据,去重基本没收益。

压缩(Compression)针对的是"单个块内部能不能变小"。VDO 默认用 LZ4 算法,对每个块独立压缩。文本、日志、部分二进制数据压缩效果不错,已经压过的格式(比如 JPEG、zip)再压就没意义了。

这两条流水线的顺序是先去重、后压缩。逻辑也说得通:先看这个块是不是重复的,重复的直接省掉;不重复的再试着压一压。

2.2 它在设备映射里的位置

VDO 是基于device mapper实现的一个目标(target),叫dm-vdo。所以它在存储栈里的位置很清晰:

应用 / 文件系统(XFS、ext4) ↓ VDO 卷(一个块设备,比如 /dev/mapper/vdo0) ↓ dm-vdo 目标(去重 + 压缩) ↓ 底层物理设备(可以是分区、LVM 逻辑卷、甚至另一层 RAID)

关键点在于:VDO 呈现给上层的是一个"逻辑块设备",这个设备的逻辑大小可以远大于底层物理设备。比如你给它一块 1TB 的物理盘,可以对外宣称这是一块 10TB 的 VDO 卷。这不是虚标,而是因为去重压缩后实际占用会小很多,VDO 用"逻辑大小"来容纳这些被优化过的数据。当然,如果实际数据真的涨到超过物理容量,就会出问题——这个后面单独讲。

2.3 为什么是"块级"而不是"文件级"

市面上也有文件级的去重方案,VDO 选择块级是有取舍的。块级的好处是对上层透明:不管上面跑的是 XFS、ext4 还是别的,VDO 都一视同仁,它根本不关心文件系统怎么组织数据,只认块。坏处是它看不到文件语义,没法做"这个文件删了所以相关块可以回收"这种判断,只能靠块本身的内容和引用计数。

理解这一点很重要,因为它直接解释了一个常见困惑:为什么删了文件,VDO 的空间没马上回来?因为 VDO 层面看到的是块被改写了,它需要等这些块不再被引用,才会真正释放物理空间。这个回收是有延迟的,后面会细说。

3. 动手之前:容量规划和参数怎么定

3.1 逻辑大小不是拍脑袋定的

创建 VDO 卷时有两个尺寸概念必须分清:

  • 物理大小(physical size):底层实际给它的空间,比如 1TB。
  • 逻辑大小(logical size):对外呈现的大小,比如 10TB。

逻辑大小和物理大小的比值,决定了 VDO 内部索引结构要预留多少元数据空间。VDO 需要维护一张"块指纹 → 物理位置"的映射表,这张表本身要占空间。逻辑大小越大,表越大。

经验上,逻辑大小不要超过物理大小的 10 到 20 倍。超过这个范围,元数据开销会变得很夸张,而且一旦实际数据量逼近物理容量,你会非常被动。我一般按预期去重压缩比来倒推:如果估计能压到 3:1,那 1TB 物理盘对外给 3TB 逻辑大小就够了,留点余量给突发增长。

3.2 索引模式的选择

VDO 的索引(index)负责存指纹映射,有两种模式:

模式特点适用场景
同步索引(sync)写数据时同步更新索引,一致性更强对数据安全要求高、写入不密集
异步索引(async)索引更新异步进行,性能更好写入量大、能接受一定风险

异步模式性能明显更好,但机器异常掉电时,最近的索引更新可能丢失,导致部分去重信息失效(数据本身不丢,只是去重率下降)。生产环境里如果对性能敏感,通常选异步,然后配合 UPS 或者定期同步来兜底。

3.3 块大小和压缩的取舍

VDO 默认块大小 4KB,这个值一般不用改。块太小,索引条目爆炸,元数据吃空间;块太大,去重粒度变粗,小文件场景收益下降。4KB 是个平衡点。

压缩默认开启,算法 LZ4。LZ4 的特点是快,压缩比一般,但对存储层来说延迟比压缩比更重要。如果你的数据是高度可压的文本,可以考虑更激进的算法,但大多数场景 LZ4 够用。

提示:规划阶段一定要先想清楚"这块盘上跑的是什么数据"。虚拟化镜像、容器层、备份归档——这三类去重收益最高;数据库数据文件、已加密数据、视频素材——收益很低甚至为负(白白消耗 CPU)。

4. 从裸盘到可用 VDO 卷的完整搭建

4.1 环境准备和软件安装

先确认内核支持 dm-vdo。较新的 RHEL 系发行版(8 及以上)默认带,老版本可能需要额外装模块。检查一下:

modinfo dm-vdo

有输出说明模块在。然后装管理工具:

# RHEL/CentOS 系 dnf install -y vdo kmod-kvdo # 确认版本 vdo version

装完加载模块:

modprobe dm-vdo lsmod | grep vdo

4.2 创建 VDO 卷

假设底层用/dev/sdb这块 1TB 的盘。先别急着直接用它,建议在它上面建个 LVM 逻辑卷再给 VDO,这样以后扩容、迁移都灵活。不过为了讲清楚,这里先用裸盘演示,后面再说 LVM 的玩法。

# 基本创建:物理 1TB,逻辑 3TB,异步索引,开压缩 vdo create \ --name=vdo0 \ --device=/dev/sdb \ --vdoLogicalSize=3T \ --indexMem=0.5 \ --blockMapCacheSize=128M \ --writePolicy=async \ --compression=on

几个参数解释一下:

  • --vdoLogicalSize=3T:对外逻辑大小 3TB。
  • --indexMem=0.5:给索引分配 0.5GB 内存。这个值影响能缓存多少指纹映射,太小会导致频繁读盘查索引,性能掉得厉害。一般按每 TB 逻辑大小配 0.25 到 0.5GB 估。
  • --blockMapCacheSize=128M:块映射缓存,也是性能相关。
  • --writePolicy=async:异步写策略。

创建完看一下状态:

vdo status --name=vdo0

重点看Deduplication、Compression是不是 enabled,以及Logical size、Physical size对不对。

4.3 格式化并挂载

VDO 卷创建好后,会出现一个设备/dev/mapper/vdo0。像对待普通块设备一样格式化:

mkfs.xfs /dev/mapper/vdo0 mkdir -p /data mount /dev/mapper/vdo0 /data

写进/etc/fstab让它开机自动挂载:

/dev/mapper/vdo0 /data xfs defaults 0 0

注意:VDO 卷的挂载要确保 VDO 服务先起来。用 systemd 管理的话,vdo.service会处理依赖,但如果你手动写 fstab,最好加上x-systemd.requires=vdo.service之类的依赖,避免开机时设备还没就绪就挂载失败。

4.4 验证去重压缩是否真的生效

搭完别急着上业务,先做个验证。往/data里写一份有重复内容的数据,看 VDO 的统计:

# 写 1GB 的重复数据 dd if=/dev/zero of=/data/test1 bs=1M count=1024 cp /data/test1 /data/test2 cp /data/test1 /data/test3 # 看 VDO 统计 vdostats --human-readable

vdostats会输出几个关键指标:

指标含义
1K-blocks逻辑大小
Used实际占用的物理空间
Available剩余物理空间
Used%物理使用率
Saving%节省比例
Write policy写策略

如果三份 1GB 的相同数据写进去,Used应该只涨了 1GB 左右,Saving%会很高。这就说明去重在工作。如果 Saving% 一直是 0,那要么数据本身没重复,要么配置有问题。

5. 那些文档不写、但一定会踩的坑

5.1 空间"删了不还"的真相

这是 VDO 被吐槽最多的一点。你删了一大批文件,df看文件系统层面空间是回来了,但vdostats里Used几乎没动。原因在于:VDO 是块级的,它不知道文件被删了。文件系统删除文件,只是把对应的块标记为"可复用",并没有通知 VDO 这些块可以回收。VDO 要等到这些块被新数据覆盖,才会重新计算指纹、释放旧的物理块。

那怎么主动回收?VDO 提供了fstrim支持。前提是文件系统支持 discard,并且挂载时开启了。XFS 默认支持,但要在挂载选项里加discard,或者定期手动跑:

# 手动触发 TRIM,让文件系统告诉 VDO 哪些块空了 fstrim -v /data

跑完之后再看vdostats,Used会下降。但要注意,fstrim对 VDO 来说不是"立即释放",它只是把块标记为空,VDO 后台还需要时间处理。而且频繁 TRIM 对性能有影响,生产环境一般用定期任务(比如每周一次)而不是挂载时开discard。

提示:如果你的业务是"写多删少"型(比如日志归档),空间回收压力不大;如果是"反复覆盖"型(比如镜像仓库不断推新版本删旧版本),一定要配好 TRIM,否则物理盘会被慢慢撑满。

5.2 物理空间真的满了会怎样

前面说逻辑大小可以远大于物理大小,但这有个前提:实际数据量不能超过物理容量。一旦去重压缩后的数据把物理盘写满,VDO 会进入只读或者报错状态,上层文件系统跟着出问题。

这个坑的隐蔽性在于:df看逻辑卷还有大量空间,但底层已经满了。所以监控 VDO 一定要看vdostats的Used%,而不是只看df。我一般会设两级告警:物理使用率 70% 预警,85% 严重告警,留出处理时间。

真满了怎么办?最直接的是加物理盘扩容。VDO 支持在线扩容物理层:

# 假设底层是 LVM,先扩 LV lvextend -L +500G /dev/vg0/vdo_pool # 然后扩 VDO 物理层 vdo growPhysical --name=vdo0

5.3 内存和 CPU 的隐性成本

VDO 不是零成本的。去重要做哈希计算,压缩要跑 LZ4,这些都要 CPU。索引要常驻内存,逻辑卷越大、去重率越高,内存需求越大。一台跑 VDO 的机器,如果索引内存给少了,会频繁触发索引换入换出,性能断崖式下跌。

实测经验:每 TB 逻辑大小预留 0.5GB 到 1GB 内存比较稳妥。如果机器内存紧张,宁可把逻辑大小调小,也别把索引内存压太狠。CPU 方面,去重压缩是并行的,多核机器收益明显,单核老机器上 VDO 可能成为瓶颈。

5.4 和 LVM、RAID 的叠加顺序

VDO 可以和 LVM、RAID 组合,但顺序有讲究。推荐的结构是:

RAID(物理冗余) ↓ LVM 逻辑卷(灵活扩容) ↓ VDO(去重压缩) ↓ 文件系统

也就是VDO 放在 LVM 之上、文件系统之下。这样 LVM 负责底层空间的灵活管理,VDO 专注优化。反过来把 VDO 放在 RAID 下面(先 VDO 再 RAID)通常没意义,因为 RAID 会复制数据,去重收益被抵消。

6. 性能调优和日常维护的几个抓手

6.1 索引内存和缓存怎么调

如果发现 VDO 性能不理想,先看索引命中情况。vdo status里有一些统计,但更直接的是观察系统 IO:如果 VDO 底层盘持续有大量随机读,很可能是索引缓存不够,在反复读盘查映射。

调整索引内存需要重建卷(因为索引结构在创建时确定),所以规划阶段就要给够。块映射缓存(block map cache)倒是可以运行时调:

vdo setBlockMapCacheSize --name=vdo0 --blockMapCacheSize=256M

加大缓存能减少元数据读盘,但吃内存。一般 128M 到 256M 是常见区间。

6.2 什么时候该关掉去重或压缩

不是所有场景都适合全开。举两个反例:

  • 存已加密数据:加密后数据块几乎无重复,去重白算哈希,纯浪费 CPU。这种场景可以只开压缩或者全关。
  • 存视频、图片素材:本身已压缩,VDO 再压收益极低,去重也难命中。这种盘干脆别用 VDO,直接裸盘或 RAID。

关掉某个功能:

vdo disableDeduplication --name=vdo0 vdo disableCompression --name=vdo0

反过来也能开。但注意,开关去重会影响已有数据的索引,切换后可能需要一段时间重新整理。

6.3 监控要看哪些指标

日常巡检 VDO,我固定看这几项:

指标命令关注点
物理使用率vdostats超过 85% 要处理
节省比例vdostats突然下降说明数据特征变了
写策略vdo status确认没被意外改回 sync
索引状态vdo status看是否有异常
底层盘健康smartctlVDO 不解决硬件故障

把这些接进监控系统,比出事之后再查强得多。

6.4 升级和迁移的注意事项

VDO 卷迁移到别的机器,不能简单dd底层盘就完事,因为索引和元数据是绑定的。正确做法是用vdo工具导出导入,或者干脆在新机器上重建、用文件级同步迁移数据。

升级内核或 VDO 版本前,先看发行版的 release notes,确认兼容性。升级后第一时间vdo status检查卷状态,别等业务报错才发现问题。

7. 我踩过的几个真实教训

说几个我自己在实际操作里栽过的跟头,比参数表更有参考价值。

第一个是逻辑大小给太贪。早期我给一块 2TB 的盘配了 20TB 逻辑大小,想着去重率高能撑住。结果业务数据比预期"不重复"得多,物理盘半年就快满了,而逻辑层还显示大量空闲。扩容时又发现索引内存当初按 20TB 配的,机器内存吃紧。后来学乖了,逻辑大小按保守估计给,宁可后面扩。

第二个是忘了配 TRIM。一个镜像仓库场景,天天推新镜像删旧镜像,物理盘使用率一路涨到 90% 多,df看逻辑卷才用了一半。查了半天才想起来没做空间回收。加上定期fstrim之后,使用率稳定在 60% 左右。

第三个是在错误的场景硬上 VDO。有次给一个存加密备份的盘配了 VDO,结果去重率接近 0,压缩也几乎没效果,白白多了一层开销,性能还降了。后来把 VDO 去掉,直接裸盘,反而更稳。这件事让我明白:VDO 是优化工具,不是万能药,用之前先判断数据特征。

最后一个偏细节:异步索引 + 非正常关机。有次机器断电,重启后 VDO 卷能起来,但去重率明显下降,因为最近的索引更新丢了。数据没丢,但空间效率受影响。后来给关键机器配了 UPS,并且定期做索引同步,才算稳下来。

8. 关于 VDO 适用边界的一点个人判断

用不用 VDO,我的判断标准其实很简单:看这块盘上的数据"重复度"和"可压性"高不高,以及你对 CPU、内存开销的容忍度。

虚拟化平台、容器镜像、开发测试环境、备份归档——这些场景重复数据天然多,VDO 收益明显,值得上。数据库主库、加密存储、多媒体素材库——这些场景收益低,硬上反而添乱。中间地带比如通用文件服务器,可以先小范围试,用vdostats观察实际节省比例,再决定要不要推广。

还有一点,VDO 解决的是"空间效率",不解决"数据安全"。它不做冗余,底层该 RAID 还得 RAID;它也不替代备份,去重后的数据一样会丢。把它放在存储栈里正确的位置,配合 LVM 做灵活管理、配合监控做容量预警,这套组合用起来才踏实。

如果你正准备在环境里引入 VDO,我的建议是先拿一块非关键盘做验证,把去重率、性能影响、空间回收这几件事摸清楚,再往生产推。存储这层的东西,改起来动静大,前期多花半天验证,能省后面很多麻烦。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/20 22:51:52

Ryu控制器北向接口实战:流表操作与多控制器信息互通

1. 从标题拆解这个项目的核心脉络“ryu--北向接口(流表的操作以及多控制器流表信息互通)”这个标题,第一次看到的时候,我脑子里浮现的是三个关键词:Ryu控制器、北向接口、流表互通。这三个词串起来,其实就是一个很典型的SDN实验场…

作者头像 李华
网站建设 2026/10/20 22:51:46

kinodynamic_rrt_star:动力学约束下的机器人轨迹规划实战

简介:本资源为Kinodynamic RRT 算法的MATLAB实现,对应Dustin J. Webb与Jur van den Berg的论文《Kinodynamic RRT : Optimal Motion Planning for Systems with Linear Differential Constraints》,面向从事机器人运动规划、最优控制与轨迹…

作者头像 李华
网站建设 2026/10/20 22:51:40

macOS下载器证书配置实战:5步解决HTTPS拦截验证失败

你是不是也遇见过这种情况:在macOS上装好某个带网络拦截功能的下载器,开开心心点了一个下载任务,结果任务列表里全是“证书验证失败”,浏览器每次访问正常HTTPS站点都跳警告。这个证书配置问题,听着像一次性的小操作&a…

作者头像 李华
网站建设 2026/10/20 22:50:55

CH634单芯片方案:USB3.2 Gen1 Hub与PD快充的硬件设计全解析

做过扩展坞的人都有个共同的痛:又要盯USB3.2 Gen1 Hub主控的选型,又要为PD快充单独找一颗协议芯片,两套控制器、两套电源管理,画原理图好不容易,调试的时候更是被CC线上的电平、VBUS的时序折腾到怀疑人生。CH634这颗芯…

作者头像 李华
网站建设 2026/10/20 22:50:52

鸿蒙应用邮箱验证码登录实战:AGC认证服务集成与踩坑记录

做鸿蒙应用开发一年多,最常被问到的就是“验证码登录怎么接”。手机号验证码虽然用户熟悉,但个人开发者要申请短信服务,资质审核、签名配置、计费问题一整套走下来非常折腾。后来我在某工具类应用里改用邮箱验证码登录,基于AGC&am…

作者头像 李华
网站建设 2026/10/20 22:50:36

AI辅助超导材料预测论文初稿实战指南

说实话,刚开始碰“AI赋予超导材料预测论文初稿”这个题目时,我脑子里冒出来的不是某个网络结构图,而是上半年那堆晶体结构文件和怎么也调不对的临界温度记录。做超导材料研究的人应该都有同感:想从几万种元素组合里挑出一个可能具…

作者头像 李华