← Home
最近接到一个需求,服务器上使用 rsync 同步文件速度太慢,tutor 说试试 redis 加快一下速度。一开始我有点懵,文件同步如何做到比 rsync 更快呢,那可是诞生于1996年的古董级软件啊😦。
研究一番之后发现还真有可能。
图片来源:rsync, article 3: How does rsync work? (2022)
大家知道 rsync 的特点是可以做增量同步,增量同步体现在两个方面,一是文件列表上的增量,就是找出哪些文件需要更新。二是在更新某个文件的时候,不是简单的复制和覆盖,而是将源文件和目标文件切成分片,计算每个分片的 checksum,然后只更新不同的分片。
原理很简单,具体细节可以参考 How Rsync Works A Practical Overview 和 rsync, article 3: How does rsync work? (2022)。
弄清楚 rsync 的工作原理之后,一开始我是懵的,根本想不出还有比 rsync 更快的同步方法。后来又跟 tutor 确认了一下细节,才发现原来是 rsync 的文件列表生成太慢了,文件同步本身倒是很快。
谷歌一下,发现早有人身受其害,Large Directory Causes ls to "Hang",Moving 2TB (10 mil files + dirs), what's my bottleneck?。
简单说就是,Linux 上 ls
默认是按字母表排序的,就得把全部文件信息读到内存中,经历漫长的排序之后才能输出。如果文件数量太多,那就会很慢。Large Directory Causes ls to "Hang" 这篇文章的作者使用 300 万文件测试,结果显示有一万倍的性能差距。
不信,你可以使用 ls
和 ls -1 -f
试试。
文件同步的本质是找到最近更新的文件,然后把它同步到目标机器上。所以,如果能够快速找到最近更新的文件,那么同步的速度就会快很多。
因此我们打算使用 Redis 的 sorted set,把文件名作为 key,文件的更新时间作为 score,这样就可以快速找到最近更新的文件了。本质是把排序功能放在 Redis 里了。
不过这只是理论上可能,实际还没测试过。
ps:tutor说有个 redis 的竞品,叫 dragonflydb,号称比 redis 快很多可以试试。