问题

服务器上有多层目录结构,存放的均为几十kb的小文件,文件总量在3000w+。
使用rsync将文件备份到另一台服务器上时。rsync首先会遍历所有文件目录,这个过程大约要七八个小时,时长基本不可接受。

分析

由于文件特别多,又分布在众多的目录当中,rsync每次进行同步时,会遍历所有文件目录,并给每个文件的每层目录都分配一个FD(文件描述符),并与远程的目录进行对比,这个过程占用了大量的时间

解决思路

同步慢的主要原因是由于目录层级过多,遍历目录时间过长,且rsync进行同步的时候无法并行,因此,如果将一个大的同步任务分解为多个小任务,从最底层目录进行同步,这样就省去了遍历目录的时间,且可以多个rsync实例同时执行同步。

这种情况适用于比较规则的目录,即目录层级确定,如果目录层级不确定,那么可以改为从最底层的文件进行同步,目前对于海量目录列出最底层的子目录而不列出父目录还没有实践出比较高效的方法,具体操作如下。

利用find命令查找最底层的目录(目录结构一致且确定层级)

find /path -mindepth 3 -maxdepth 3 -type d -print0 |xargs -P 30 -n 100 -I % -0 rsync -avuzPR % backup@remote::module/

如果没有固定的目录层级,则从最底层的文件开始同步

find /path -type f -print0 |xargs -P 30 -n 100 -I % -0 rsync -avuzPR % backup@remote::module/

这里主要用到xargs 的-P参数,表示同时启用多少个进程,默认是1。
-n表示一次传递多少参数给后面的命令,默认是所有。
上述命令则表示 查找/path 目录下相应的目录或者文件,然后作为参数传递给rsync,每次传递100个参数,启用30个并行任务

整体效果良好。

最后修改:2019 年 09 月 19 日
如果觉得我的文章对你有用,请随意赞赏