scp ile transfer tam ortasında kesildi ve şimdi hangi dosyaların ulaştığını, hangilerinin ulaşmadığını bilmiyorsunuz. Ya da cp -r ile 40 GB'lık bir klasörü kopyaladınız ve her seferinde sıfırdan başlıyor. Sorun yanlış aracı seçmiş olmanız. rsync tam da bu an için yapıldı: artımlı transfer, sürdürülebilir ve zaten yerinde olan şeyleri yeniden kopyalamadan tekrarlanabilir.
Bu rehberde sadece gerçek bir sunucuda karşılaştığım şeyleri yazıyorum; tüm sonucu değiştiren sondaki tek bir eğik çizginin farkından, yanlış kullanıldığında hedef sunucudaki dosyaları silen bayraklara kadar.
rsync tam olarak neyi aktarır, neyi aktarmaz
rsync her transferden önce kaynak ve hedef dosya listesini oluşturur ve karşılaştırır. Varsayılan karşılaştırma ölçütü içerik hash'i değil, dosya boyutu ile değişiklik zamanının (mtime) birleşimidir. Yani bir dosya aynı boyuttaysa ve mtime'ı da aynıysa, rsync onu aynı kabul eder ve atlar. Bu karar işlerin %99'u için doğrudur çünkü hızı kat kat artırır, ancak önemli bir istisnası vardır: dosya içeriği değişmiş ama boyut ve zaman dokunulmamış kalmışsa. Örneğin timestamp'i elle sıfırlayan bir script. Bu durumda rsync'in MD5 hash alması için --checksum kullanmalısınız. Bedeli şudur: yüz binlerce küçük dosyada ilk tarama birkaç dakika sürer ve disk I/O yükselir.
Ağ üzerinden transfer için rsync genellikle tünel olarak SSH kullanır. SSH'ı varsayılan olmayan bir porta aldıysanız, açıkça belirtmelisiniz:
rsync -avz -e "ssh -p 2222" /var/www/html/ deploy@203.0.113.10:/var/www/html/
-z bayrağı veriyi göndermeden önce sıkıştırır. Metin ve kod dosyalarında faydalıdır. jpg, zip veya mp4 gibi zaten sıkıştırılmış dosyalarda sadece CPU tüketir ve hiçbir şey kazandırmaz. Yedeklemeyi iç ağ üzerinden alıyorsanız -z'yi kaldırın.
Sondaki eğik çizgi farkı; en çok hatanın yapıldığı yer
Burada hata yapıyorlar: kaynak yolun sonundaki eğik çizgiyi görüyorlar ve süs sanıyorlar. Değil. Bu iki komut tamamen farklı sonuç verir:
rsync -av /var/www/html/ user@host:/backup/
rsync -av /var/www/html user@host:/backup/
İlk satırda html klasörünün içeriği backup içine dökülür. İkinci satırda html klasörünün kendisi backup içinde bir alt klasör olarak oluşturulur. Bunu yanlış yaparsanız, birkaç gün yedekleme yaptıktan sonra klasör yapısının iç içe geçtiğini ve geri yükleme yolunun bozulduğunu fark edersiniz. Pratik işareti, hedefte html/html/html adında bir klasör görmenizdir.
Akılda tutulacak kural: sondaki eğik çizgi "bu klasörün içini dök" demektir. Eğik çizgi olmadan "bu klasörün kendisini götür" demektir. Hedef yol için bu fark yoktur; orada sondaki eğik çizgi etkisizdir.
Gerçekten işe yarayan seçenekler
man rsync'in tam listesi yüzden fazla bayrak içerir. Bunlar web sunucularında pratikte gerekli olanlardır:
| Bayrak | İşlev | Bedel veya not |
|---|---|---|
-a | Arşiv modu: özyinelemeli, izinleri, sahipliği, bağlantıları ve zamanları korur | Sahipliği hedefte yalnızca root uygulayabilir |
-v | Aktarılan dosyaları gösterir | Milyonlarca dosyada log'u ağırlaştırır |
-n | Deneme çalıştırması; hiçbir değişiklik uygulanmaz | Her --delete öncesi zorunludur |
--delete | Kaynakta olmayan dosyaları hedeften siler | Tehlikeli; yanlış bir eğik çizgiyle tüm hedef boşalır |
--exclude | Deseni transferden hariç tutar | Desenlerin sırası önemlidir |
--partial | Yarım kalan dosyayı tutar | O olmadan eksik dosya silinir |
--bwlimit | Bant genişliğini saniyede kilobayt olarak sınırlar | 5000 değeri yaklaşık 5 megabayt/saniye demektir |
Bir WordPress sitesinin günlük yedeklemesi için kullandığım kombinasyon şudur:
rsync -avz --partial --bwlimit=8000 \
--exclude='wp-content/cache/' \
--exclude='*.log' \
/var/www/html/ backup@10.0.0.5:/srv/backups/site1/
Bant genişliği sınırını hafife almayın. Yedekleme, kullanıcı trafiğinin geldiği aynı ağ bağlantısı üzerindeyse, sınırsız bir rsync sitenin TTFB'sini birkaç dakika boyunca yükseltebilir. 100 megabitlik bir bağlantıda saniyede 8000 kilobayt değeri kapasitenin yaklaşık %60'ını alır ve geri kalanı canlı trafik için kalır.
Kesilen transferi sıfırdan başlamadan sürdürme
20 GB'lık bir dosyanın transferi tam ortasında kesilirse, rsync varsayılan olarak hedeflerdeki eksik dosyayı siler ve bir sonraki sefer baştan başlar. --partial ile yarım kalan dosya yerinde kalır ve sonraki çalıştırma aynı yerden devam eder. Büyük dosyalar için --append-verify de bir seçenektir: aktarılan kısmın sağlam olduğunu varsayar ve yalnızca devamını gönderir. Ancak o ilk kısım bozulmuşsa, nihai dosya bozuk kalır. Hassas yedeklemeler için --partial'ı tercih ederim ve tamamlandıktan sonra her şeyin aynı olduğunu checksum ile doğrulamak için bir kez rsync -avnc çalıştırırım.
Uzun transferler için rsync çalıştırmasını screen veya tmux altına koyun. SSH kesilirse ve rsync onun alt süreci olarak ölürse, o saatlerin hepsi boşa gider.
Güvenli silme: --delete ile kendinizi nasıl yok etmezsiniz
--delete, rsync'i basit bir kopyalayıcıdan gerçek bir senkronizasyon aracına dönüştüren şeydir. O olmadan, kaynaktan silinen dosyalar hedefte sonsuza kadar kalır ve yedeğiniz giderek değersizleşir. O olduğunda ise kaynak yoldaki bir hata, hedeften veri silinmesi anlamına gelir.
Güvenli yöntem, her zaman önce -n ile çalıştırıp çıktıyı okumaktır:
rsync -avn --delete /var/www/html/ backup@10.0.0.5:/srv/backups/site1/
deleting ile başlayan satırlar, silinecek dosyalardır. Sayıları beklenmedik şekilde fazlaysa, yolu yanlış yazmışsınızdır. Bir başka koruma katmanı --max-delete=100'dür: rsync bundan fazla dosya silmek isterse durur. Bu bayrak, eksik bir eğik çizgi yüzünden tüm hedefin silinmesi gibi bir felaketi önler.
İkinci nokta, --delete'in --exclude ile etkileşimidir. Hariç tutulmayan dosyalar hedefte rsync'in gözünde "korumalı"dır ve --delete-excluded kullanmadığınız sürece silinmez. Hedefte yalnızca orada kalması gereken dosyalarınız varsa (yerel önbellek gibi), bu davranış tam olarak istediğiniz şeydir.
rsync doğru cevap vermediğinde
Her biri farklı bir nedene sahip üç yaygın işaret:
- Başlangıçta "Permission denied (publickey)": SSH anahtarı hedef kullanıcıya kurulu değil. rsync aynı SSH mekanizmasını kullanır, yani önce
ssh user@hostparolasız çalışmalıdır. - Transfer ortasında "rsync: mkstemp ... failed: Permission denied": Hedef kullanıcının hedef klasörde yazma izni yok. rsync her dosya için geçici bir dosya oluşturur ve sonra taşır; klasör yazılabilir değilse bu hatayı görürsünüz.
- Transfer her seferinde tüm dosyaları gönderiyor: Muhtemelen mtime korunmuyor.
-akullanmadıysanız veya hedef dosya sistemi FAT gibi zamanları iki saniye hassasiyetle saklıyorsa, rsync her zaman dosyanın değiştiğini düşünür.-aekleyin.
Hedef sunucunuz paylaşımlı bir hostingse ve tam SSH erişiminiz yoksa, rsync bir seçenek değildir ve diğer transfer yöntemlerine bakmalısınız. Tam kontrole sahip sunucular için, SSH erişimi ve önceden kurulu rsync ile Linux hosting mantıklı bir başlangıç noktasıdır.
Cron ile günlük yedekleme scripti
Hem log tutan hem de hata durumunda e-posta gönderen kısa bir script, her seferinde elle çalıştırdığınız uzun bir komuttan daha iyidir:
#!/bin/bash
LOG=/var/log/rsync-backup.log
rsync -az --partial --delete --max-delete=200 \
--exclude='wp-content/cache/' \
/var/www/html/ backup@10.0.0.5:/srv/backups/site1/ \
>> "$LOG" 2>&1
echo "$(date '+%F %T') exit=$?" >> "$LOG"
Son satırı silmeyin. Çıkış kodu kaydedilmezse, rsync başarısız olur ve cron sadece sessiz kalırsa, haftalar sonra yedeklerin eksik olduğunu fark edersiniz. Sıfır çıkış kodu başarı demektir; başka her sayı log'u açmanız gerektiği anlamına gelir.
Aynı sunucuda WordPress çalıştırıyorsanız, zamanlamaya dikkat edin. Cron yedeklemeyi tam wp-cron'un da çalıştığı anda başlatırsanız, ikisi de disk ve CPU'ya baskı yapar. Bu çakışma ve çözümü hakkında WordPress wp-cron ve gerçek cron ile değiştirilmesi yazısında yazdım.
Sık sorulan sorular
rsync ile scp arasındaki fark nedir ve hangisini seçmeliyim?
scp her seferinde tüm dosyayı baştan aktarır ve kesilen transferi sürdürme veya hedeften fazla dosyaları silme imkanı yoktur. rsync yalnızca farkları gönderir ve --delete ile hedefi tam olarak kaynağın aynası yapabilir. Tek seferlik küçük bir dosya transferi için scp daha basittir; tekrarlanacak her şey için rsync doğru seçimdir.
rsync neden her seferinde tüm dosyaları yeniden aktarıyor?
Çoğu durumda dosyaların değişiklik zamanı korunmadığı için. -a bayrağını unutmuşsunuzdur veya hedef dosya sistemi mtime'ı düşük hassasiyetle saklayan bir türdendir. rsync -avni ile çalıştırın ve hangi dosyaların transfer listesinde olduğunu görün; hepsi oradaysa sorun içerikte değil zamandadır.
rsync dosyaları hedef sunucuda şifreleyebilir mi?
rsync'in kendisinin içerik şifrelemesi yoktur. Transfer SSH üzerinden şifrelenir, ancak dosya hedef diskte orijinal haliyle saklanır. Şifrelenmiş yedek istiyorsanız, transferden sonra dosyaları gpg veya openssl enc gibi bir araçla şifrelemelisiniz ya da bunu dahili olarak yapan bir yedekleme aracı kullanmalısınız.
Yalnızca belirli bir tarihten daha yeni dosyaları nasıl aktarırım?
--newer kullanın: rsync -av --newer='2024-01-01' /src/ user@host:/dst/. Bu bayrak yalnızca mtime'ı verilen tarihten sonra olan dosyaları gönderir. Bir zaman aralığı için --newer ve --older'ı birlikte kullanın. Bu filtrenin dosya oluşturma tarihi üzerinde değil, mtime üzerinde çalıştığını unutmayın.
Otomatik yedeklemeyi kurmadan önce yol yapısını ve izinleri bir kez doğru şekilde düzenlemek istiyorsanız, ServerNet'in dokümantasyonu ve bilgi bankası iyi bir başlangıç noktasıdır. Ve yalnızca iki sunucunuz arasındaki gerçek transfer hızının ne olduğunu bilmek istiyorsanız, ücretsiz araçlar tam da bu ölçüm için yapıldı.
Yorumlar 0
Henüz yorum yok — ilk siz olun!