まだ書き込まれているファイルでのrsyncの動作は?


12

Apacheが大きなファイルの書き込み中に、そのファイルでrsync cronジョブが実行されている場合、rsyncはファイルをコピーしようとしますか?

  • Apache-1:大きいファイルが書き込まれてい/var/wwwます。
  • Apache-2:Apache-1のクローン。5分ごとにcronを実行してrsyncを実行し、/var/www同期させます。

回答:


20

Apacheが何らかの種類のファイルを1つの場所に書き込んでいて 書き込みを完了せずにrsync起動した場合、rsyncそこにあるものはすべてコピーされます。

つまり、Apacheが5MBのファイルを処理しており、2MBのみが書き込まれてrsync起動すると、部分的な2MBのファイルがコピーされます。そのため、そのファイルは、宛先サーバー上で「破損」しているように見えます。

使用しているファイルのサイズに応じて、--inplaceオプションを使用rsyncして以下を実行できます。

このオプションは、ファイルのデータを更新する必要がある場合にrsyncがファイルを転送する方法を変更します。ファイルの新しいコピーを作成し、完了時に所定の場所に移動するデフォルトの方法ではなく、rsyncは更新されたデータを直接宛先に書き込みますファイル。

これの利点は、最初の実行で5MBファイルのコピーが2MBのみである場合、次の実行では2MBをピックアップし、5MBが完全に配置されるまでファイルをコピーし続けることです。

欠点は、ファイルがコピーされている間に誰かがWebサーバーにアクセスしている場合に、部分的なファイルが表示される可能性があることです。私の意見rsyncでは、「見えない」ファイルをキャッシュしてからすぐに所定の場所に移動するというデフォルトの動作が最適です。しかし--inplace、大きなファイルと帯域幅の制約が、大きなファイルが正方形のものから簡単にコピーされるのを妨げる可能性があるシナリオには適しています。

それはあなたがこれを述べていると言った。強調は私のものです:

5分ごとに cronがrsyncを実行します…

だから、このcronジョブを管理するためのbashスクリプトが用意されていると思いますか?まあ、物事はrsyncコピーする必要があるファイルだけをコピーするのに十分スマートです。また、5分ごとに実行されるスクリプトがある場合は、rsync高速化すれば、お互いに踏み込むことを避けようとしているように見えます。つまり、毎分rsync実行した場合、ファイルサイズまたはネットワーク速度が原因で1つ以上のプロセスがまだ実行されており、次のプロセスがそれと競合しているというリスクがあります。レース状態。

これを回避する1つの方法rsyncは、ファイルロックをチェックするbashスクリプトでコマンド全体をラップすることです。以下は、このような場合に使用する定型的なbashスクリプトフレームワークです。

一部の人々は使用することを推奨しますflockが、flock私が使用する一部のシステムにインストールされていないため(そして、Ubuntu(それがあります)とMac OS X(ない)の間を頻繁に移動します)

LOCK_NAME="MY_GREAT_BASH_SCRIPT"
LOCK_DIR='/tmp/'${LOCK_NAME}.lock
PID_FILE=${LOCK_DIR}'/'${LOCK_NAME}'.pid'

if mkdir ${LOCK_DIR} 2>/dev/null; then
  # If the ${LOCK_DIR} doesn't exist, then start working & store the ${PID_FILE}
  echo $$ > ${PID_FILE}

  echo "Hello world!"

  rm -rf ${LOCK_DIR}
  exit
else
  if [ -f ${PID_FILE} ] && kill -0 $(cat ${PID_FILE}) 2>/dev/null; then
    # Confirm that the process file exists & a process
    # with that PID is truly running.
    echo "Running [PID "$(cat ${PID_FILE})"]" >&2
    exit
  else
    # If the process is not running, yet there is a PID file--like in the case
    # of a crash or sudden reboot--then get rid of the ${LOCK_DIR}
    rm -rf ${LOCK_DIR}
    exit
  fi
fi

その考えは、一般的なコア-私が持っているecho "Hello world!"場所-があなたのスクリプトの中心であるということです。残りは基本的にに基づいたロックメカニズム/ロジックですmkdir。コンセプトの良い説明はこの答えにあります

mkdirは、まだ存在しない場合はディレクトリを作成し、存在する場合は終了コードを設定します。さらに重要なことは、このすべてを単一のアトミックアクションで実行することで、このシナリオに最適です。

したがって、rsyncプロセスの場合は、echoコマンドをコマンドに変更するだけでこのスクリプトを使用することをお勧めしますrsync。また、LOCK_NAMEをのようなものに変更RSYNC_PROCESSすれば、準備完了です。

rsyncこのスクリプトでラップすると、2つ以上のrsyncプロセスが同じことを行うために戦っている競合状態のリスクなしに、cronジョブを毎分実行するように設定できます。これによりrsync、部分的なファイルの転送の問題を解消することはできませんが、速度または更新を増やすことができますが、全体のプロセスを高速化して、ある時点で完全なファイルを適切にコピーできます。


1
複数のrsyncが実行される可能性を指摘してくれてありがとう、それは考えていませんでした。スクリプトは素晴らしいですね。負荷分散サイトをrsyncと同期することの落とし穴を理解しようとしていましたが、これはそれらを軽減するようです。素晴らしいボーナス。おそらくこれは間違ったアプローチかもしれませんが...見てみましょう:)
ルイワウェル14

@Louisどういたしまして!また、ファイルの即時変更に基づいてフォルダーの同期を維持する場合は、使用/適応を検討することを強くお勧めしlsyncdます。これにより、「ホットフォルダ」を作成して、その中のアクティビティに本当に注意を払い、変更が加えられたときにそれらのファイルを操作できます。私rsyncは答えで概説したように多くのことを使用lsyncdしますが、非cron /より直接的なアクションが必要な場合に使用します。
JakeGould

3

はい-ファイルの書き込みと同時にrsyncがファイルを読み込んでいる場合、ファイルが破損する可能性があります。

これを試すことができますhttps : //unix.stackexchange.com/a/2558

lsofを使用してスクリプトを作成することもできます。

lsof /path/to file

0の終了コードはファイルが使用中であることを意味し、1の終了コードはそのファイルにアクティビティがないことを意味します。


rsyncはちょうどそれを読んでいる場合、私は、ファイルが破損します、なぜ表示されない
orestisf
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.