クイックスタート(5分)
サーバー間で数十ギガバイトものデータを転送する際、cpやscpといった標準コマンドだけに頼るのはリスクが伴います。SSH接続が途中で切断されれば最初からやり直しになり、さらに厄介なことに、わずか2KBしか変更されていない40GBのデータベースダンプであっても、すべてのバイトを一から上書きしてしまいます。これこそが、システム管理者やDevOpsチームにとってrsync(remote sync)が不可欠であり続ける理由です。rsync独自の差分転送アルゴリズムは、転送元と転送先の双方でファイルを比較し、差分データのみをネットワーク経由で送信します。
まず、ローカルホストと転送先マシンの両方にrsyncがインストールされているか確認しましょう。
# Debian / Ubuntu
sudo apt update && sudo apt install -y rsync
# RHEL / Rocky Linux / AlmaLinux
sudo dnf install -y rsync
基本的な構文は至ってシンプルです。
rsync [OPTIONS] SOURCE DESTINATION
末尾のスラッシュに関する鉄則
末尾のスラッシュ(/)の扱いには細心の注意を払ってください。スラッシュが1つあるかないかだけで、ディレクトリが意図せず入れ子構造になってしまうのは、Linuxで最もよくあるミスの1つです。
# 末尾スラッシュなし: 'mydata' ディレクトリ自体を '/backup' 内にコピー
# 結果: /backup/mydata/file.txt
rsync -av /var/www/mydata /backup
# 末尾スラッシュあり: 'mydata' の「中身」を直接 '/backup' 内にコピー
# 結果: /backup/file.txt
rsync -av /var/www/mydata/ /backup
SSH経由での最初のリモート同期
本番サーバーからログディレクトリを安全に取得するには、SSHトランスポートを指定しつつ標準的なアーカイブフラグを付与して実行します。
rsync -avz -e ssh [email protected]:/var/log/nginx/ /opt/logs/remote-nginx/
各フラグには明確な役割があります。-aはファイルパーミッション、タイムスタンプ、シンボリックリンク、所有者情報を保持し、-vは詳細なログを出力します。そして-zは転送中のパケットペイロードを圧縮してネットワーク帯域を節約します。
ディープダイブ:主要フラグとセキュアなリモート転送
本番環境のストレージボリュームに対して同期を実行するには、各フラグがファイルシステムの状態にどう影響を与えるかを正確に把握しておく必要があります。
必須の運用フラグ
-a(アーカイブモード):-rlptgoDの組み合わせです。ファイルを再帰的に同期し、シンボリックリンクを保持し、パーミッション、タイムスタンプ、所有者、グループ、デバイスノードをそのまま維持します。-P(進捗表示と部分保持):--progressと--partialを組み合わせたオプションです。転送速度や推定残り時間(ETA)を含むプログレスバーが表示されます。8GBのISOイメージ転送中に接続が途切れた場合でも、rsyncは不完全なファイルを破棄せず保持し、次回実行時にその中断箇所のオフセットから再開します。--delete: 転送元で削除されたファイルを転送先からも削除します。完全な1対1のレプリカを作成できますが、実行前に対象パスを必ず再確認してください。-h(人間が読みやすい形式): 生のバイト数表示を、512MBや3.4GBのようなわかりやすい単位に変換します。
ドライラン(Dry Run)による安全な検証
本番データに対して、検証なしで--deleteを付けた同期を実行してはいけません。まずは-n(ドライラン)と-i(変更項目の詳細表示)を組み合わせて、パスの指定やロジックをテストしましょう。
rsync -avzPhn --delete /data/project/ [email protected]:/storage/project/
ドライランを実行すると、指定されたすべての除外・包含パターンが評価され、ディスク上のファイルを1つも変更することなく、予定されている処理内容が出力されます。
カスタムSSH接続の設定
セキュリティを強化した踏み台サーバーでは、非標準ポートを使用していたり、専用の秘密鍵が要求されたりすることがよくあります。その場合はカスタム接続引数を-eオプションに直接渡します。
rsync -avzP -e "ssh -p 2222 -i /home/deploy/.ssh/backup_rsa" /etc/app/ backup-node:/remote-backups/app/
高度な活用法:帯域制御と増分バックアップ
共有WAN回線経由で120GBのデータベースダンプを転送すると、アップリンクが飽和し、VoIPパケットのロスやユーザーリクエストの遅延を引き起こす可能性があります。帯域上限を設定してネットワーク輻輳を防ぎつつ、ファイルシステムのハードリンクを活用してディスク容量を節約しましょう。
帯域幅の制限(スロットリング)
--bwlimitオプションを使用すると、転送レートの上限をキロバイト/秒単位で指定できます。オフサイト同期を約5MB/s(40Mbps)に制限する場合は次のように設定します。
# 転送レートを 5,000 KB/s (~5 MB/s) に制限
rsync -avzP --bwlimit=5000 /var/backups/db.sql offsite-storage:/backups/
これにより、営業時間中に大容量データ転送が稼働中アプリケーションの通信を圧迫するのを防止できます。
ハードリンクを活用したスマートな増分バックアップ
毎晩フルバックアップを取得していると、あっという間にストレージが枯渇してしまいます。従来の増分バックアップ方式なら容量は抑えられますが、深いスナップショットチェーンからファイルを復元する作業は時間がかかり、ミスも起こりやすいのが難点です。rsyncの--link-destを使えば、この両者の利点を美しく両立できます。
日次スナップショットを生成する際、rsyncは前日のバックアップディレクトリをチェックします。ファイルのサイズやタイムスタンプに変更がなければ、新たなデータブロックを書き込む代わりに、既存ファイルへのinodeハードリンクを作成します。そのため、変更のないファイルがディスク容量を余分に消費することはありません。
Ubuntu 22.04サーバー上で日次変更率3%の50GBディレクトリを対象にテストしたところ、毎日のバックアップは45秒足らずで完了しました。各スナップショットは独立した完全なフォルダとして見えるため、復元作業も通常のcpやtarコマンドと同じくらいシンプルです。
本番環境向け増分バックアップスクリプト
以下の軽量な自動バックアップスクリプトは、cronにそのまま登録して利用できます。
#!/usr/bin/env bash
set -euo pipefail
# 設定
SOURCE_DIR="/var/www/html/"
BACKUP_ROOT="/mnt/backups/web-app"
DATE_STAMP="$(date +%Y-%m-%d_%H%M%S)"
CURRENT_BACKUP="${BACKUP_ROOT}/${DATE_STAMP}"
LATEST_LINK="${BACKUP_ROOT}/latest"
mkdir -p "${BACKUP_ROOT}"
# ハードリンクの参照元となる過去バックアップが存在するか確認
LINK_DEST_OPTION=""
if [ -d "${LATEST_LINK}" ]; then
LINK_DEST_OPTION="--link-dest=${LATEST_LINK}"
fi
# 増分同期を実行
rsync -a --delete \
${LINK_DEST_OPTION} \
--exclude="*.log" \
--exclude="cache/" \
"${SOURCE_DIR}" "${CURRENT_BACKUP}"
# 'latest' シンボリックリンクをアトミックに新しいスナップショットへ向け直す
rm -f "${LATEST_LINK}"
ln -s "${CURRENT_BACKUP}" "${LATEST_LINK}"
echo "バックアップが正常に完了しました: ${CURRENT_BACKUP}"
スクリプトに実行権限を付与し、毎晩午前2時に実行されるようスケジューリングします。
chmod +x /usr/local/bin/backup-app.sh
# crontab エディタを開く
sudo crontab -e
# スケジュール行を追加:
0 2 * * * /usr/local/bin/backup-app.sh >> /var/log/backup-app.log 2>&1
本番環境向けの強化策とパフォーマンスチューニング
大規模な本番ファイルシステムに対してrsyncを実行する際は、以下の運用ポイントを意識してください。
1. 除外ルールは専用ファイルにまとめる
インラインの--excludeフラグが何重にも連なると、シェルスクリプトの可読性が著しく低下します。除外パターンは専用のテキストファイルに切り出しましょう。
# /etc/rsync-excludes.txt
.git/
*.tmp
node_modules/
storage/logs/*
cache/*
このリストを--exclude-fromで読み込みます。
rsync -avz --exclude-from="/etc/rsync-excludes.txt" /var/www/app/ /storage/app/
2. nice と ionice でシステムI/Oの負荷を制御する
数百万ものファイルinodeを走査してチェックサムを算出すると、激しいディスク競合が発生します。負荷の高いWebサーバーやデータベースサーバーでは、突発的なバックアップ処理によってI/O waitが跳ね上がり、HTTP 504タイムアウトを招く恐れがあります。niceとioniceを使ってCPUおよびブロックI/Oの優先度を下げましょう。
# CPUスケジューリング優先度を下げ (nice 19)、ディスクアクセスをアイドル時のみに制限 (ionice -c 3)
nice -n 19 ionice -c 3 rsync -a /heavy-data/ /backup/heavy-data/
3. 高速LAN環境でのCPUボトルネックを解消する
10GbEなどの高速ネットワーク環境では、ネットワーク帯域が上限に達する前にSSH暗号化処理がCPUの限界にぶつかることがよくあります。また、圧縮済みの画像や動画が多い場合、高速LAN内での-zによる圧縮処理はいたずらにCPUサイクルを消費するだけです。信頼できるプライベートVLAN内で同期する場合は、[email protected]や[email protected]といった高速なストリーム暗号に切り替え、-zを外しましょう。
rsync -av -e "ssh -c [email protected]" /srv/media/ remote-box:/srv/media/
これらのチューニングを取り入れることで、本番サービスに負荷をかけることなく、転送速度の最大化、ストレージ容量の節約、そして予測可能で安定したバックアップ運用が実現できます。

