Hala yazılmakta olan dosya ile rsync'in davranışı?


13

Apache büyük bir dosya yazmanın ortasındaysa ve bu dosyada rsync cron işi çalışıyorsa, rsync dosyayı kopyalamaya çalışır mı?

Misal

  • Apache-1: Büyük dosya yazılıyor /var/www.
  • Apache-2: Apache-1'in Klonu. Her beş dakikada bir cron run rsync ile /var/wwwsenkronize edilir.

Yanıtlar:


21

Apache bir tür dosyayı tek bir yere yazıyorsa ve yazmayı tamamlamamışsa versync içeri giriyorsa, rsyncorada oturan her şeyi kopyalar.

Yani Apache 5MB'lık bir dosyayla uğraşıyorsa, sadece 2MB yazılır ve başlarsa, 2MB'lık rsynckısmi dosya kopyalanacaktır. Yani bu dosya hedef sunucuda “bozuk” gibi görünüyor.

Kullandığınız dosyaların boyutuna bağlı olarak , aşağıdakileri yapmak için --inplaceseçeneğini kullanabilirsiniz rsync:

Bu seçenek, dosyanın verileri güncellenmesi gerektiğinde rsync'in bir dosyayı nasıl aktardığını değiştirir: dosyanın yeni bir kopyasını oluşturmak ve tamamlandığında yerine taşımak için varsayılan yöntem yerine, rsync güncellenmiş verileri doğrudan hedefe yazar dosya.

Bunun yararı, bir 5MB dosyasında yalnızca ilk çalıştırmada 2MB kopyalanmış olması durumunda, bir sonraki çalıştırma 2MB'de toplanacak ve tam 5MB yerinde olana kadar dosyayı kopyalamaya devam edecektir.

Olumsuz tarafı, bir dosya kopyalanırken birisinin web sunucusuna eriştiği ve sonra kısmi bir dosya göreceği bir durum oluşturabilmesidir. Bence rsyncen iyi sonucu, "görünmez" bir dosyayı önbelleğe alma ve hemen yerine taşıma varsayılan davranışı. Ancak --inplacebüyük dosyaların ve bant genişliği kısıtlamalarının büyük bir dosyanın kareden birinden kolayca kopyalanmasının önüne geçebileceği senaryolar için iyidir.

Bunu söylediğini söyledi; vurgu benimdir:

Her beş dakikada bir cron run rsync var…

Bu cron işini yönetmek için bazı bash betiğiniz olduğunu varsayalım? Şey, rsyncsadece kopyalanması gereken dosyaları kopyalamak için yeterince akıllı. Ve her 5 dakikada bir çalışan bir komut dosyanız rsyncvarsa, daha hızlı giderse birbirinize adım atmaktan kaçınmaya çalışıyorsunuz . Yani, her dakika rsyncçalıştırırsanız, dosya boyutu veya ağ hızı nedeniyle bir veya daha fazla işlemin devam etme riski vardır ve bir sonraki işlem sadece onunla rekabet edebilir; bir yarış koşulu.

Bundan kaçınmanın bir yolu, tüm rsynckomutunuzu bir dosya kilidini kontrol eden bir bash betiğine sarmaktır; Aşağıda böyle durumlar için kullandığım bir boilerplate bash script çerçevesi var.

Bazı kişilerin kullanmanızı flockönereceğim flock, ancak kullandığım bazı sistemlerde yüklü olmadığından ve Ubuntu (sahip olduğu) ve Mac OS X (ki olmayan) arasında atladığımı unutmayın - bu basit çerçeveyi gerçek bir sorun olmadan kullanıyorum:

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

Fikir, genel çekirdeğin echo "Hello world!"- sahip olduğum yerde - senaryonuzun kalbinin nerede olduğu. Geri kalanı temel olarak bir kilitleme mekanizması / mantığıdır mkdir. Kavramın iyi bir açıklaması bu cevapta :

mkdir henüz yoksa bir dizin oluşturur ve varsa bir çıkış kodu ayarlar. Daha da önemlisi, tüm bunları tek bir atomik eylemde yapar ve bu senaryo için mükemmel hale getirir.

Bu nedenle, rsyncişleminiz için, sadece echokomutunuzu komutunuza değiştirerek bu komut dosyasını kullanmanızı tavsiye ederim rsync. Ayrıca, LOCK_NAMEgibi bir şey değiştirin RSYNC_PROCESSve sonra gitmek için iyidir.

Şimdi rsyncbu komut dosyasına sarıldığınızda, iki veya daha fazla rsyncişlemin aynı şeyi yapmak için savaştığı bir yarış koşulu riski olmadan her dakika çalışacak şekilde cron işini ayarlayabilirsiniz . Bu, rsyncaktarılan kısmi dosyalar sorununu ortadan kaldırmayacak hızı veya güncellemeleri artırmanıza izin verecektir , ancak tüm dosyanın bir noktada düzgün bir şekilde kopyalanabilmesi için genel işlemin hızlanmasına yardımcı olacaktır.


2
Birden fazla rsync'in çalışma olasılığını işaret ettiğiniz için teşekkürler, bunu düşünmedim. Senaryo kulağa hoş geliyor. Sadece yük dengeli bir siteyi rsync ile senkronize etmeyi anlamaya çalışıyordum ve bu onları hafifletiyor gibi görünüyor. Harika bonus. Hala yanlış yaklaşım gibi hissediyorum ... ama bakalım :)
Louis Waweru

@ Louis Hoş geldiniz! Ayrıca, klasörleri anında dosya değişikliklerine göre senkronize tutmak istiyorsanız, kullanmanızı / uyarlamayı aramanızı şiddetle tavsiye ederim lsyncd. İçlerindeki etkinliğe gerçekten dikkat eden ve daha sonra değişiklikler yapıldığında bu dosyalar üzerinde etkili olan “hot klasörlere” sahip olmanızı sağlar. rsyncCevabımda belirtildiği gibi çok şey kullanıyorum , ancak lsyncdcron olmayan / daha acil bir eylem şekli gerektiren durumlar için kullanıyorum .
JakeGould

3

Evet - ve rsync dosyayı yazarken aynı anda okuyorsa dosya bozulabilir.

Bunu deneyebilirsiniz: /unix//a/2558

Ayrıca lsof ile kodlayabilirsiniz:

lsof /path/to file

0 çıkış kodu, dosyanın kullanımda olduğu ve 1 çıkış kodu o dosyada etkinlik olmadığı anlamına gelir.


Rsync sadece okuyorsa dosyanın neden
bozulacağını
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.