Jika Apache sedang menulis file dari satu jenis ke satu tempat dan belum selesai menulisnya lalu rsync
menendang, rsync
akan menyalin apa pun yang ada di sana.
Berarti jika Apache berurusan dengan file 5MB, hanya 2MB yang ditulis dan rsync
dimulai, file 2MB parsial akan disalin. Jadi file itu akan tampak seperti "rusak" di server tujuan.
Bergantung pada ukuran file yang Anda gunakan, Anda dapat menggunakan --inplace
opsi rsync
untuk melakukan hal berikut:
Opsi ini mengubah cara rsync mentransfer file ketika data file perlu diperbarui: alih-alih metode default untuk membuat salinan file baru dan memindahkannya ke tempatnya ketika selesai, rsync sebagai gantinya menulis data yang diperbarui langsung ke tujuan mengajukan.
Manfaatnya adalah jika file 5MB hanya memiliki 2MB yang disalin pada proses pertama, proses berikutnya akan mengambil pada 2MB dan terus menyalin file hingga 5MB penuh di tempat.
Yang negatif adalah bahwa hal itu dapat menciptakan situasi di mana seseorang mengakses server web saat file sedang disalin dan kemudian mereka akan melihat sebagian file. Menurut pendapat saya rsync
bekerja paling baik di dalamnya perilaku default caching file "tidak terlihat" dan kemudian memindahkannya ke tempatnya segera. Tetapi --inplace
bagus untuk skenario di mana file besar dan batasan bandwidth mungkin menghalangi file besar yang mudah disalin dari persegi.
Yang mengatakan Anda menyatakan ini; penekanan adalah milikku:
Setiap lima menit memiliki cron run rsync…
Jadi saya menganggap Anda memiliki beberapa skrip bash untuk mengelola pekerjaan cron ini? Nah, masalahnya rsync
cukup pintar untuk hanya menyalin file yang perlu disalin. Dan jika Anda memiliki skrip yang berjalan setiap 5 menit tampaknya Anda mencoba untuk menghindari saling rsync
menginjak jika berjalan lebih cepat. Artinya, jika Anda menjalankannya setiap menit, ada risiko bahwa satu atau lebih rsync
proses masih akan berjalan karena ukuran file atau kecepatan jaringan dan proses selanjutnya hanya akan bersaing dengannya; kondisi balap.
Salah satu cara untuk menghindari ini adalah dengan membungkus seluruh rsync
perintah Anda dalam skrip bash yang memeriksa kunci file; di bawah ini adalah kerangka skrip bash boilerplate yang saya gunakan untuk kasus-kasus seperti ini.
Perhatikan bahwa beberapa orang akan merekomendasikan penggunaan flock
tetapi karena flock
tidak diinstal pada beberapa sistem yang saya gunakan — dan saya beralih di antara Ubuntu (yang memilikinya) dan Mac OS X (yang tidak) banyak - saya menggunakan kerangka kerja sederhana ini tanpa masalah nyata:
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
Idenya adalah inti umum — di mana saya memiliki echo "Hello world!"
— adalah tempat inti naskah Anda. Sisanya pada dasarnya adalah mekanisme penguncian / logika berdasarkan mkdir
. Penjelasan konsep yang baik ada dalam jawaban ini :
mkdir membuat direktori jika belum ada, dan jika ada, ia menetapkan kode keluar. Lebih penting lagi, ia melakukan semua ini dalam aksi atom tunggal sehingga sempurna untuk skenario ini.
Jadi dalam hal rsync
proses Anda , saya akan merekomendasikan menggunakan skrip ini dengan hanya mengubah echo
perintah ke rsync
perintah Anda . Juga, ubah LOCK_NAME
ke sesuatu seperti RSYNC_PROCESS
dan kemudian Anda baik untuk pergi.
Sekarang dengan rsync
dibungkus dengan skrip ini, Anda dapat mengatur tugas cron untuk berjalan setiap menit tanpa risiko kondisi balapan di mana dua atau lebih rsync
proses berjuang untuk melakukan hal yang sama. Ini akan memungkinkan Anda untuk meningkatkan kecepatan atau rsync
pembaruan yang tidak akan menghilangkan masalah file parsial yang ditransfer, tetapi ini akan membantu mempercepat proses keseluruhan sehingga file lengkap dapat disalin dengan benar di beberapa titik.
lsyncd
. Ini memungkinkan Anda untuk memiliki "folder panas" yang benar-benar memperhatikan aktivitas di dalamnya dan kemudian bertindak pada file-file tersebut ketika perubahan dibuat. Saya menggunakanrsync
banyak hal seperti yang dijabarkan dalam jawaban saya, tetapi saya gunakanlsyncd
untuk kasus-kasus yang membutuhkan bentuk tindakan non-cron / lebih cepat.Ya - dan file mungkin rusak jika rsync membaca file pada saat yang sama file sedang ditulis.
Anda dapat mencoba ini: /unix//a/2558
Anda juga dapat membuat skrip dengan lsof:
Kode keluar 0 berarti bahwa file sedang digunakan, dan kode keluar 1 berarti tidak ada aktivitas pada file itu.
sumber