不幸的是,某些服务器的网络很慢.
rsync最多需要五分钟才能检测到,巨大的目录中没有任何变化.这些巨大的目录树包含许多小文件(大约80k文件).
我猜rsync客户端为每个80k文件发送数据.
由于网络很慢,我想避免发送关于每个文件的80k次信息.
有没有办法告诉rsync制作子目录树的哈希值?
这样rsync客户端只会为一个巨大的目录树发送几个字节.
更新
到目前为止,我的策略是使用rsync.但如果不同的工具在这里更合适,我可以切换.两者(服务器和客户端)都在我的控制之下.
UPDATE2
一个目录树中有80k个文件.每个目录没有超过2k个文件或子目录
UPDATE3
有关网络缓慢的详细信息:
time ssh einswp 'cd attachments/200 && ls -lLR' >/tmp/list real 0m2.645s
tmp / list文件的大小:2MByte
time scp einswp:/tmp/list tmp/ real 0m2.821s
结论:scp具有相同的速度(毫不奇怪)
time scp einswp:tmp/100MB tmp/ real 1m24.049s
速度:1.2MB / s
解决方法
80K是很多文件.
一个目录中有80,000个文件?默认情况下,操作系统或应用程序没有很好地处理这种情况你碰巧注意到rsync的这个问题.
检查您的rsync版本
现代rsync处理大型目录比过去好很多.请确保您使用的是最新版本.
即使是旧的rsync也可以在高延迟链接上很好地处理大型目录…但是80k文件并不大……这是巨大的!
也就是说,rsync的内存使用量与树中的文件数成正比.大目录占用大量RAM.缓慢可能是由于任何一方都缺乏RAM.在观察内存使用情况时进行测试运行. Linux使用任何剩余的RAM作为磁盘缓存,因此如果RAM运行不足,则磁盘缓存较少.如果RAM耗尽并且系统开始使用swap,性能将非常糟糕.
确保没有使用–checksum
–checksum(或-C)需要读取每个文件的每个块.您可能只需读取修改时间(存储在inode中)的默认行为即可.
将工作分成小批量.
有些项目如@L_403_0@将“通过使用perl来递减工作负载来递归目录树,构建用rsync传输的小文件列表.”
额外的目录扫描将是一个大量的开销,但也许它将是一个净赢.
操作系统默认设置不适用于此情况.
如果您使用具有所有默认值的Linux / FreeBSD / etc,那么所有应用程序的性能都会非常糟糕.默认值假定较小的目录,以免在超大缓存上浪费RAM.
调整文件系统以更好地处理大型目录:Do large folder sizes slow down IO performance?
看看“namei cache”
类似BSD的操作系统有一个缓存,可以加速查找inode的名称(“namei”缓存“).每个目录都有一个名称缓存.如果它太小,它就是一个障碍而不是优化.由于rsync在每个文件上执行lstat(),因此正在为每个80k文件访问inode.这可能会破坏您的缓存.研究如何调整系统上的文件目录性能.
考虑一个不同的文件系统
XFS旨在处理更大的目录.见Filesystem large number of files in a single directory
也许5分钟是你能做的最好的.
考虑计算正在读取的磁盘块数,并计算硬件能够读取多少块的速度.
也许你的期望太高了.考虑必须读取多少磁盘块才能执行没有更改文件的rsync:每个服务器都需要读取目录并读取每个文件的一个inode.我们假设没有任何缓存,因为80k文件可能已经破坏了你的缓存.让我们说,保持数学简单是80k块.那是大约40M的数据,应该可以在几秒钟内读取.但是,如果需要在每个块之间进行磁盘搜索,则可能需要更长时间.
因此,您将需要阅读大约80,000个磁盘块.你的硬盘有多快可以做到这一点?考虑到这是随机I / O,而不是长线性读取,5分钟可能非常好.那是1 /(80000/600),或者每7.5毫秒读一次磁盘.您的硬盘是快还是慢?这取决于模型.
针对类似的东西的基准
另一种思考方式就是这样.如果没有更改文件,则ls -Llr执行相同数量的磁盘活动但从不读取任何文件数据(仅元数据). ls -Llr运行的时间是你的上限.
> rsync(没有更改文件)明显慢于ls -Llr吗?然后可以改进用于rsync的选项.也许-C已启用或其他一些标志不仅仅读取目录和元数据(inode数据).
> rsync(没有更改文件)几乎和ls -Llr一样快吗?然后你尽可能地调整了rsync.您必须调整操作系统,添加RAM,获得更快的驱动器,更改文件系统等.
和你的开发者交谈
80k文件只是糟糕的设计.很少有文件系统和系统工具可以很好地处理这些大型目录.如果文件名是abcdefg.txt,请考虑将它们存储在abdc / abcdefg.txt中(注意重复).这会将目录分解为较小的目录,但不需要对代码进行大的更改.
另外….考虑使用数据库.如果你在一个目录中有80k文件,那么你的开发人员可能正在解决他们真正想要的是数据库这一事实. MariaDB或MysqL或Postgresql是存储大量数据的更好选择.
嘿,5分钟有什么不对?
最后,是5分钟真的那么糟糕?如果您每天运行一次备份,则5分钟不是很多时间.是的,我喜欢速度.但是,如果5分钟对您的客户来说“足够好”,那么它对您来说已经足够了.如果您没有书面SLA,那么如何与您的用户进行非正式讨论,以了解他们对备份的期望速度.
我假设如果不需要改善性能,你就不会问这个问题.但是,如果您的客户对5分钟感到满意,请宣布胜利并继续进行其他需要您努力的项目.
更新:经过一番讨论,我们确定瓶颈是网络.在我放弃之前,我会推荐两件事:-).
>尝试通过压缩从管道中挤出更多带宽.但是压缩需要更多cpu,因此如果cpu过载,可能会使性能变差.尝试使用和不使用-z的rsync,并使用和不使用压缩配置ssh.计算所有4种组合的时间,看看它们是否比其他组合表现得更好.
>观察网络流量,看看是否有任何暂停.如果有暂停,您可以找到导致它们的原因并在那里进行优化.如果rsync总是发送,那么你真的是在你的极限.你的选择是:
>更快的网络> rsync以外的东西>将源和目的地拉得更近.如果你不能这样做,你可以rsync到本地机器然后rsync到真正的目的地?如果在初始rsync期间系统必须关闭,则执行此操作可能会有好处.