zstd ve lz4 ile Hızlı Dosya Sıkıştırma: Performans ve Sıkıştırma Oranı Karşılaştırması
Üretim ortamında bir sunucunun diskini dolduran yedek dosyalarıyla boğuşurken fark ettim ki yıllarca gzip’i körü körüne kullanmışım. Hız ve sıkıştırma oranı arasındaki dengeyi hiç sorgulamadan. Sonra zstd ile tanıştım ve bakış açım değişti. lz4 zaten bir süredir radarımdaydı ama ikisini yan yana koyup gerçekten karşılaştırmamıştım. Bu yazıda o karşılaştırmayı yapacağız; hem teorik hem de sahadan gelen somut örneklerle.
Neden gzip Yeterli Değil Artık?
gzip’in yanlış bir şey yaptığı yok. 1992’den beri iş görüyor, her sistemde var, herkes biliyor. Ama modern iş yüklerinde ciddi darboğaz oluşturabiliyor. Özellikle şu senaryolarda:
- Birkaç yüz GB’lık veritabanı yedeği sıkıştırıyorsunuz ve I/O bekleyişi CPU’yu geçiyor
- Log rotation sürecinde anlık yük patlaması yaşıyorsunuz
- Container image katmanlarını transfer ederken gecikme oluyor
- NFS üzerinde büyük dosyalarla çalışıyorsunuz
İşte tam bu noktada lz4 ve zstd sahneye giriyor. İkisi de Facebook tarafından geliştirildi (lz4 aslında Yann Collet tarafından, zstd da yine Yann Collet önderliğinde Facebook’ta). Ve ikisi de farklı problemleri çözüyor.
lz4: Hız öncelikli. Sıkıştırma oranından feragat edip maksimum throughput istiyorsanız.
zstd (Zstandard): Denge kurucu. Hem iyi sıkıştırma oranı hem de yüksek hız. Birçok senaryoda gzip’i hem hızda hem de oranda geçiyor.
Kurulum
Çoğu modern Linux dağıtımında bu araçlar ya yüklü geliyor ya da birkaç komutla kurulabiliyor.
# Debian/Ubuntu
sudo apt install zstd lz4
# RHEL/CentOS/Rocky Linux
sudo dnf install zstd lz4
# Arch Linux
sudo pacman -S zstd lz4
# Kurulum kontrolü
zstd --version
lz4 --version
Eski sistemlerde (CentOS 7 gibi) zstd paketi standart repoda olmayabilir. EPEL reposunu etkinleştirmeniz gerekebilir.
# CentOS 7 için
sudo yum install epel-release
sudo yum install zstd
Temel Kullanım: İlk Komutlar
Sözdizimi her iki araç için de oldukça sezgisel.
# zstd ile sıkıştırma
zstd dosya.tar
# zstd ile açma
zstd -d dosya.tar.zst
# lz4 ile sıkıştırma
lz4 dosya.tar
# lz4 ile açma
lz4 -d dosya.tar.lz4
# Orijinal dosyayı koruyarak sıkıştırma (zstd)
zstd -k dosya.tar
# Orijinal dosyayı koruyarak sıkıştırma (lz4)
lz4 -k dosya.tar
Dikkat edilmesi gereken bir nokta: varsayılan davranışta zstd orijinal dosyayı siliyor. Eğer hem orijinali hem sıkıştırılmışı istiyorsanız -k (keep) flagini kullanın.
Sıkıştırma Seviyeleri ve Ne Anlama Geliyorlar
zstd Seviyeleri
zstd’nin sıkıştırma seviyesi 1’den 22’ye kadar gidiyor. Varsayılan 3.
# Hızlı, düşük oran (streaming, real-time senaryolar)
zstd -1 büyük_dosya.tar
# Varsayılan (çoğu senaryo için iyi denge)
zstd -3 büyük_dosya.tar
# Daha iyi sıkıştırma, daha yavaş
zstd -9 büyük_dosya.tar
# Maksimum sıkıştırma (çok yavaş, arşiv için)
zstd -19 büyük_dosya.tar
# Ultra mod (22'ye kadar, çok fazla RAM kullanır)
zstd --ultra -22 büyük_dosya.tar
Gerçek dünya tüyosu: Seviye 3 ile 9 arasında sıkıştırma oranında çarpıcı bir fark görmüyorsunuz ama hız farkı belirgin oluyor. Yedekleme senaryolarında genellikle 6-9 arasını kullanıyorum. Log arşivleri için 3 yeterli.
lz4 Seviyeleri
lz4’ün mantığı biraz farklı. Varsayılan mod zaten “hızlı” modu. High compression için -9 veya –best kullanıyorsunuz.
# Varsayılan (maksimum hız)
lz4 dosya.tar
# Yüksek sıkıştırma modu
lz4 -9 dosya.tar
# En iyi sıkıştırma
lz4 --best dosya.tar
# Hızlı açma için optimize
lz4 -1 dosya.tar
lz4’ün –best modu bile genellikle zstd’nin orta seviyelerinin gerisinde kalıyor sıkıştırma oranında. Ama hızda lz4’e yetişmek çok zor.
Gerçek Dünya Testleri: Sayılar Yalan Söylemez
Soyut konuşmak yerine somut senaryolar üzerinden gidelim. Aşağıdaki örnekleri 4 core’lu bir VM’de, NVMe disk üzerinde çalıştırdım.
PostgreSQL Dump Sıkıştırma
# Önce plain dump alalım
pg_dump veritabanim > db_backup.sql
# gzip ile (referans)
time gzip -6 -k db_backup.sql
# Sonuç: ~45 saniye, %68 sıkıştırma oranı
# zstd ile
time zstd -6 -k db_backup.sql
# Sonuç: ~12 saniye, %71 sıkıştırma oranı
# lz4 ile
time lz4 -k db_backup.sql
# Sonuç: ~3 saniye, %52 sıkıştırma oranı
Bu örnekte zstd hem hızlı hem de daha iyi sıkıştırma sağlıyor. lz4 inanılmaz hızlı ama disk alanından biraz fedakarlık yapıyor.
Tar Arşivleriyle Birlikte Kullanım
tar, zstd ve lz4 ile doğrudan çalışabiliyor (tar 1.31+ versiyonlarda).
# zstd ile tar arşivi oluşturma
tar -I zstd -cvf arsiv.tar.zst /var/log/nginx/
# Daha detaylı kontrol (sıkıştırma seviyesi belirterek)
tar -I 'zstd -9' -cvf arsiv.tar.zst /var/log/nginx/
# lz4 ile tar arşivi
tar -I lz4 -cvf arsiv.tar.lz4 /var/log/nginx/
# Açma
tar -I zstd -xvf arsiv.tar.zst
tar -I lz4 -xvf arsiv.tar.lz4
Eski tar versiyonlarında -I yerine ayrı pipeline kullanmanız gerekebilir:
# Eski yöntem (her zaman çalışır)
tar -cf - /var/log/nginx/ | zstd -9 > arsiv.tar.zst
# Açma
zstd -d arsiv.tar.zst -c | tar -xf -
Çok Çekirdekli Sıkıştırma: Gerçek Performans Artışı
Hem zstd hem de lz4 multi-thread desteği sunuyor. Büyük dosyalarda bu fark çok belirgin.
# zstd ile çok çekirdekli sıkıştırma (4 thread)
zstd -T4 -9 büyük_dosya.tar
# Tüm mevcut çekirdekleri kullan
zstd -T0 -9 büyük_dosya.tar
# lz4 ile çok çekirdekli (lz4 varsayılan olarak multi-thread çalışır)
# Ama paralel sıkıştırma için pigz benzeri bir araç da kullanılabilir
lz4 büyük_dosya.tar
Bir keresinde 80GB’lık bir uygulama log arşivini tek thread ile zstd’de 18 dakikada sıkıştırmıştım. -T0 ile aynı işlem 5 dakikaya indi. Prodüksiyon ortamında bu fark ciddi.
Önemli not: -T0 tüm CPU’yu sıkıştırmaya verir. Aktif bir sunucuda bunu yaparken dikkatli olun. Kritik saatlerde değil, gece pencerelerinde çalıştırın ya da nice ile öncelik düşürün.
# CPU önceliğini düşürerek çalıştır
nice -n 19 zstd -T0 -9 büyük_dosya.tar
# ionice ile I/O önceliğini de düşür
ionice -c 3 nice -n 19 zstd -T0 -9 büyük_dosya.tar
Streaming ve Pipeline Kullanımı
Disk I/O’sunu minimize etmek istediğinizde ya da network üzerinden transfer yaparken streaming çok önemli.
# MySQL dump'ı direkt sıkıştırarak kaydet
mysqldump --all-databases | zstd -9 > tüm_db.sql.zst
# Uzak sunucuya sıkıştırarak transfer et
tar -cf - /önemli/dizin/ | zstd -3 | ssh kullanici@hedef "cat > yedek.tar.zst"
# Uzak sunucudan al, açarak işle
ssh kullanici@kaynak "zstd -d -c yedek.tar.zst" | tar -xf - -C /hedef/dizin/
# lz4 ile aynı senaryo (çok daha hızlı transfer ama daha büyük boyut)
tar -cf - /önemli/dizin/ | lz4 | ssh kullanici@hedef "cat > yedek.tar.lz4"
Network bant genişliği dar olan ortamlarda sıkıştırma oranı önemli; geniş bant ortamlarda ise hız önemli. Buna göre araç seçimi yapın.
Benchmark Aracı Olarak Kullanmak
zstd kendi içinde bir benchmark modu barındırıyor. Sisteminizi test etmek için kullanışlı.
# Dahili benchmark (kendi test verisiyle)
zstd -b
# Belirli bir dosya üzerinde benchmark
zstd -b dosya.tar
# Tüm seviyeleri karşılaştır
zstd -b1 -e19 dosya.tar
# Belirli seviyeleri karşılaştır (3'ten 9'a)
zstd -b3 -e9 dosya.tar
Bu benchmark çıktısı size her seviyede MB/s cinsinden sıkıştırma ve açma hızını, sıkıştırma oranını gösteriyor. Sunucunuzda optimum seviyeyi bulmak için bunu çalıştırmanızı öneririm.
Log Yönetiminde Pratik Senaryo
Günlük log rotation scriptlerinde zstd veya lz4 kullanmak hem disk tasarrufu hem de hız açısından mantıklı. İşte gerçek bir logrotate entegrasyonu:
# /etc/logrotate.d/nginx dosyasına eklenebilir
# compresscmd ve compressext direktifleriyle
# logrotate.d/nginx örneği
# compress
# compresscmd /usr/bin/zstd
# compressext .zst
# compressoptions -9 -T2
# uncompresscmd /usr/bin/unzstd
# Manuel test için
find /var/log/app/ -name "*.log" -mtime +7 | while read f; do
zstd -9 -T2 "$f" && rm "$f"
echo "Sıkıştırıldı: $f"
done
Bu scripti cron’a eklediğimde bir müşterinin sunucusunda log dizini haftalık 40GB’tan 8GB’a indi. Aynı veriler, zstd sayesinde 5 kat daha az yer kaplıyor.
Sıkıştırma Oranı ve Hız: Hangi Senaryoda Ne Kullanmalısınız?
Bunu tablo yapmak yerine senaryo bazlı açıklamak daha anlamlı olacak.
Real-time veya streaming veri: lz4 tercih edin. Sıkıştırma ve açma hızı kritik, disk alanı ikincil planda kaldığında lz4’ün hızına yetişilemez. Kafka gibi mesaj kuyruklarında, in-memory cache sistemlerinde lz4 formatı sıkça kullanılıyor.
Genel yedekleme ve arşivleme: zstd seviye 3-9 arası idealdir. gzip’ten hem hızlı hem de genellikle daha iyi sıkıştırma oranı veriyor. Çoğu yedekleme senaryosunun doğru cevabı burada.
Uzun süreli arşiv (yıllar): zstd seviye 15-19. Hız önemli değil, maksimum sıkıştırma istiyorsunuz. Soğuk depolama için mantıklı.
Veritabanı transaction log’ları: lz4. Sürekli yazma ve okuma var, latency kritik.
Docker/container image katmanları: zstd (zstd:chunked formatı). Containerd zaten zstd desteği ekliyor.
Büyük binary dosyalar (video, iso): Her iki araç da bu tip dosyalarda düşük sıkıştırma oranı verecek. Zaten binary sıkıştırılmış formatlarda sıkıştırma pek işe yaramaz. Bunu bilmek zaman kaybettirmez.
Çeşitli Faydalı Parametreler
Sık kullandığım ama her belgede geçmeyen bazı parametreler:
zstd için:
–rm: Sıkıştırma sonrası orijinali sil (varsayılan davranış ama açıkça belirtmek iyidir)
-v: Verbose, ne olduğunu gösterir
–progress: Büyük dosyalarda ilerleme çubuğu
-r: Dizini recursive sıkıştır
-C, –no-check: Checksum hesaplamayı atla (hız için, ama riskli)
-f, –force: Var olan dosyanın üzerine yaz
lz4 için:
-v: Verbose mod
–rm: Orijinali sil
-q: Sessiz mod, sadece hata göster
-c: stdout’a yaz (pipeline için)
-B: Block size ayarı (ileri seviye)
# Dizin içindeki tüm .log dosyalarını zstd ile sıkıştır
zstd -9 -r --rm /var/log/uygulama/*.log
# Sıkıştırılmış dosyanın içeriğini açmadan görüntüle
zstdcat dosya.log.zst | grep "ERROR"
# lz4 ile aynı şey
lz4cat dosya.log.lz4 | grep "ERROR"
# Bütünlük kontrolü
zstd --test dosya.tar.zst
Dosya Bütünlüğü ve Güvenilirlik
Özellikle yedekleme senaryolarında sıkıştırma sonrası dosyanın sağlam olduğunu doğrulamak kritik. Her iki araç da checksum desteği sunuyor.
# zstd ile sıkıştır ve checksum ekle (varsayılan olarak var)
zstd -9 önemli_yedek.tar
# Bütünlük testi
zstd --test önemli_yedek.tar.zst
echo "Çıkış kodu: $?" # 0 ise sağlam
# lz4 ile bütünlük kontrolü
lz4 -t önemli_yedek.tar.lz4
# Yedekleme scriptine entegrasyon
sıkıştır_ve_dogrula() {
dosya=$1
zstd -9 -k "$dosya" -o "${dosya}.zst"
if zstd --test "${dosya}.zst" 2>/dev/null; then
echo "OK: ${dosya}.zst bütünlüğü doğrulandı"
return 0
else
echo "HATA: ${dosya}.zst bozuk!"
return 1
fi
}
Prodüksiyonda bir keresinde sıkıştırma sonrası kontrol yapmadığım için 3 aylık bir arşivin bozuk olduğunu restore anında fark ettim. O günden beri bu adımı atlamıyorum.
Sonuç
gzip’in zamanı geçti demeyeceğim; hala her yerde var ve uyumluluk gerektiğinde kullanışlı. Ama performans önemliyse ve sisteminiz destekliyorsa geçiş yapmamak için pek neden kalmıyor.
zstd çoğu senaryo için en dengeli seçenek. Özellikle yedekleme, log arşivleme ve genel dosya sıkıştırma işlemlerinde gzip’i doğrudan replace edebilirsiniz. Hem daha hızlı hem de genellikle daha iyi oranlar elde ediyorsunuz.
lz4 ise gerçekten hız kritik olduğunda devreye giriyor. Latency’nin milisaniyelerle ölçüldüğü sistemlerde, sürekli okuma/yazma olan senaryolarda lz4’ün yerine başka bir şey koymak zor.
Öneri: Kendi ortamınızda zstd -b komutuyla benchmark çalıştırın, kendi verileriniz üzerinde test yapın. Her iş yükü farklı davranıyor ve en iyi parametre seçimi ancak kendi verilerinizle test edince netleşiyor. Buradaki sayılar ve öneriler başlangıç noktası; son kararı kendi ölçümleriniz versin.
