Apacheが大きなファイルを書き込んでいる最中にrsync cronジョブがそのファイルで実行されている場合、rsyncはファイルをコピーしようとしますか?
例
/var/www
に書き込まれています。/var/www
を同期させます。Apacheが1か所にある種類のファイルを書き込んでいて、その書き込みを完了していない場合、次にrsync
起動します、rsync
はそこにあるものをすべてコピーします。
つまり、Apacheが5MBのファイルを処理している場合、2MBのみが書き込まれ、rsync
が起動し、部分的な2MBファイルがコピーされます。そのため、そのファイルは宛先サーバーで「破損」しているように見えます。
使用しているファイルのサイズに応じて、rsync
の--inplace
オプションを使用して以下を実行できます。
このオプションは、ファイルのデータを更新する必要があるときにrsyncがファイルを転送する方法を変更します。ファイルの新しいコピーを作成し、完了時にファイルを所定の場所に移動するデフォルトの方法ではなく、rsyncが更新されたデータを宛先に直接書き込みますファイル。
これの利点は、5MBのファイルが最初の実行で2MBしかコピーされない場合、次の実行は2MBで取得され、完全な5MBが配置されるまでファイルをコピーし続けます。
否定的な点は、ファイルのコピー中に誰かがWebサーバーにアクセスして、部分的なファイルが表示されるという状況が発生する可能性があることです。私の意見では、rsync
は、「非表示」ファイルをキャッシュしてすぐに所定の場所に移動するというデフォルトの動作で最適に機能します。ただし、--inplace
は、サイズの大きなファイルや帯域幅の制約により、サイズの大きなファイルを正方形のファイルから簡単にコピーできない場合に適しています。
それはあなたがこれを述べていると言った;強調は私のものです:
5分ごとにcronがrsyncを実行しています…
それで、このcronジョブを管理するためのbashスクリプトがあると思いますか?そうですね、rsync
は、コピーする必要のあるファイルのみをコピーするのに十分スマートです。そして、5分ごとに実行されるスクリプトがある場合、それが速くなる場合は、互いにrsync
ステップを実行しないようにしようとしているようです。つまり、毎分実行した場合、ファイルサイズまたはネットワーク速度が原因で、1つ以上のrsync
プロセスがまだ実行されており、次のプロセスがそれと競合しているというリスクがあります。レース状態。
これを回避する1つの方法は、ファイルロックをチェックするbashスクリプトでrsync
コマンド全体をラップすることです。以下は、このような場合に使用する定型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は、ディレクトリがまだ存在しない場合は作成し、存在する場合は終了コードを設定します。さらに重要なことは、このすべてを1つのアトミックアクションで実行することで、このシナリオに最適です。
したがって、rsync
プロセスの場合は、echo
コマンドをrsync
コマンドに変更するだけでこのスクリプトを使用することをお勧めします。また、LOCK_NAME
をRSYNC_PROCESS
のように変更すれば、問題ありません。
rsync
をこのスクリプトにラップすると、2つ以上のrsync
プロセスが同じことを実行するために競合する競合状態のリスクなしに、毎分実行するようにcronジョブを設定できます。これにより、速度の向上やrsync
の更新が可能になり、部分的なファイルの転送の問題が解消されませんが、プロセス全体の速度が向上し、ファイル全体を適切にコピーできるようになります。
はい。ファイルへの書き込みと同時にrsyncがファイルを読み取っていると、ファイルが破損する可能性があります。
あなたはこれを試すことができます: https://unix.stackexchange.com/a/2558
Lsofを使用してスクリプトを作成することもできます。
lsof /path/to file
終了コード0はファイルが使用中であることを意味し、終了コード1はそのファイルにアクティビティがないことを意味します。