rsync Alternatifi: Unison ile Çift Yönlü Dosya Senkronizasyonu
Yıllarca rsync kullandım, hala da kullanıyorum. Ama bir gün bir kullanıcı beni aradı: “Hem evdeki bilgisayarımda hem de ofisteki sunucuda aynı proje klasörü var, ikisinde de değişiklik yapıyorum, nasıl senkronize ederim?” O anda rsync’in bu iş için ne kadar zahmetli olduğunu fark ettim. Rsync tek yönlü çalışır; kaynaktan hedefe kopyalar, hedefteki değişiklikleri görmezden gelir. İşte tam bu noktada Unison devreye giriyor.
Unison Nedir ve Neden Farklı?
Unison, Cornell Üniversitesi’nde geliştirilen açık kaynaklı bir dosya senkronizasyon aracıdır. Rsync’ten temel farkı çift yönlü çalışmasıdır. Her iki taraftaki değişiklikleri izler, karşılaştırır ve akıllıca birleştirir. Çakışma (conflict) durumlarını tespit eder ve kullanıcıya bildirir.
Rsync ile Unison arasındaki farkı şöyle özetleyebilirim:
- rsync: A’dan B’ye kopyalar. B’de ne olduğuna bakmaz. Tek yön.
- unison: A ve B’yi karşılaştırır, her iki taraftaki değişiklikleri birbirine yansıtır. Çift yön.
- rsync: Conflict yönetimi yok. Son çalıştırılan kazanır.
- unison: Conflict tespiti yapar, çözüm için kullanıcıya sorar veya profil ayarlarına göre otomatik karar verir.
- rsync: Delta transfer ile hız odaklıdır, büyük dosyalarda çok iyi performans gösterir.
- unison: Hız önceliği daha düşüktür ama tutarlılık önceliği yüksektir.
Kurulum
Unison’ı çoğu Linux dağıtımında paket yöneticisi ile kurabilirsiniz. Dikkat etmeniz gereken kritik nokta şu: Her iki tarafta da aynı Unison versiyonu olmalı. Farklı versiyonlar birbirleriyle konuşmayı reddeder. Bu, özellikle eski bir sunucu ile yeni bir iş istasyonunu senkronize etmeye çalışırken can sıkıcı bir sorun haline gelir.
# Ubuntu/Debian
sudo apt update
sudo apt install unison
# RHEL/CentOS/Rocky Linux
sudo dnf install unison
# Arch Linux
sudo pacman -S unison
# macOS (Homebrew ile)
brew install unison
# Versiyon kontrolü - her iki tarafta aynı olmalı
unison -version
Eğer paket yöneticisindeki versiyonlar uyuşmuyorsa, kaynak koddan derleme yapmanız gerekebilir. Bunun için OCaml gereklidir:
# OCaml kurulumu
sudo apt install ocaml ocaml-findlib
# Kaynak koddan derleme
wget https://github.com/bcpierce00/unison/archive/refs/tags/v2.53.3.tar.gz
tar -xzf v2.53.3.tar.gz
cd unison-2.53.3
make
sudo cp src/unison /usr/local/bin/
Temel Kullanım: İlk Senkronizasyon
En basit haliyle Unison iki dizin arasında çalışır. Yerel iki dizini senkronize etmek için:
# İki yerel dizin arasında senkronizasyon
unison /home/ali/proje-a /home/ali/proje-b
# İlk çalıştırmada Unison her iki tarafı tarar ve farkları listeler
# Değişiklik başına ne yapılacağını sorar:
# < : sağdan sola kopyala
# > : soldan sağa kopyala
# / : çakışma (conflict)
# [f] follow : bu dosya için kararı uygula
İlk çalıştırmada Unison, her iki tarafı “boş” kabul eder ve her şeyi senkronize etmeye çalışır. Bu davranış bir sonraki çalıştırmada değişir; sadece o zamandan bu yana değişen dosyaları takip eder.
SSH Üzerinden Uzak Senkronizasyon
Gerçek dünyada en çok kullanılan senaryo budur. Unison SSH üzerinden sorunsuz çalışır:
# Yerel dizini uzak sunucudaki dizinle senkronize et
unison /home/ali/projeler ssh://192.168.1.100//home/ali/projeler
# Kullanıcı adı belirtmek için
unison /home/ali/projeler ssh://[email protected]//home/ali/projeler
# SSH portu farklıysa
unison /home/ali/projeler
"ssh://[email protected]:2222//home/ali/projeler"
Burada çift slash (//) dikkat çekici. İlk slash SSH protokolü sözdiziminin parçası, ikincisi ise uzak sistemdeki mutlak yolun başlangıcı. Göreli yol kullanmak istiyorsanız tek slash kullanın; bu durumda home dizinine göre işler.
Profil Dosyaları: Asıl Güç Buradan Geliyor
Unison’ın gerçek gücü profil sistemidir. ~/.unison/ dizininde .prf uzantılı profil dosyaları oluşturursunuz. Bu sayede karmaşık senkronizasyon kurallarını tekrar tekrar yazmak zorunda kalmazsınız.
# Profil dosyası oluştur
mkdir -p ~/.unison
nano ~/.unison/is-yedek.prf
Basit bir profil örneği:
# ~/.unison/is-yedek.prf
# Senkronize edilecek dizinler
root = /home/ali/belgeler
root = ssh://[email protected]//home/ali/belgeler
# Görmezden gelinecek dosya ve dizinler
ignore = Name .git
ignore = Name .DS_Store
ignore = Name *.tmp
ignore = Name *~
ignore = Path node_modules
ignore = Path __pycache__
ignore = Path .cache
# Log dosyası
log = true
logfile = /home/ali/.unison/is-yedek.log
# Batch modu: onay sormadan çalışır (dikkatli kullanın)
# batch = true
# Çakışmalarda yeni olanı tercih et
prefer = newer
# Timestamps'i koru
times = true
# Symlink'leri takip etme
followsymlinks = false
Profili çalıştırmak için:
# Profil adıyla çalıştır (uzantısız)
unison is-yedek
# Verbose modda çalıştır
unison is-yedek -verbose
# Sadece ne yapacağını göster, gerçekten yapma
unison is-yedek -testonly
Çakışma Yönetimi: En Kritik Konu
Çakışma durumu, aynı dosyanın her iki tarafta da son senkronizasyondan bu yana değiştirildiği anlamına gelir. Unison bunu tespit ettiğinde birkaç şekilde davranabilir:
# İnteraktif modda kullanıcıya sor (varsayılan)
unison profilim
# Yeni olanı tercih et
unison profilim -prefer newer
# Soldaki (birinci root) tercih et
unison profilim -prefer /home/ali/belgeler
# Sağdaki (ikinci root) tercih et
unison profilim -prefer ssh://[email protected]//home/ali/belgeler
# Backup al ve yeni olanı uygula
unison profilim -prefer newer -backup 'Name *'
Yedekleme özelliği son derece değerlidir. Unison, üzerine yazmadan önce eski dosyayı ~/.unison/backup/ dizinine kopyalar. Bir felaket anında hayat kurtarır.
Pratik Senaryo 1: Geliştirici İş İstasyonu Senkronizasyonu
Diyelim ki hem ofiste hem evde çalışan bir geliştiricisiniz. Her iki makinede de projeniz var ve git kullanmıyorsunuz (ya da git kullandığınız bir alt projedir ama binary dosyalar, konfigürasyon dosyaları vb. de var). Şöyle bir profil oluşturabilirsiniz:
# ~/.unison/gelistirici.prf
root = /home/ali/workspace
root = ssh://ev-sunucu.example.com//home/ali/workspace
# Git, IDE cache ve geçici dosyaları atla
ignore = Name .git
ignore = Name .idea
ignore = Name .vscode
ignore = Name *.pyc
ignore = Name *.class
ignore = Name *.o
ignore = Path node_modules
ignore = Path target
ignore = Path build
ignore = Path dist
ignore = Path .gradle
ignore = Name .env.local
# Dosya izinlerini senkronize et
perms = -1
# Zaman damgalarını koru
times = true
# Paralel işlem sayısı
fastcheck = true
# Log tut
log = true
logfile = /home/ali/.unison/gelistirici.log
# Çakışmalarda yeni olanı al ama backup'ı koru
prefer = newer
backup = Name *
backuplocation = local
backupsuffix = .bak.%Y%m%d%H%M%S
Bu profili sabah ofise geldiğinizde ve akşam eve giderken çalıştırın. İki dakika içinde her şey senkronize olur.
Pratik Senaryo 2: Cron ile Otomatik Senkronizasyon
Batch modunda Unison etkileşimsiz çalışır, yani cron ile kullanılabilir. Ancak çakışma durumunda ne yapacağını bilmesi gerekir:
# ~/.unison/otomatik-yedek.prf
root = /var/www/html/site
root = ssh://yedek-sunucu.example.com//var/www/html/site
# Temel ayarlar
ignore = Name *.tmp
ignore = Name .htaccess.bak
ignore = Path .git
# Batch modu: kullanıcı girişi bekleme
batch = true
# Etkileşimsiz çalışma için
silent = true
# Çakışmalarda yeni olanı tercih et
prefer = newer
# Log
log = true
logfile = /var/log/unison-site-sync.log
# SSH kimlik dosyası
sshargs = -i /root/.ssh/yedek_rsa -o StrictHostKeyChecking=no
Crontab ayarı:
# Her 4 saatte bir senkronize et
crontab -e
# Şunu ekle:
0 */4 * * * /usr/bin/unison otomatik-yedek >> /var/log/unison-cron.log 2>&1
Önemli not: Cron ile kullanırken batch = true ve prefer = newer veya prefer = mutlaka ayarlanmalı. Aksi halde çakışmada Unison askıda kalır ve cron job’ınız hiç bitmez.
Pratik Senaryo 3: Ekip İçi Dosya Paylaşımı
Küçük ekiplerde bazen bir NAS veya ortak sunucu üzerinden çalışmak gerekir. Merkezi bir sunucu olsun, her ekip üyesi kendi dizinini bununla senkronize etsin:
# ~/.unison/ekip-paylasim.prf
root = /home/kullanici/ekip-dosyalari
root = ssh://nas.sirket.local//volume1/ekip
ignore = Name .DS_Store
ignore = Name Thumbs.db
ignore = Name desktop.ini
ignore = Name *.part
ignore = Name ~$*
# Microsoft Office geçici dosyalarını atla
ignore = Name .~lock.*
times = true
log = true
logfile = /home/kullanici/.unison/ekip.log
# Çakışmalarda log'a yaz ama eski versiyonu yedekle
backup = Name *
backuplocation = central
backupdir = /home/kullanici/.unison/yedekler
Sık Karşılaşılan Hatalar ve Çözümleri
“Warning: No valid roots” hatası: Profil dosyasında root satırları eksik veya yanlış yazılmış.
“Unison is already running” hatası: Önceki bir Unison işlemi kilid dosyası bırakmış. ~/.unison/*.lk dosyalarını silin.
# Kilid dosyalarını temizle
rm ~/.unison/*.lk
“Fatal error: Received unexpected header” hatası: İki taraftaki Unison versiyonları farklı. Her iki tarafı aynı versiyona getirin.
Büyük dosyalarda yavaşlık: fastcheck = true ayarı, dosyaların içeriğini değil inode ve zaman damgasını kontrol eder. Çok büyük dizinlerde hız kazanırsınız ama küçük bir doğruluk kaybı riski vardır.
# Hız/güvenilirlik dengesi için
unison profilim -fastcheck true
# Tam checksum karşılaştırması için (yavaş ama güvenilir)
unison profilim -fastcheck false
SSH timeout sorunları: Büyük aktarımlarda SSH bağlantısı kopabilir. SSH yapılandırmasına keep-alive ekleyin:
# ~/.ssh/config dosyasına ekle
Host sunucu.sirket.com
ServerAliveInterval 60
ServerAliveCountMax 3
IdentityFile ~/.ssh/id_rsa
Unison GUI: Görsel Arayüz Seçeneği
Terminal sevmeyenler için Unison’ın GTK tabanlı bir GUI versiyonu da vardır:
# GTK arayüzü ile kur
sudo apt install unison-gtk
# GUI ile başlat
unison-gtk
# Ya da var olan profili GUI ile aç
unison-gtk profilim
GUI arayüzünde çakışmalar çok daha anlaşılır şekilde gösterilir. Her dosya için sol ve sağ versiyon yan yana gösterilir, hangisini tutmak istediğinizi tıklayarak seçebilirsiniz. Özellikle Unison’a yeni başlayanlar için GUI ile birkaç senkronizasyon yapıp işin mantığını kavramak iyi bir yaklaşım.
Performans Karşılaştırması: Rsync mi Unison mu?
Bu sorunun cevabı kullanım senaryosuna göre değişir.
Büyük binary dosyaların tek yönlü dağıtımı için rsync daha iyidir. Delta transfer algoritması sayesinde değişen kısımları gönderir, bu büyük dosyalarda muazzam bant genişliği tasarrufu sağlar.
İki taraflı metin dosyası veya yazılım projesi senkronizasyonu için Unison daha iyidir. Çakışma yönetimi, profil sistemi ve tutarlılık garantisi çok daha güvenlidir.
Unison da delta transfer yapabilir, bu özellik rsrc = true ile aktif edilir ama rsync kadar optimize değildir.
Pratik tavsiyem: Deployment pipeline’ında rsync kullanın. Geliştirici iş istasyonu veya ekip dosya paylaşımında Unison kullanın.
İleri Seviye: Ignore Kuralları
Unison’ın ignore sistemi oldukça güçlüdür:
# Tam isim eşleşmesi
ignore = Name .DS_Store
# Joker karakterlerle eşleşme
ignore = Name *.log
ignore = Name temp_*
# Belirli bir path
ignore = Path logs
ignore = Path tmp/cache
# Regex ile
ignore = Regex .*/node_modules/.*
ignore = Regex .*.pyc
# Büyük/küçük harf duyarsız
ignore = BelowPath uploads/thumbnails
Belirli dosyaları her zaman dahil etmek için ignorenot kullanın:
# Tüm log dosyalarını atla, ama error.log'u atma
ignore = Name *.log
ignorenot = Name error.log
Sonuç
Unison, rsync’in çözemeyeceği bir problemi çözüyor: çift yönlü senkronizasyon. Eğer iki farklı lokasyonda aynı dosyalar üzerinde bağımsız değişiklikler yapıyorsanız, rsync sizi sonunda bir felakete götürür. Ya birinin değişikliklerini kaybedersiniz ya da kim neyi değiştirdi bilemezsiniz.
Unison’a geçerken dikkat etmeniz gereken iki kritik nokta var. Birincisi, her iki tarafta aynı versiyon olmalı; bunu bir kez atlarsanız saat kaybedersiniz. İkincisi, batch modunda çalışırken prefer ayarını mutlaka yapın; yoksa cron job’larınız askıda kalır.
Profil sistemi sayesinde onlarca farklı senkronizasyon senaryosunu tek bir araçla yönetebilirsiniz. İş makinesi ile ev bilgisayarı, geliştirme sunucusu ile üretim, ofis NAS’ı ile laptop; hepsini ayrı profiller halinde tutun ve günlük rutininize dahil edin.
Rsync dosya dağıtımı içindir, Unison dosya senkronizasyonu içindir. Bu farkı kavradıktan sonra ikisini doğru yerde kullanmak çok daha netleşiyor.
