5000 个 1KB 文件搬运实测:你的 cp/rsync 对比,可能测的是内存而不是磁盘

举报
yd_276135645 发表于 2026/11/10 06:09:15 2026/11/10
【摘要】 冷热缓存下的 cp/rsync/tar 管道实测对比:热缓存下 tar 快 20%、rsync 慢 80%,冷缓存下三个工具挤在 3.6~3.9 秒且顺序反转。附带增量同步(rsync 快 5 倍)与元数据成本(5000 个 1KB 比 1 个 5MB 慢 14 倍)两组数据,以及 drop_caches 测性能的正确姿势。

5000 个 1KB 文件搬运实测:你的 cp/rsync 对比,可能测的是内存而不是磁盘

「小文件用 tar 管道比 cp 快」「rsync 比 cp 慢」——这类结论在网上流传很广,但大多数实测都有一个共同缺陷:没清页缓存。第二次跑的命令测的是内存带宽,不是磁盘。我用同一台机器、同一批文件,把热缓存和冷缓存分开测了一遍,结论和流传的版本不太一样。

实验设置

  • 5000 个 1KB 文件,分散在 50 个目录里,总计 5MB
  • ext4(/dev/sda1),每次跑 3 遍取中位数
  • 冷缓存用 sync; echo 3 > /proc/sys/vm/drop_caches
  • 目标目录每次跑前清空,避免「覆盖已有文件」混进结果

第一组:热缓存(大多数人实际在测的东西)

cp -r            0.133 s
tar -cf - | tar  0.125 s
cp -a            0.153 s
rsync -a         0.229 s

看起来 rsync 慢了 80%,tar 管道赢了 cp -a 约 20%。但请注意这批数字的绝对量级:0.13 秒搬完 5MB,折算 38 MB/s 以上——这个速度里磁盘几乎没参与,数据全在 page cache 里。

第二组:冷缓存(每个命令都从盘上读)

rsync -a         3.630 s   (3.801 / 3.630 / 3.623)
cp -a            3.854 s   (3.854 / 3.694 / 3.920)
tar -cf - | tar  3.920 s   (3.920 / 3.982 / 3.919)

三个工具挤在 3.6–3.9 秒之间,最大差距 8%,而且顺序完全反了:热缓存下最慢的 rsync 在冷缓存下最快,热缓存下最快的 tar 管道排到了最后。

这不是工具的性能变了,而是你测的东西变了。冷缓存下瓶颈是「每个文件一次 open/stat/read」的元数据开销,谁少一次系统调用谁赢;热缓存下瓶颈是内存拷贝和进程调度,差距被放大成看起来很有意义的百分比。

同一批命令,换个缓存状态,冠军就换人。 所以任何不带 drop_caches 的 cp/rsync 横评,结论只在「源目录刚被写过」这个前提下成立。

第三组:元数据才是真正的成本

同样是搬 5MB:

1 个 5MB 文件      0.011 s
5000 个 1KB 文件   0.153 s

字节数一样,小文件慢了 14 倍。这不是 I/O 带宽问题,是 5000 次目录项查找、inode 分配、权限拷贝。推论很直接:如果你的目录里全是几十 KB 的小文件,优化方向不是换工具,而是减少文件数(打包、合并日志、归档冷数据),任何工具选择都只在 8% 这个量级上折腾。

第四组:增量同步,rsync 才真正拉开差距

前面三组 rsync 都不占优,但它的价值不在首次搬运。往已有副本里改 10 个文件,再同步一次:

rsync -a   0.071 s
cp -a      0.367 s

rsync 快 5 倍。原因有两个:它按 size+mtime 跳过未变文件;而 cp 不但全量重写,还要对已存在的目标文件做截断再写,比写新文件更慢——注意 cp -a 在这一组里从 0.153 秒涨到了 0.367 秒,同一命令、同一数据量,只因目标已存在。

怎么选

  • 一次性搬大目录、源数据刚写过:tar -C src -cf - . | tar -C dst -xf -,简单且不比谁慢
  • 重复同步(部署、备份、重跑流水线):rsync -a,增量场景 5 倍差距,前面那 8% 不值得计较
  • 文件数极多(十万级):先想能不能打包,tar 归档比任何逐文件拷贝都快一个数量级
  • 测性能:先 sync 再 drop_caches,跑 3 次取中位数。否则你测的是内存速度,还会得出互相矛盾的结论

最后一个提醒:drop_caches 是全局操作,会把整机缓存清空,生产机上别随手跑。要测就测在隔离环境里——我这次是在一块只放测试数据的 scratch 目录上做的,跑完顺手删掉,不留在业务盘上。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。