一些无关的要点:
80K是很多文件。
一个目录中有80,000个文件?默认情况下,没有操作系统或应用程序能够很好地处理这种情况。您只是偶然发现rsync存在此问题。
检查您的rsync版本
现代rsync处理大型目录要比过去更好。确保您使用的是最新版本。
即使是旧的rsync也可以通过高延迟链接很好地处理大型目录...但是80k文件并不大...它很大!
也就是说,rsync的内存使用量与树中的文件数成正比。大目录占用大量RAM。速度缓慢可能是由于两边都没有RAM。在观察内存使用情况的同时进行测试。Linux使用任何剩余的RAM作为磁盘缓存,因此,如果RAM不足,则磁盘缓存会更少。如果RAM不足,并且系统开始使用swap,则性能将非常糟糕。
确保不使用--checksum
--checksum
(或-c
)需要读取每个文件的每个块。您可能可以通过仅读取修改时间(存储在inode中)的默认行为来解决。
将作业分成小批。
有一些像Gigasync这样的项目,它们将“通过使用perl递归目录树,构建较小的文件列表以通过rsync传输来增加工作量”。
额外的目录扫描将产生大量开销,但也许将是一次净赢。
没有为这种情况设置操作系统默认值。
如果您使用所有默认值的Linux / FreeBSD / etc,则所有应用程序的性能都会很糟糕。默认值假定目录较小,以免在超大缓存上浪费RAM。
调整文件系统以更好地处理大型目录:大型文件夹会降低IO性能吗?
看看“ namei缓存”
类似于BSD的操作系统具有一个高速缓存,该高速缓存可加快查找索引节点的名称的速度(“ namei”高速缓存”)。由于rsync在每个文件上执行lstat(),因此正在为80k文件中的每个文件访问inode,这可能会浪费您的缓存,请研究如何调整系统上文件目录的性能。
考虑不同的文件系统
XFS旨在处理更大的目录。查看单个目录中的文件系统大量文件
也许5分钟是您可以做的最好的事情。
考虑计算要读取的磁盘块数,并计算您期望硬件能够读取这么多块的速度。
也许您的期望太高了。考虑一下在不更改文件的情况下执行rsync必须读取多少磁盘块:每台服务器将需要读取目录并为每个文件读取一个索引节点。假设没有任何缓存,因为8万个文件可能已经耗尽了缓存。假设数学运算简单,需要80k块。那大约是40M的数据,应该在几秒钟内就能读取。但是,如果需要在每个块之间进行磁盘搜索,则可能需要更长的时间。
因此,您将需要读取大约80,000个磁盘块。您的硬盘驱动器可以做到多快?考虑到这是随机I / O,而不是长时间的线性读取,因此5分钟可能非常好。那是1 /(80000/600),或者每7.5ms读取一次磁盘。您的硬盘驱动器快还是慢?这取决于型号。
对类似事物进行基准测试
另一种思考的方式是这样。如果没有文件更改,ls -Llr
则执行相同数量的磁盘活动,但从不读取任何文件数据(仅读取元数据)。ls -Llr
运行所需的时间是您的上限。
与您的开发者交谈
80k文件只是不好的设计。很少有文件系统和系统工具能够很好地处理如此大的目录。如果文件名是abcdefg.txt,请考虑将其存储在abdc / abcdefg.txt中(请注意重复)。这会将目录分解成较小的目录,但是不需要对代码进行很大的更改。
另外...考虑使用数据库。如果目录中有80k文件,则开发人员可能正在解决他们真正想要的是数据库这一事实。MariaDB或MySQL或PostgreSQL将是存储大量数据的更好选择。
嘿,五分钟怎么了?
最后,5分钟真的那么糟糕吗?如果每天运行一次此备份,则5分钟的时间并不多。是的,我喜欢速度。但是,如果5分钟对您的客户来说“足够好”,那么对您来说就足够了。如果您没有书面的SLA,那么如何与用户进行非正式讨论以了解他们期望备份进行的速度有多快。
我假设您没有问这个问题,是否不需要提高性能。但是,如果您的客户对5分钟感到满意,请宣布胜利并继续进行其他需要您努力的项目。
更新:经过讨论,我们确定了瓶颈是网络。在放弃之前,我将推荐两件事:-)。
- 尝试通过压缩从管道中挤出更多带宽。但是压缩需要更多的CPU,因此,如果您的CPU过载,则可能会使性能变差。尝试使用带有和不带有的rsync
-z
,并配置带有和不带有压缩的ssh。对所有4种组合进行计时,以查看它们是否有明显好于其他的组合。
- 观察网络流量以查看是否有任何暂停。如果有停顿,您可以找到造成停顿的原因并在那里进行优化。如果rsync始终在发送,那么您确实处于极限。您的选择是:
- 更快的网络
- 除了rsync
- 将源和目标移近一点。如果无法执行此操作,可以将rsync同步到本地计算机,然后rsync到真实目的地吗?如果系统在初始rsync期间必须停机,则这样做可能会有好处。