GNU/Linux >> Belajar Linux >  >> Linux

Perilaku rsync dengan file yang masih ditulis?

Jika Apache menulis semacam file ke satu tempat dan belum selesai menulisnya lalu rsync masuk, rsync akan menyalin apa pun yang ada di sana.

Artinya jika Apache berurusan dengan file 5MB, hanya 2MB yang ditulis dan rsync masuk, file 2MB parsial akan disalin. Sehingga file tersebut seolah-olah “rusak” di server tujuan.

Bergantung pada ukuran file yang Anda gunakan, Anda dapat menggunakan --inplace opsi di rsync untuk melakukan hal berikut:

Opsi ini mengubah cara rsync mentransfer file saat data file perlu diperbarui:alih-alih metode default untuk membuat salinan baru file dan memindahkannya ke tempatnya saat selesai, rsync malah menulis data yang diperbarui langsung ke file tujuan.

Keuntungan dari ini adalah jika file 5MB hanya memiliki 2MB yang disalin pada proses pertama, proses berikutnya akan mengambil 2MB dan terus menyalin file hingga 5MB penuh tersedia.

Negatifnya adalah hal itu dapat menciptakan situasi di mana seseorang mengakses server web saat file sedang disalin dan kemudian mereka akan melihat sebagian file. Menurut saya rsync berfungsi paling baik dalam perilaku defaultnya untuk menyimpan file "tidak terlihat" dan kemudian segera memindahkannya ke tempatnya. Tapi --inplace bagus untuk skenario di mana file besar dan batasan bandwidth mungkin menghalangi file besar yang mudah disalin dari awal.

Yang mengatakan Anda menyatakan ini; penekanan adalah milikku:

Setiap lima menit telah menjalankan cron rsync…

Jadi saya berasumsi Anda memiliki beberapa skrip bash untuk mengelola tugas cron ini? Nah, masalahnya adalah rsync cukup pintar untuk hanya menyalin file yang perlu disalin. Dan jika Anda memiliki skrip yang berjalan setiap 5 menit, tampaknya Anda mencoba menghindari rsync menginjak satu sama lain jika berjalan lebih cepat. Artinya, jika Anda menjalankannya setiap menit, ada risiko salah satu atau lebih dari rsync proses akan tetap berjalan karena ukuran file atau kecepatan jaringan dan proses selanjutnya hanya akan bersaing dengannya; kondisi balapan.

Salah satu cara untuk menghindarinya adalah dengan membungkus seluruh rsync Anda perintah dalam skrip bash yang memeriksa kunci file; di bawah ini adalah framework skrip bash boilerplate yang saya gunakan untuk kasus seperti ini.

Perhatikan bahwa beberapa orang akan merekomendasikan penggunaan flock tapi sejak flock tidak diinstal pada beberapa sistem yang saya gunakan—dan saya beralih 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 itu—di mana saya memiliki echo "Hello world!" —Adalah inti dari naskah Anda. Sisanya pada dasarnya adalah mekanisme/logika penguncian berdasarkan mkdir . Penjelasan konsep yang bagus ada di jawaban ini:

mkdir membuat direktori jika belum ada, dan jika ya, itu menetapkan kode keluar. Lebih penting lagi, semua ini dilakukan dalam aksi atom tunggal sehingga sempurna untuk skenario ini.

Jadi dalam kasus rsync Anda proses, saya akan merekomendasikan menggunakan script ini dengan hanya mengubah echo perintah ke rsync Anda memerintah. Juga, ubah LOCK_NAME ke sesuatu seperti RSYNC_PROCESS dan kemudian Anda baik untuk pergi.

Sekarang dengan rsync Anda dibungkus dengan skrip ini, Anda dapat mengatur tugas cron untuk berjalan setiap menit tanpa risiko kondisi balap 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 transfer sebagian file, tetapi ini akan membantu mempercepat keseluruhan proses sehingga file lengkap dapat disalin dengan benar di beberapa titik.


Ya - dan file mungkin rusak jika rsync membaca file pada saat yang sama saat file sedang ditulis.

Anda dapat mencoba ini:https://unix.stackexchange.com/a/2558

Anda juga dapat membuat skrip dengan lsof:

lsof /path/to file

Kode keluar 0 berarti file sedang digunakan, dan kode keluar 1 berarti tidak ada aktivitas pada file tersebut.


Linux
  1. Apakah Menggunakan Rsync Saat Sumber Diperbarui Aman?

  2. Ganti Baris Baru Dengan Nul?

  3. Tail -f, Tentukan Apakah Sebuah File Tidak Lagi Ditulis?

  1. Bagaimana Cara Mengeluarkan File &Mengabaikan Baris Yang Dimulai Dengan "?"?

  2. Apakah aman membuka file yang sedang ditulis oleh skrip yang sedang berjalan?

  3. Menonton sesuatu ditulis ke file langsung dengan ekor

  1. Transfer File Lebih Cerdas Dari Rsync??

  2. Izin File di Linux dengan Contoh

  3. Pulihkan file yang dihapus yang saat ini sedang ditulis