我一直在使用rsync
脚本将一台主机上的数据与另一台主机上的数据同步。该数据包含大量小文件,总计近 1.2TB。
为了同步这些文件,我一直使用rsync
以下命令:
rsync -avzm --stats --human-readable --include-from proj.lst /data/projects REMOTEHOST:/data/
proj.lst的内容如下:
+ proj1
+ proj1/*
+ proj1/*/*
+ proj1/*/*/*.tar
+ proj1/*/*/*.pdf
+ proj2
+ proj2/*
+ proj2/*/*
+ proj2/*/*/*.tar
+ proj2/*/*/*.pdf
...
...
...
- *
作为测试,我选择了其中两个项目(8.5GB 数据)并执行上面的命令。作为一个连续过程,需要 14 分 58 秒才能完成。因此,对于 1.2TB 的数据,需要几个小时。
如果我可以rsync
并行运行多个进程(使用&
、xargs
或parallel
),这会节省我的时间。
我尝试使用以下命令parallel
(在cd
ing 到源目录之后),执行时间为 12 分 37 秒:
parallel --will-cite -j 5 rsync -avzm --stats --human-readable {} REMOTEHOST:/data/ ::: .
这本应该减少 5 倍的时间,但事实并非如此。我想,我在某个地方走错了。
如何运行多个rsync
进程以减少执行时间?
答案1
我强烈建议任何人不要使用已接受的答案,更好的解决方案是抓取顶级目录并启动一定数量的 rsync 操作。
我有一个很大的 zfs 卷,我的源是 cifs 安装。两者都与 10G 链接,并且在某些基准测试中可能会使链接饱和。使用 评估性能zpool iostat 1
。
源驱动器的安装方式如下:
mount -t cifs -o username=,password= //static_ip/70tb /mnt/Datahoarder_Mount/ -o vers=3.0
使用单个rsync
进程:
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/ /StoragePod
io 仪表读数:
StoragePod 30.0T 144T 0 1.61K 0 130M
StoragePod 30.0T 144T 0 1.61K 0 130M
StoragePod 30.0T 144T 0 1.62K 0 130M
在综合基准测试(水晶盘)中,顺序写入的性能接近 900 MB/s,这意味着链接已饱和。 130MB/s 不太好,等一个周末和两周的区别。
因此,我构建了文件列表并尝试再次运行同步(我有一台 64 核机器):
cat /home/misha/Desktop/rsync_logs_syncs/Datahoarder_Mount.log | parallel --will-cite -j 16 rsync -avzm --relative --stats --safe-links --size-only --human-readable {} /StoragePod/ > /home/misha/Desktop/rsync_logs_syncs/Datahoarder_Mount_result.log
并且具有相同的性能!
StoragePod 29.9T 144T 0 1.63K 0 130M
StoragePod 29.9T 144T 0 1.62K 0 130M
StoragePod 29.9T 144T 0 1.56K 0 129M
作为替代方案,我只是在根文件夹上运行 rsync:
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/Marcello_zinc_bone /StoragePod/Marcello_zinc_bone
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/fibroblast_growth /StoragePod/fibroblast_growth
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/QDIC /StoragePod/QDIC
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/sexy_dps_cell /StoragePod/sexy_dps_cell
这实际上提高了性能:
StoragePod 30.1T 144T 13 3.66K 112K 343M
StoragePod 30.1T 144T 24 5.11K 184K 469M
StoragePod 30.1T 144T 25 4.30K 196K 373M
总之,正如@Sandip Bhattacharya 提出的那样,编写一个小脚本来获取目录并与之并行。或者,将文件列表传递给 rsync。但不要为每个文件创建新实例。
答案2
以下步骤为我完成了这项工作:
- 运行
rsync --dry-run
第一个命令以获得受影响的文件列表。
$ rsync -avzm --stats --safe-links --ignore-existing --dry-run \
--human-readable /data/projects REMOTE-HOST:/data/ > /tmp/transfer.log
cat transfer.log
我输入to的输出parallel
以便并行运行 5rsync
秒,如下所示:
$ cat /tmp/transfer.log | \
parallel --will-cite -j 5 rsync -avzm --relative \
--stats --safe-links --ignore-existing \
--human-readable {} REMOTE-HOST:/data/ > result.log
在这里,--relative
选项(关联)确保源和目标处受影响文件的目录结构保持相同(/data/
目录内部),因此该命令必须在源文件夹中运行(例如,/data/projects
)。
答案3
我个人使用这个简单的:
\ls -1 | parallel rsync -a {} /destination/directory/
仅当您有多个非近乎空的目录时,这才有用,否则您最终将几乎所有rsync
终止项和最后一个单独完成所有工作。
请注意前面的反斜杠ls
会导致跳过别名。从而确保输出符合预期。
答案4
对于多目标同步,我正在使用
parallel rsync -avi /path/to/source ::: host1: host2: host3:
提示:所有 ssh 连接都是使用公钥建立的~/.ssh/authorized_keys