用dnf更新系统时,最直观的痛点就是下载量。一次常规的内核加基础库更新,动辄几百兆流量,如果身处网络环境不佳的场景,更新一次系统可能要等上半个小时。Fedora其实早就内置了解决这个问题的机制,就是deltarpm增量更新。它的思路很直接:既然新包和旧包绝大部分内容是一样的,那为什么每次都要下载完整的RPM?只下载差异部分,在本地把完整包拼出来,下载量自然就下来了。

deltarpm的工作原理:差异是怎么算出来的
要理解deltarpm,得先知道它操作的对象是什么。RPM包本质上是一个cpio归档加上元数据的容器,包里的每个文件以压缩后的形式存放。deltarpm工具会先在服务端完成一次预处理:把旧版本RPM和新版本RPM分别解开、解压,对两份文件树做逐文件比对,然后基于二进制差异算法(类似bsdiff的思路)生成一个delta文件。这个delta文件记录了从旧包内容变换到新包内容所需的全部信息。
客户端这边的过程正好相反。dnf下载到delta文件后,先用本机已安装的旧版RPM还原出解压后的文件树,再把delta中记录的差异应用上去,得到新版本的文件树,最后重新压缩、重打RPM头部信息,组装出一个和官方发布的一模一样的RPM包。组装完成后,后续的安装流程和普通RPM没有任何区别,rpm数据库照常记录,文件校验值也完全一致。
这里有一个关键点值得注意:deltarpm省的是下载带宽,花的是本地CPU。解压、打差异、再压缩这三步都是计算密集型操作,尤其在重新压缩阶段,如果开启高压缩级别,耗时可能相当可观。这就是为什么有些用户在配置了deltarpm之后反而觉得更新变慢了——下载确实变短了,但本地合成时间拉长了。在CPU较弱的旧机器上,这个权衡需要仔细掂量。
如何在dnf中开启和配置deltarpm
现代Fedora发行版中,deltarpm支持默认是开启的。确认当前状态可以用下面的命令查看主配置文件。dnf的增量更新行为由/etc/dnf/dnf.conf中的两个参数控制:一个负责总开关,另一个决定性能取舍的阈值。
# 查看当前deltarpm相关配置 grep -i delta /etc/dnf/dnf.conf # 编辑主配置文件 sudo vi /etc/dnf/dnf.conf
在dnf.conf的[main]小节中加入或确认以下两行:
[main] deltarpm=true deltarpm_percentage=75
deltarpm=true是功能开关,设为false则dnf会忽略所有delta文件,直接下载完整RPM。真正有意思的是deltarpm_percentage这个参数。它表示一个比例上限:只有当delta文件的大小估计不超过完整RPM大小的这个百分比时,dnf才会选择走增量路径。默认值75意味着如果差异部分超过完整包的四分之三,下载delta就不划算了,因为合成它还要额外消耗CPU。网络越慢、机器CPU越强,可以把这个值调得越大,比如设成90甚至100,更积极地利��增量;反之在网络快但机器弱的场景,调低到50左右更合适。
另外要确保系统安装了deltarpm相关的处理工具链。虽然dnf自身内置了对delta元数据的解析能力,但createrepo_c等工具在某些依赖场景下也需要到位。检查方式很简单:
# 确认deltarpm工具已安装 rpm -q deltarpm # 如未安装则补装 sudo dnf install deltarpm
配置完成后,执行sudo dnf upgrade时如果软件仓库提供了delta文件,dnf会在下载阶段显示delta的大小和节省的流量,输出信息里能明显看到每个包的下载量比平时小很多。
deltarpm不生效的常见原因排查
实际使用中最常见的困惑是:配置明明写了deltarpm=true,为什么更新时还是下载了完整包?原因主要有三个层面。第一是仓库端不支持。delta文件必须由镜像服务器提供,如果官方仓库在某个版本周期没有生成delta,或者你使用的第三方镜像没有同步delta目录,客户端再怎么配置也没用。可以用dnf repoinfo查看仓库详情,或者直接在浏览器访问镜像的repodata目录确认是否存在drpm相关文件。
第二是版本跨度问题。delta文件只针对相邻版本之间的升级生成,如果你的系统某个包落后了好几个版本,服务端往往没有从你的旧版本直接到最新版本的delta,dnf只能回退到下载完整RPM。这也是长时间不更新系统后,第一次大更新总是全量下载的原因。
第三是本地缓存和元数据问题。有时仓库元数据缓存过期会导致dnf看不到delta信息,清理后重新载入即可解决:
# 清理dnf元数据缓存后重试 sudo dnf clean all sudo dnf makecache sudo dnf upgrade
还有一种容易被忽略的情况是磁盘空间。合成RPM需要临时空间存放解压后的文件树,如果/var/cache/dnf所在分区空间吃紧,dnf会静默放弃增量路径。保持几GB的可用空间是稳妥的做法。排查时可以加上-v参数运行dnf,详细输出里会明确写出每个包是选择了drpm还是完整RPM,以及做出该选择的原因。
综合来看,deltarpm是一个对网络敏感用户非常友好的特性,配置成本几乎为零,理解了deltarpm_percentage的取舍逻辑之后,还能根据自己机器的实际情况做精细调优。配合Fedora默认开启的max_parallel_downloads多线程下载,弱网环境下的系统更新体验会有明显改善。