LoginSignup
12
12

More than 5 years have passed since last update.

ディレクトリ配下のファイルを再帰的に並列でrsyncする

Last updated at Posted at 2013-03-29

DB移行の際、slaveのサーバにmysqlのコールドバックアップを送る時の
転送時間がボトルネックになり、試行錯誤して最終的に使ったシェル。

注意点

  • ディレクトリ構造を先にコピー先にコピーしておかないとrsyncがこける
  • 帯域に依存しているので、帯域が狭いとあまり効果が無いらしい
  • ファイル数のプロセスを起動するため、100万個ファイルがあると100万プロセスたちあがる
  • 完了後に普通のrsyncを実行し、差分が無いかをチェックするとベター
rsync -avz /tmp/backup/mysql/ username@hostname:/tmp/backup/mysql/
#!/bin/bash

# パスの末尾に/をつけてもつけなくても大丈夫なようにsedする
from_dir=`echo $1 | sed -e "s|/$||"`
to_host_user=$2
to_host=$3
to_dir=`echo $4 | sed -e "s|/$||"`

# 引数チェック
if [ "$from_dir" == "" ]; then
  echo "usage $0 from_directory_path to_host_user_name to_host_ip to_directory_path"
  exit -1
elif [ "$to_host_user" == "" ]; then
  echo "usage $0 from_directory_path to_host_user_name to_host_ip to_directory_path"
  exit -1
elif [ "$to_host" == "" ]; then
  echo "usage $0 from_directory_path to_host_user_name to_host_ip to_directory_path"
  exit -1
elif [ "$to_dir" == "" ]; then
  echo "usage $0 from_directory_path to_host_user_name to_host_ip to_directory_path"
  exit -1
fi

# ディレクトリ構造を先にコピーしておかないとこける
rsync -a --include "*/" --exclude "*" ${from_dir}/ ${to_host_user}@${to_host}:${to_dir}/

# findでディレクトリ配下のファイルを再起的に取得し、それを引数にrsyncを実行する
# つまり、ファイルが100万個あればプロセスが100万起動することになるので注意
cd ${from_dir}
for f in `find . -type f`
do
  f=${f:2}
  /usr/bin/rsync -avz --bwlimit=0 --whole-file --sockopts=TCP_NODELAY --delay-updates ${from_dir}/$f ${to_host_user}@${to_host}:${to_dir}/$f &

  usleep 500000
done
12
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
12