rsync 多进程并发执行同步数据

原始命令

rsync -aPv --delete rsync://1.2.3.4/dp1/ /mnt/backup

多进程模式

#!/bin/sh
#

src='rsync://1.2.3.4/dp1' #源路径,结尾不带斜线
dst='/mnt/backup' #目标路径,结尾不带斜线

opt="-aPv --delete" #同步选项

num=16 #并发进程数
depth='5 4 3 2 1' #归递目录深度

task=/tmp/`echo $src$ | md5sum | head -c 16`
[ -f $task-next ] && cp $task-next $task-skip
[ -f $task-skip ] || touch $task-skip

# 创建目标目录结构
rsync $opt --include "*/" --exclude "*" $src/ $dst

# 从深到浅同步目录
for l in $depth ;do
    # 启动rsync进程
    for i in `find $dst -maxdepth $l -mindepth $l -type d`; do
        i=`echo $i | sed "s#$dst/##"`
        if `grep -q "$i$" $task-skip`; then
            echo "skip $i"
            continue
        fi
        while true; do
            now_num=`ps axw | grep rsync | grep $dst | grep -v '\-\-daemon' | wc -l`
            if [ $now_num -lt $num ]; then
                echo "rsync $opt $src/$i/ $dst/$i" >>$task-log
                rsync $opt $src/$i/ $dst/$i &
                echo $i >>$task-next
                sleep 1
                break
            else
                sleep 5
            fi
        done
    done
done

# 最终单进程验证
while true; do
    sleep 5
    now_num=`ps axw | grep rsync | grep $dst | grep -v '\-\-daemon' | wc -l`
    if [ $now_num -lt 1 ]; then
        echo "rsync $opt $src/ $dst" >>$task-log
        rsync $opt $src/ $dst
        break
    fi
done
文章作者: 若海; 原文链接: https://www.rehiy.com/post/134/; 转载需声明来自技术写真 - 若海

已有 6 条评论

  1. arya

    for i in $(find $dst -maxdepth $l -mindepth $l -type d | sed "s#$dst/##")

    好像可以写一行哦

    find $dst -maxdepth $l -mindepth $l -type d | sed "s#$dst/##" | while read -r i; do

    1. 的确可以,我是为了输出跳过的路径

  2. 最大目录深度使用shell自动获取比较好吧。最深不一定是5

    1. 目录太深会导致执行太多的扫描,所以我一般建议估算下

  3. 武鹏飞
    创建目标目录结构

    rsync $opt --include "*/" --exclude "*" $src/ $dst

    先创建目录,然后find $dst

    请问这块用src,不同步目录有问题吗?
    我用脚本跑上千万个目录同步耗时很长

    1. 若海

      这里的确会非常的耗时

添加新评论