Sıkıştırma Algoritmalarını Karşılaştırma: Hız ve Boyut

Bir dosyayı sıkıştırmak kulağa basit gelir: gzip çalıştırırsın, iş biter. Ama üretim ortamında 50 GB’lık bir log dizisini sıkıştırman gerektiğinde, ya da her gece çalışan yedekleme script’in sabaha karşı 4’te sunucuyu kasıp kavurduğunda, hangi algoritmayı seçtiğin gerçekten önem kazanır. CPU süresi, disk alanı, ağ bant genişliği, hatta yedekten geri dönme hızı bile doğru sıkıştırma algoritmasına bağlı. Bu yazıda gzip, bzip2, xz, lz4 ve zstd’yi gerçek senaryolarla karşılaştıracağız.

Temel Kavramlar

Sıkıştırma algoritmalarını değerlendirirken iki temel metrik var: sıkıştırma oranı ve hız. Bunlar çoğu zaman ters orantılıdır. Daha küçük dosya istiyorsan daha fazla CPU harcarsın, daha hızlı sıkıştırma istiyorsan dosya biraz daha büyük kalır.

Bir de sıkıştırma seviyesi kavramı var. Çoğu araç 1’den 9’a kadar (bazen daha yükseğe) giden seviyeler sunar. Seviye 1 en hızlı ama en az sıkıştıran, seviye 9 en yavaş ama en çok sıkıştıran demektir.

Pratik dünyada şu soruları sorman gerekiyor:

  • Bu dosyayı kaç kez sıkıştıracaksın? (Bir kez arşiv mi, yoksa sürekli dönen loglar mı?)
  • Dosyayı geri açma hızı önemli mi? (Felaket kurtarma senaryosu mu?)
  • Sunucunun CPU’su bu iş için ne kadar zaman ayırabilir?
  • Depolama alanın kısıtlı mı, yoksa bant genişliği mi?

Araçların Tanıtımı

gzip

Linux dünyasının klasik sıkıştırma aracı. DEFLATE algoritmasını kullanır. Neredeyse her sistemde kurulu gelir, her araçla uyumludur. Orta seviye sıkıştırma oranı, makul hız. Yıllardır web sunucularının, log rotation araçlarının ve tar arşivlerinin vazgeçilmezi.

# Temel kullanım
gzip dosya.txt

# Sıkıştırma seviyesi belirtmek
gzip -9 buyuk_dosya.log

# Orijinali koruyarak sıkıştır
gzip -k config_backup.sql

# Geri açma
gzip -d dosya.txt.gz
# veya
gunzip dosya.txt.gz

# Sıkıştırma oranını göster
gzip -v dosya.txt

-k: Orijinal dosyayı siler, bu flag ile korur -v: İşlem sonunda oran bilgisi gösterir -9: Maksimum sıkıştırma (en yavaş) -1: Minimum sıkıştırma (en hızlı) -d: Decompress (açma) modu

bzip2

gzip’ten daha iyi sıkıştırma oranı sunar ama belirgin şekilde daha yavaştır. Burrows-Wheeler algoritmasını kullanır. Özellikle kaynak kod tarball’larında (.tar.bz2) sıkça görülür. Kernel arşivleri uzun yıllar bzip2 kullandı.

# Temel kullanım
bzip2 dosya.txt

# Maksimum sıkıştırma
bzip2 -9 kernel_source.tar

# Orijinali koru
bzip2 -k veritabani_dump.sql

# Geri açma
bzip2 -d dosya.txt.bz2
# veya
bunzip2 dosya.txt.bz2

# Hızlı sıkıştırma (daha az RAM kullanır)
bzip2 -1 buyuk_dosya.txt

-k: Orijinal dosyayı korur -9: Maksimum sıkıştırma, en fazla RAM kullanır -1: En az RAM kullanan, hızlı mod -t: Test modu, dosya bütünlüğünü kontrol eder

xz

LZMA2 algoritması kullanan xz, en yüksek sıkıştırma oranına ulaşır. Ama bu performans için ciddi bir bedel ödersin: işlem yavaştır, bellek tüketimi yüksektir. Büyük yazılım paketleri, kritik arşivler için idealdir. Fedora ve birçok dağıtım .rpm paketlerinde xz kullanır.

# Temel kullanım
xz dosya.txt

# Sıkıştırma seviyesi
xz -9 kritik_arsiv.tar

# Aşırı sıkıştırma modu (çok yavaş, çok küçük)
xz -9e buyuk_arsiv.tar

# Paralel sıkıştırma (çekirdek sayısı kadar thread)
xz -T 0 cok_buyuk_dosya.tar

# Geri açma
xz -d dosya.txt.xz
# veya
unxz dosya.txt.xz

# Dosya bilgisi
xz -l dosya.txt.xz

-T 0: Mevcut tüm CPU çekirdeklerini kullan -9e: Extreme mode, aynı bellek ile ekstra sıkıştırma dener -l: Arşiv hakkında bilgi listeler, açmadan -k: Orijinal dosyayı korur

lz4

Hız odaklı bir algoritma. Sıkıştırma oranı düşük, ama inanılmaz hızlı. RAM’i bol ama CPU’su kısıtlı ortamlarda, ya da çok sık erişilen verilerde lz4 mantıklı bir seçim. Docker, bazı dosya sistemleri ve veritabanı sistemleri (ZFS, RocksDB) lz4’ü dahili olarak kullanır.

# Kurulum (genellikle varsayılan gelmez)
sudo apt install lz4
# veya
sudo yum install lz4

# Temel kullanım
lz4 dosya.txt

# Hızlı mod (varsayılan zaten hızlı ama)
lz4 -1 dosya.txt

# Yüksek sıkıştırma modu
lz4 -9 dosya.txt

# Geri açma
lz4 -d dosya.txt.lz4

# stdout'a yaz (pipe için)
lz4 -c dosya.txt > cikti.lz4

# Hız testi
lz4 -b dosya.txt

-c: Stdout’a yazar, orijinali silmez -d: Decompress modu -b: Benchmark modu -BD: Block bağımlılıklarını aktif et, daha iyi oran için

zstd

Facebook’un geliştirdiği Zstandard algoritması, “en iyisi” olmak iddiasıyla ortaya çıktı ve büyük ölçüde başardı. Hem hız hem sıkıştırma oranında çok iyi bir denge kurar. Geniş seviye aralığı (-1 ile -22 arası), sözlük desteği ve çok iş parçacıklı çalışma kabiliyeti ile modern sistemlerin gözdesi. Linux çekirdeği 5.1’den itibaren btrfs zstd desteğine kavuştu, Arch Linux paket yöneticisi pacman varsayılan olarak zstd kullanıyor.

# Temel kullanım
zstd dosya.txt

# Sıkıştırma seviyesi (1-22 arası)
zstd -3 hizli_arsiv.tar     # Hızlı, makul oran
zstd -19 uzun_arsiv.tar     # Yavaş, iyi oran

# Paralel sıkıştırma
zstd -T0 buyuk_dosya.tar    # Tüm çekirdekleri kullan

# Geri açma
zstd -d dosya.txt.zst
# veya
unzstd dosya.txt.zst

# Orijinali koru
zstd -k dosya.txt

# Sıkıştırılmış dosya bilgisi
zstd -l dosya.txt.zst

# Sözlük oluştur (benzer dosyalar için)
zstd --train klasor/*.log -o log_sozluk.zstd
zstd -D log_sozluk.zstd kucuk_log.txt

-T0: Tüm CPU çekirdeklerini kullan -l: Arşiv bilgisi göster –train: Sözlük eğitimi, küçük benzer dosyalar için mükemmel -D: Önceden oluşturulmuş sözlüğü kullan -k: Orijinal dosyayı sil, bu flag ile koru

Gerçek Dünya Senaryoları

Senaryo 1: Nightly Log Rotation

Klasik bir web sunucusu senaryosu. Her gece nginx access logları döndürülüyor, eski loglar sıkıştırılıyor. Burada kritik olan şey: sıkıştırma işlemi sunucuyu yavaşlatmamalı. Gece yarısı trafik düşük olsa bile CPU’yu tıkamak istemezsin.

#!/bin/bash
# /usr/local/bin/log_compress.sh
# Log rotation sonrası sıkıştırma scripti

LOG_DIR="/var/log/nginx"
ARCHIVE_DIR="/mnt/log_arsiv"
DATE=$(date +%Y%m%d)

# Dünün loglarını bul
find "$LOG_DIR" -name "*.log.1" -type f | while read logfile; do
    filename=$(basename "$logfile")
    
    # zstd ile hızlı sıkıştırma, sunucuya yük bindirme
    # -3 hız/oran dengesi, -T0 tüm çekirdekler
    zstd -3 -T0 "$logfile" -o "${ARCHIVE_DIR}/${DATE}_${filename}.zst"
    
    if [ $? -eq 0 ]; then
        echo "$(date): $filename sıkıştırıldı" >> /var/log/compress.log
        rm "$logfile"
    else
        echo "$(date): HATA - $filename sıkıştırılamadı" >> /var/log/compress.log
    fi
done

Bu senaryoda gzip de kullanılabilir ama zstd ile karşılaştırdığında aynı seviyede çok daha küçük dosya elde edersin.

Senaryo 2: Veritabanı Yedekleme

PostgreSQL dump’ları ciddi yer tutar. Haftalık full backup için sıkıştırma oranı ön plana çıkar. Haftada bir sıkıştırıyorsan, birkaç dakika daha bekleyebilirsin.

#!/bin/bash
# PostgreSQL yedekleme ve sıkıştırma

DB_NAME="production_db"
BACKUP_DIR="/backup/postgresql"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${DATE}.sql"

echo "Dump alınıyor..."
pg_dump -U postgres "$DB_NAME" > "$BACKUP_FILE"

echo "Sıkıştırılıyor..."
# Yedekleme için xz iyi seçim: en iyi oran, hız sorun değil
# -6 seviyesi iyi bir denge noktası
xz -6 -T0 "$BACKUP_FILE"

echo "Tamamlandı: ${BACKUP_FILE}.xz"
echo "Boyut: $(du -sh ${BACKUP_FILE}.xz | cut -f1)"

# 30 günden eski yedekleri temizle
find "$BACKUP_DIR" -name "*.xz" -mtime +30 -delete

Aynı dump’ı gzip ile sıkıştırsan yaklaşık %60-65 küçülür. xz ile %70-75 civarı bekleyebilirsin. Büyük veritabanlarında bu fark onlarca gigabayta karşılık gelir.

Senaryo 3: Hızlı Veri Transferi

Sunucular arası veri aktarımında bant genişliği kısıtlı. Ama sıkıştırma CPU’yu yormamalı çünkü aynı anda başka işlemler de yapılıyor. Pipe kullanarak sıkıştırma ve transfer aynı anda yapılır.

# lz4 ile hızlı pipeline transferi
# Sıkıştırma overhead'i minimumdur, CPU serbest kalır
tar -cf - /data/buyuk_klasor | lz4 -c | ssh hedef_sunucu "lz4 -d | tar -xf - -C /hedef"

# Karşılaştırma: aynı şeyi gzip ile
tar -czf - /data/buyuk_klasor | ssh hedef_sunucu "tar -xzf - -C /hedef"

# zstd ile orta yol: iyi oran + makul hız
tar -cf - /data/buyuk_klasor | zstd -3 -T0 | ssh hedef_sunucu "zstd -d | tar -xf - -C /hedef"

Senaryo 4: Benchmark Scripti Yaz

Hangi algoritmanın kendi verin için en iyi çalıştığını test etmek istiyorsan, aşağıdaki scripti çalıştır. Herkese uyan tek bir cevap yok. Sıkıştırılabilirlik büyük ölçüde veri tipine göre değişir. JSON loglar mı, binary dump’lar mı, metin dosyaları mı?

#!/bin/bash
# compress_benchmark.sh
# Kullanım: ./compress_benchmark.sh test_dosyasi.tar

DOSYA="$1"

if [ -z "$DOSYA" ]; then
    echo "Kullanım: $0 <dosya>"
    exit 1
fi

ORIJINAL_BOYUT=$(stat -c%s "$DOSYA")
echo "Orijinal boyut: $(du -sh $DOSYA | cut -f1)"
echo "----------------------------------------"

test_compress() {
    local ISIM=$1
    local COMPRESS_CMD=$2
    local DECOMPRESS_CMD=$3
    local CIKTI="test_output.compressed"
    
    # Sıkıştırma süresi
    BASLANGIC=$(date +%s%N)
    eval "$COMPRESS_CMD "$DOSYA" > $CIKTI"
    BITIS=$(date +%s%N)
    COMPRESS_SURE=$(( (BITIS - BASLANGIC) / 1000000 ))
    
    SIKIS_BOYUT=$(stat -c%s "$CIKTI")
    ORAN=$(echo "scale=1; (1 - $SIKIS_BOYUT / $ORIJINAL_BOYUT) * 100" | bc)
    
    # Açma süresi
    BASLANGIC=$(date +%s%N)
    eval "$DECOMPRESS_CMD $CIKTI > /dev/null"
    BITIS=$(date +%s%N)
    DECOMPRESS_SURE=$(( (BITIS - BASLANGIC) / 1000000 ))
    
    echo "$ISIM:"
    echo "  Boyut: $(du -sh $CIKTI | cut -f1) (-%${ORAN} küçüldü)"
    echo "  Sıkıştırma: ${COMPRESS_SURE}ms"
    echo "  Açma: ${DECOMPRESS_SURE}ms"
    echo ""
    
    rm -f "$CIKTI"
}

test_compress "gzip -6" "gzip -6 -c" "gzip -d"
test_compress "bzip2 -6" "bzip2 -6 -c" "bzip2 -d"
test_compress "xz -6" "xz -6 -c" "xz -d"
test_compress "lz4" "lz4 -c" "lz4 -d"
test_compress "zstd -3" "zstd -3 -c" "zstd -d"
test_compress "zstd -19" "zstd -19 -c" "zstd -d"

Algoritma Seçim Rehberi

Hangi durumda ne kullanacağını bir mantık akışıyla açıklayayım.

Hız birinci öncelikse:

lz4 seç. Sıkıştırma oranı düşük ama hız konusunda rakibine zorla. Anlık veri işleme, cache sistemleri, sık erişilen geçici dosyalar için.

Denge istiyorsan (çoğu senaryo bu):

zstd -3 ya da zstd -6 kullan. Hem gzip’ten hızlı hem de daha iyi oran sunar. Nightly backup, log rotation, orta boy transferler için neredeyse her zaman doğru seçim.

Maksimum sıkıştırma önemliyse:

xz -6 ya da xz -9. Haftalık/aylık arşivler, uzun süreli depolama, bant genişliği çok kısıtlı transferler. Hız önemli değil, boyut önemli.

Uyumluluk kritikse:

gzip. Karşı tarafın ne kullandığını bilmiyorsan, gzip’i açamayacak sistem neredeyse yok. Eski sistemler, farklı işletim sistemleri, standartlaşmış formatlar.

Küçük ama benzer dosyalar varsa:

zstd + sözlük eğitimi inanılmaz sonuçlar verir. JSON API logları, küçük konfigürasyon yedekleri, ses/görüntü metadata dosyaları gibi benzer yapılı veriler için sözlük modu özellikle güçlü.

tar ile Entegrasyon

Pratikte sıkıştırmayı genellikle tar ile birlikte kullanırsın. Klasik kullanımlar:

# gzip ile tar arşivi
tar -czf arsiv.tar.gz /kaynak/klasor
tar -xzf arsiv.tar.gz

# bzip2 ile
tar -cjf arsiv.tar.bz2 /kaynak/klasor
tar -xjf arsiv.tar.bz2

# xz ile
tar -cJf arsiv.tar.xz /kaynak/klasor
tar -xJf arsiv.tar.xz

# zstd ile (modern tar sürümlerinde)
tar -cf arsiv.tar.zst --zstd /kaynak/klasor
tar -xf arsiv.tar.zst

# Pipe yöntemiyle (her araçla çalışır)
tar -cf - /kaynak/klasor | zstd -9 -T0 > arsiv.tar.zst
zstd -d arsiv.tar.zst | tar -xf -

# Paralel gzip (pigz kuruluysa)
tar -cf - /kaynak/klasor | pigz -p 4 > arsiv.tar.gz

pigz multi-thread gzip türevidir. Mevcut script’lerini gzip’ten pigz’e geçirmek için tek değişiklik gzip yerine pigz yazmak. Paralel çalıştığı için büyük dosyalarda ciddi hız farkı oluşturur.

Disk Alanı ve Sıkıştırılabilirlik Analizi

Sıkıştırma oranları veri tipine göre dramatik şekilde değişir. Şunu bil:

  • Metin dosyaları, loglar, JSON, CSV: Çok iyi sıkışır. %70-90 küçülme görülebilir.
  • SQL dump’ları: İyi sıkışır, %60-75 arası normaldir.
  • Binary executable’lar: Orta düzey, %30-50 civarı.
  • Zaten sıkıştırılmış veriler (jpg, mp4, zip, gz): Neredeyse hiç sıkışmaz, hatta bazen büyür.
# Bir dosyanın ne kadar sıkışabileceğini tahmin et
# (gerçek sıkıştırma yapmadan)
zstd --no-progress -c --fast dosya.txt | wc -c

# Bir dizinin sıkıştırılabilirliğini test et
tar -cf - /test/klasor | zstd -3 | wc -c | 
    awk -v orig=$(du -sb /test/klasor | cut -f1) 
    '{printf "Sıkıştırılmış: %.1f MB (oran: %.1f%%)n", $1/1024/1024, (1-$1/orig)*100}'

Zaten sıkıştırılmış dosyaları tekrar sıkıştırmak anlamsız, hatta zararlı. /var/www altında jpg ve png dosyaları varsa, onları tar’layıp sıkıştırmak boşa gidecek CPU süresi demek. Bu durumda ya dosyaları atlarsın ya da sıkıştırmayı devre dışı bırakırsın:

# Belirli uzantıları dışla
tar --exclude="*.jpg" --exclude="*.mp4" --exclude="*.zip" 
    -czf arsiv.tar.gz /var/www/html

Sonuç

Sıkıştırma algoritması seçimi “en iyi nedir?” sorusundan değil, “bu iş için ne gerekiyor?” sorusundan başlamalı.

Eğer bugün hala her şey için gzip kullanıyorsan, zstd’ye geçmeyi ciddi düşün. Varsayılan seviyede gzip’ten hızlı ve daha iyi sıkıştırma yapıyor. Uyumluluk sorunu yoksa, yeni projeler ve scriptlerde zstd neredeyse her zaman daha iyi bir başlangıç noktası.

xz kritik, nadiren erişilen, uzun süreli arşivler için saklansın. Haftalık veritabanı yedeklerini xz ile sıkıştırıp soğuk depolamaya gönderirken, günlük logları zstd ile işlemek çok daha verimli bir strateji.

lz4 ise özellikle programatik sıkıştırma yapıyorsan, yani bir uygulama içinden ya da pipeline’ın sıkıştırmadan çok başka işlemler yaptığı durumlarda değerini gösterir.

Son olarak: benchmark’ı kendi verinle çalıştır. Yukarıdaki script’i al, gerçek production dosyalarından birini test et. Teorik karşılaştırmalar genel eğilimi gösterir ama gerçek farkı kendi sisteminde kendi verinle görmek, doğru kararı vermenin tek güvenilir yolu.

Yorum yapın