rsyncで効率的なファイル同期

Linux・CLI・DevOpsカテゴリを表すパンダのイラスト Linux・CLI・DevOps

rsyncで効率的なファイル同期

要件と前提

rsyncコマンドを用いてリモートサーバー間でファイルを効率的かつ安全に同期するためのDevOpsプラクティスを解説します。具体的には、以下の要件を満たすことを目指します。

  • 効率性: 差分転送によりネットワーク帯域と時間を節約します。

  • 安全性: シェルスクリプトは冪等性を保ち、エラーハンドリングを適切に行い、一時ファイルを安全に扱います。

  • 自動化: systemd unitとsystemd timerを用いて定期的な同期を自動化します。

  • 拡張性: jqを用いたJSONデータの処理や、curlを用いたAPI連携の例を示します。

  • 権限管理: root権限の適切な扱いと権限分離について考慮します。

前提条件:

  • Linux環境(Ubuntu/CentOSなど)が動作していること。

  • rsync, bash, systemd, jq, curlがインストールされていること。

  • SSH鍵認証が設定されており、パスワードなしでリモートサーバーに接続できること。

実装

フローの概要

systemd timerによって定期的にrsync実行サービスが起動される流れを図1に示します。

graph TD
    A["systemd Timer"] -- 定期実行をスケジュール --> B("systemd Service");
    B -- サービス起動コマンド実行 --> C{"Bashスクリプト"};
    C -- SSH経由でファイルを転送 --> D("rsyncコマンド");
    D -- ファイル同期を処理 --> E["リモートサーバー"];
    C -- 実行結果を出力 --> F["ログファイル"];
    C -- 処理結果を通知 (JSON形式) --> G["監視システム/API"];

図1: rsync同期処理フロー

rsync実行スクリプトの作成

rsyncを実行するシェルスクリプトは、冪等性を保ち、エラー時に適切に終了し、一時ファイルを安全に扱う必要があります。

#!/usr/bin/env bash

# rsync_sync.sh: 安全なrsyncファイル同期スクリプト

# 1. 厳格なエラーハンドリングとパイプ失敗時の即時終了
set -euo pipefail

# 2. 一時ディレクトリの安全な作成とクリーンアップ
#    trapコマンドでスクリプト終了時に必ず一時ファイルを削除
RSYNC_TMPDIR=$(mktemp -d -t rsync-tmp-XXXXXXXXXX)
trap 'rm -rf "${RSYNC_TMPDIR}"' EXIT SIGHUP SIGINT SIGTERM

# ログファイルパス
LOG_DIR="/var/log/rsync"
LOG_FILE="${LOG_DIR}/rsync_sync_$(date +%Y%m%d%H%M%S).log"

exec > >(sudo tee -a "${LOG_FILE}") 2>&1

echo "$(date '+%Y-%m-%d %H:%M:%S JST') - INFO: rsync同期処理を開始します。"
echo "一時ディレクトリ: ${RSYNC_TMPDIR}"

# 設定変数
SOURCE_DIR="/path/to/local/source/"     # 同期元ローカルディレクトリ
REMOTE_USER="remote_user"                # リモートサーバーのユーザー
REMOTE_HOST="remote.example.com"         # リモートサーバーのホスト名
DEST_DIR="/path/to/remote/destination/"  # 同期先リモートディレクトリ

# rsyncオプション
RSYNC_OPTIONS="-avz --delete --exclude 'tmp/' --partial-dir='${RSYNC_TMPDIR}'"

# rsyncコマンドの実行
if ! rsync ${RSYNC_OPTIONS} "${SOURCE_DIR}" "${REMOTE_USER}@${REMOTE_HOST}:${DEST_DIR}"; then
    echo "$(date '+%Y-%m-%d %H:%M:%S JST') - ERROR: rsync同期に失敗しました。"

    MESSAGE="rsync同期が ${REMOTE_HOST} で失敗しました。"
    PAYLOAD=$(jq -n \
        --arg msg "${MESSAGE}" \
        --arg timestamp "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
        '{ "status": "failed", "message": $msg, "timestamp": $timestamp }')

    if ! curl -sS --retry 5 --retry-delay 5 --retry-max-time 60 \
              --fail-silent --show-error --tlsv1.2 \
              -H "Content-Type: application/json" \
              -d "${PAYLOAD}" "https://api.example.com/notifications"; then
        echo "$(date '+%Y-%m-%d %H:%M:%S JST') - ERROR: 監視システムへの通知に失敗しました。"
    else
        echo "$(date '+%Y-%m-%d %H:%M:%S JST') - INFO: 監視システムへ失敗を通知しました。"
    fi
    exit 1
fi

echo "$(date '+%Y-%m-%d %H:%M:%S JST') - INFO: rsync同期処理が正常に完了しました。"
exit 0

コード1: rsync_sync.sh

コードのポイント:

  • set -euo pipefail: エラー発生時の即時終了、未定義変数の禁止、パイプ中のエラー伝播を強制します。

  • mktemp -d: 一時ディレクトリを安全に作成します。

  • trap 'rm -rf "${RSYNC_TMPDIR}"' EXIT: スクリプト終了時に一時ディレクトリを確実に削除します。

  • rsyncオプション(-avz, --delete, --exclude, --partial-dir)により効率的かつ安全な差分転送を実現します。

systemd unitとtimerの定義

systemdを用いて、上記のスクリプトを定期的に実行するように設定します。

1. rsync-sync.service ファイル (/etc/systemd/system/rsync-sync.service)

[Unit]
Description=rsync based file synchronization service
Documentation=https://example.com/docs/rsync-sync-service-info
Wants=network-online.target
After=network-online.target

[Service]
User=rsync_user
Group=rsync_user
WorkingDirectory=/opt/rsync-scripts
Type=oneshot
ExecStart=/bin/bash /opt/rsync-scripts/rsync_sync.sh
Restart=no
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

コード2: rsync-sync.service

2. rsync-sync.timer ファイル (/etc/systemd/system/rsync-sync.timer)

[Unit]
Description=Run rsync file synchronization every 1 hour
Documentation=https://example.com/docs/rsync-sync-timer-info

[Timer]
OnCalendar=*-*-* *:30:00
AccuracySec=1min
Persistent=true
Unit=rsync-sync.service

[Install]
WantedBy=timers.target

コード3: rsync-sync.timer

検証

systemdの設定を反映し、タイマーを有効化して動作を確認します。

  1. スクリプトとsystemdファイルの配置と権限設定:

    • rsync_sync.shを/opt/rsync-scripts/に配置し、実行権限を付与します。

    • 専用ユーザー(rsync_user)の作成と権限設定を行います。

  2. systemd設定のリロードとタイマー有効化:

    sudo systemctl daemon-reload
    sudo systemctl enable --now rsync-sync.timer
    

まとめ

rsyncは、適切なスクリプト、systemdによる自動化、そして堅牢なエラーハンドリングを組み合わせることで、非常に効率的かつ信頼性の高いファイル同期ソリューションとなります。

この記事の更新履歴

この記事は、生成AIを活用した自動レビュー・更新フローにより内容を見直し、必要な修正を反映しています。

2026年9月16日

  • 削除冒頭のGemini未検証ドラフト表記を削除しました。
  • 変更要件と前提セクション冒頭の不要な読点を削除しました。

文書情報

記事タイトル
rsyncで効率的なファイル同期
作成日
更新日
Source URL
https://papanda925.com/?p=4544

ライセンス: 本記事のうち、当サイトが権利を有する本文・自作図表は、特記なき限り CC BY 4.0 で利用できます。生成AIを活用して作成・編集した内容を含みます。コードについて、別途ライセンス表示またはリンク先GitHubリポジトリのライセンスがある場合は、その条件を優先します。引用・第三者資料・画像・商標等は本ライセンスの対象外です。 利用ポリシー

タイトルとURLをコピーしました