2014-06-05 13 views
24

我们需要尽可能快地将数据从一台服务器转移到另一台服务器。我们目前使用的是rsync,但当我们的网络能够使用900+Mb/s(使用iperf进行测试)时,我们只能获得大约150Mb/s的速度。我已经完成了对磁盘,网络等的测试,并认为它只是在同一时间只会传输一个文件导致放缓。加速同步/并发文件传输的rsync?

我发现了一个脚本,用于为目录树中的每个文件夹运行不同的rsync(允许限制为x数),但我无法得到它的工作,它仍然一次只运行一个rsync。

我找到scripthere(复制如下)。

我们的目录树是这样的:

/main 
    - /files 
     - /1 
     - 343 
      - 123.wav 
      - 76.wav 
     - 772 
      - 122.wav 
     - 55 
      - 555.wav 
      - 324.wav 
      - 1209.wav 
     - 43 
      - 999.wav 
      - 111.wav 
      - 222.wav 
     - /2 
     - 346 
      - 9993.wav 
     - 4242 
      - 827.wav 
     - /3 
     - 2545 
      - 76.wav 
      - 199.wav 
      - 183.wav 
     - 23 
      - 33.wav 
      - 876.wav 
     - 4256 
      - 998.wav 
      - 1665.wav 
      - 332.wav 
      - 112.wav 
      - 5584.wav 

所以我想发生什么事是创建一个rsync的每个/主/文件的目录中,最多的,比方说,每次5个。所以在这种情况下,会运行3个rsyncs,对于/main/files/1,/main/files/2/main/files/3

我与它试图这样,但它只是运行1个rsync的在时间/main/files/2文件夹:

#!/bin/bash 

# Define source, target, maxdepth and cd to source 
source="/main/files" 
target="/main/filesTest" 
depth=1 
cd "${source}" 

# Set the maximum number of concurrent rsync threads 
maxthreads=5 
# How long to wait before checking the number of rsync threads again 
sleeptime=5 

# Find all folders in the source directory within the maxdepth level 
find . -maxdepth ${depth} -type d | while read dir 
do 
    # Make sure to ignore the parent folder 
    if [ `echo "${dir}" | awk -F'/' '{print NF}'` -gt ${depth} ] 
    then 
     # Strip leading dot slash 
     subfolder=$(echo "${dir}" | sed '[email protected]^\./@@g') 
     if [ ! -d "${target}/${subfolder}" ] 
     then 
      # Create destination folder and set ownership and permissions to match source 
      mkdir -p "${target}/${subfolder}" 
      chown --reference="${source}/${subfolder}" "${target}/${subfolder}" 
      chmod --reference="${source}/${subfolder}" "${target}/${subfolder}" 
     fi 
     # Make sure the number of rsync threads running is below the threshold 
     while [ `ps -ef | grep -c [r]sync` -gt ${maxthreads} ] 
     do 
      echo "Sleeping ${sleeptime} seconds" 
      sleep ${sleeptime} 
     done 
     # Run rsync in background for the current subfolder and move one to the next one 
     nohup rsync -a "${source}/${subfolder}/" "${target}/${subfolder}/" </dev/null >/dev/null 2>&1 & 
    fi 
done 

# Find all files above the maxdepth level and rsync them as well 
find . -maxdepth ${depth} -type f -print0 | rsync -a --files-from=- --from0 ./ "${target}/" 

回答

20

rsync传输文件的速度,因为它可以在网络上。例如,尝试使用它来复制目标上根本不存在的一个大文件。该速度是rsync可以传输数据的最大速度。比较它与scp(例如)的速度。 rsync在目标文件存在时在原始传输中甚至更慢,因为双方都必须双向聊天以了解文件的哪些部分发生了更改,但通过识别不需要传输的数据来为自己付出代价。

并行运行rsync的简单方法是使用parallel。下面的命令将并行运行多达5个rsync,每个命令都复制一个目录。请注意瓶颈可能不是你的网络,但你的CPU和磁盘的速度,并行运行的东西只会让它们变得更慢,而不是更快。

run_rsync() { 
    # e.g. copies /main/files/blah to /main/filesTest/blah 
    rsync -av "$1" "/main/filesTest/${1#/main/files/}" 
} 
export -f run_rsync 
parallel -j5 run_rsync ::: /main/files/* 
+0

刚刚试过这个,并不能得到这个工作。 'ls -1/main/files/* | xargs -i -n5 rsync -av {}/main/filesTest/{}'给了我很多rsync的文件或目录错误。我将如何打印出rsync命令而不是运行它,以便我可以看到发生了什么问题? – BT643

+0

你可以将它从'rsync'改为'echo rsync' –

+0

啊,对不起,'xargs'不对,应该是'parallel'。我已经更新了答案。 –

27

这似乎简单:

ls /srv/mail | parallel -v -j8 rsync -raz --progress {} myserver.com:/srv/mail/{} 
+4

请注意,如果您通过各种方式(例如LISTFLAGS变量或DIR_COLORS文件)自定义您的'ls'输出,则可能需要使用'ls --indicator-style = none'来防止添加ls'符号指向路径名称(例如用于执行文件的'*')。 – chadrik

+2

我发现这个工作好多了,如果我用 cd/sourcedir; parallel -j8 -i rsync -aqH {}/destdir/{} - * – Criggie

7

有许多的替代工具和方法,这样做的角落找寻网站上市。例如:

  • NCSA Blog具有使用xargsfind并行rsync的,无需安装用于大多数* nix系统任何新的软件的说明。

  • parsync为并行rync提供了功能丰富的Perl包装。

+2

请不要只是发布一些工具或库作为答案。至少在答案中演示[它如何解决问题](http://meta.stackoverflow.com/a/251605)。 –

+0

@i_m_mahii Stack Exchange应该自动保留链接页面的副本。 –

1

我已经开发了Python包名为:parallel_sync

https://pythonhosted.org/parallel_sync/pages/examples.html

下面是一个示例代码如何使用它:

from parallel_sync import rsync 
creds = {'user': 'myusername', 'key':'~/.ssh/id_rsa', 'host':'192.168.16.31'} 
rsync.upload('/tmp/local_dir', '/tmp/remote_dir', creds=creds) 

并行默认为10;你可以增加它:但是

from parallel_sync import rsync 
creds = {'user': 'myusername', 'key':'~/.ssh/id_rsa', 'host':'192.168.16.31'} 
rsync.upload('/tmp/local_dir', '/tmp/remote_dir', creds=creds, parallelism=20) 

注意,SSH通常默认设置的MAXSESSIONS 10所以要延长到超出10,则必须修改SSH设置。

4

您可以使用支持一次运行多个进程的xargs。为您的情况,它将是:

ls -1 /main/files | xargs -I {} -P 5 -n 1 rsync -avh /main/files/{} /main/filesTest/