Arşivleme İşlemlerinde RAM Diski Kullanma: tmpfs Üzerinde Hızlı Geçici Sıkıştırma

Yıllar önce bir üretim ortamında, büyük log dosyalarını arşivlerken disk I/O’sunun sistemi neredeyse felç ettiğine bizzat tanıklık ettim. Sunucu diğer işlere de hizmet veriyordu ve tar + gzip kombinasyonu saatlerce disk kaynaklarını tüketiyordu. O günden bu yana geçici sıkıştırma işlemleri için RAM diskini bir standart haline getirdim. Eğer siz de benzer sorunlarla boğuşuyorsanız, bu yazı tam size göre.

tmpfs Nedir ve Neden Arşivleme İçin Kullanılır?

tmpfs, Linux çekirdeğinin sunduğu bellekte yaşayan bir dosya sistemidir. Gerçek bir disk bölümü değildir; RAM üzerinde çalışır ve sistem yeniden başlatıldığında içeriği tamamen silinir. İsmi “temporary filesystem” kelimelerinden gelir ve tam olarak bu amaca hizmet eder: geçici, hızlı, uçucu depolama.

Arşivleme senaryolarında tmpfs kullanmanın temel mantığı şudur: sıkıştırma işlemi CPU yoğun bir operasyondur, ancak kaynak ve hedef dosyalar aynı fiziksel diske yazılıyorsa disk başlığı sürekli ileri geri hareket eder ve I/O beklemesi oluşur. Kaynak dosyaları disk üzerinde tutup, ara işlemleri RAM’de yaparsanız bu darboğazı ortadan kaldırmış olursunuz.

Bir de şu açıdan bakın: NVMe SSD’lerin bile sıralı okuma hızı ortalama 3-5 GB/sn civarındadır. DDR4 RAM ise 25-50 GB/sn bant genişliği sunar. Aradaki fark küçük değil.

tmpfs’in Hazır Olup Olmadığını Kontrol Etme

Çoğu modern Linux dağıtımında /tmp ve /dev/shm zaten tmpfs olarak bağlanmış gelir. Kontrol etmek için:

mount | grep tmpfs

Çıktıda şuna benzer satırlar görürsünüz:

tmpfs on /run type tmpfs (rw,nosuid,nodev,mode=755,size=100%)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
tmpfs on /tmp type tmpfs (rw,nosuid,nodev)

/dev/shm genellikle toplam RAM’in yarısı kadar boyutlandırılmıştır. Mevcut boyutu ve doluluk oranını görmek için:

df -h /dev/shm /tmp

Eğer sisteminizde /tmp tmpfs üzerinde değilse ya da boyut yetersizse, özel bir tmpfs bağlama noktası oluşturabilirsiniz.

Özel tmpfs Bağlama Noktası Oluşturma

Büyük arşivleme işlemleri için ihtiyaç duyduğunuz boyutu kendiniz belirlemek en sağlıklısı. Diyelim ki 8 GB RAM’iniz var ve arşivleme için 4 GB’lık geçici alan istiyorsunuz:

sudo mkdir -p /mnt/ramdisk
sudo mount -t tmpfs -o size=4G,mode=1777 tmpfs /mnt/ramdisk

Bağlama işlemini doğrulamak için:

df -h /mnt/ramdisk
# Çıktı:
# Filesystem      Size  Used Avail Use% Mounted on
# tmpfs           4.0G     0  4.0G   0% /mnt/ramdisk

Bu bağlama geçicidir, sistem yeniden başlatılınca kaybolur. Kalıcı hale getirmek isterseniz /etc/fstab dosyasına ekleyebilirsiniz, ancak arşivleme senaryolarında bunu genellikle önermiyorum. Çünkü sistem açılışında 4 GB RAM’i rezerve etmek her zaman mantıklı olmayabilir. Betik içinde bağlayıp işiniz bitince unmount etmek daha temiz bir yaklaşım.

Temel Arşivleme Senaryosu: Tar + Gzip

En klasik senaryo: büyük bir uygulama log dizinini arşivleyip sıkıştırmak ve ardından uzak bir yere transfer etmek.

# tmpfs üzerinde çalışma dizini oluştur
mkdir -p /mnt/ramdisk/archive_work

# Log dosyalarını tmpfs'e sıkıştırarak arşivle
tar -czf /mnt/ramdisk/archive_work/app_logs_$(date +%Y%m%d).tar.gz 
    /var/log/myapp/

# Arşivi kalıcı hedefe taşı
mv /mnt/ramdisk/archive_work/app_logs_$(date +%Y%m%d).tar.gz 
    /data/archives/

# Geçici alanı temizle
rm -rf /mnt/ramdisk/archive_work

Burada kilit nokta şu: arşiv dosyası önce RAM’de oluşturuluyor, tamamlanınca kalıcı depolamaya tek seferlik bir yazma işlemiyle aktarılıyor. Bu sayede hem log dizinini okuma hem de arşiv dosyasını yazma işlemleri birbirini bloke etmiyor.

Paralel Sıkıştırma ile Kombine Kullanım

Modern sunucularda genellikle birden fazla CPU çekirdeği var. pigz (parallel gzip) veya pbzip2 gibi araçlarla bu çekirdekleri tam kapasite kullanabilirsiniz. tmpfs ile birleşince sonuç oldukça etkileyici olabiliyor:

# pigz kurulu değilse
sudo apt-get install pigz    # Debian/Ubuntu
sudo yum install pigz        # RHEL/CentOS

# Tüm çekirdekleri kullanarak tmpfs'e arşivle
tar -I pigz -cf /mnt/ramdisk/bigdata_$(date +%Y%m%d_%H%M).tar.gz 
    /var/data/bigdataset/

# İşlem süresini ölçmek isterseniz
time tar -I pigz -cf /mnt/ramdisk/bigdata_$(date +%Y%m%d_%H%M).tar.gz 
    /var/data/bigdataset/

-I pigz parametresi tar’a sıkıştırma için harici komut olarak pigz kullanmasını söyler. Pigz varsayılan olarak mevcut tüm CPU çekirdeklerini kullanır. Belirli bir çekirdek sayısı belirtmek isterseniz:

# Sadece 4 çekirdek kullan (diğer servisler için yer bırak)
tar -I "pigz -p 4" -cf /mnt/ramdisk/output.tar.gz /kaynak/dizin/

Büyük Veri Setlerini Parçalara Bölerek İşleme

Bazen arşivlenecek veri seti tmpfs kapasitesinden büyük olabilir. Bu durumda split kombinasyonunu kullanabiliriz:

#!/bin/bash
# split_archive.sh - Büyük arşivleri parçalı işle

KAYNAK="/data/büyük_dataset"
HEDEF="/backup/archives"
TMPDIR="/mnt/ramdisk/split_work"
TARIH=$(date +%Y%m%d_%H%M%S)

mkdir -p "$TMPDIR"
mkdir -p "$HEDEF/$TARIH"

# 2 GB'lık parçalar halinde arşivle
tar -czf - "$KAYNAK" | 
    split -b 2G - "$TMPDIR/parca_"

# Parçaları hedefe taşı
for parca in "$TMPDIR"/parca_*; do
    mv "$parca" "$HEDEF/$TARIH/"
    echo "Taşındı: $(basename $parca)"
done

# Geçici dosyaları temizle
rm -rf "$TMPDIR"

echo "Arşivleme tamamlandı: $HEDEF/$TARIH"

Burada önemli bir detay var: pipe (|) kullanarak tar çıktısını doğrudan split’e yönlendiriyoruz. Bu sayede tam arşiv hiçbir zaman diske yazılmıyor, parçalar tmpfs’te geçici olarak bekleyip oradan hedefe aktarılıyor.

Çoklu Kaynak Arşivleme ve İlerleme Takibi

Üretim ortamlarında hangi dosyanın işlendiğini görmek önemlidir. pv (pipe viewer) aracıyla ilerlemeyi izleyebilirsiniz:

# pv kurulumu
sudo apt-get install pv

# İlerleme göstergesiyle tmpfs'e arşivle
tar -czf - /var/log/nginx/ | 
    pv -s $(du -sb /var/log/nginx/ | cut -f1) | 
    cat > /mnt/ramdisk/nginx_logs_$(date +%Y%m%d).tar.gz

echo "Arşiv boyutu: $(du -sh /mnt/ramdisk/nginx_logs_*.tar.gz)"

pv -s parametresi toplam veri boyutunu alarak yüzde cinsinden ilerleme gösterir. -s $(du -sb ...) kısmı kaynak boyutunu byte cinsinden hesaplar.

Gerçek Dünya Senaryosu: Veritabanı Yedekleme Hızlandırma

Bu senaryoyu özellikle paylaşmak istiyorum çünkü pratikte en çok fark yarattığını gördüğüm yer burası. PostgreSQL dump alırken diski yorduğunuz fark ederseniz:

#!/bin/bash
# pg_backup_tmpfs.sh

DB_ADI="production_db"
DB_KULLANICI="postgres"
TMPDIR="/mnt/ramdisk/pg_backup"
HEDEF="/backup/postgres"
TARIH=$(date +%Y%m%d_%H%M)

# Gerekli dizinleri oluştur
mkdir -p "$TMPDIR"
mkdir -p "$HEDEF"

echo "[$TARIH] Yedekleme başlıyor..."

# PostgreSQL dump'ı tmpfs'e al, sıkıştır
pg_dump -U "$DB_KULLANICI" -Fc "$DB_ADI" | 
    pigz -6 > "$TMPDIR/${DB_ADI}_${TARIH}.dump.gz"

DUMP_BOYUT=$(du -sh "$TMPDIR/${DB_ADI}_${TARIH}.dump.gz" | cut -f1)
echo "Dump boyutu: $DUMP_BOYUT"

# Checksum oluştur
sha256sum "$TMPDIR/${DB_ADI}_${TARIH}.dump.gz" > 
    "$TMPDIR/${DB_ADI}_${TARIH}.dump.gz.sha256"

# Kalıcı depolamaya taşı
mv "$TMPDIR/${DB_ADI}_${TARIH}.dump.gz" "$HEDEF/"
mv "$TMPDIR/${DB_ADI}_${TARIH}.dump.gz.sha256" "$HEDEF/"

echo "Yedek taşındı: $HEDEF/${DB_ADI}_${TARIH}.dump.gz"

# Temizlik
rm -rf "$TMPDIR"

# 7 günden eski yedekleri sil
find "$HEDEF" -name "${DB_ADI}_*.dump.gz" -mtime +7 -delete

echo "İşlem tamamlandı."

-Fc parametresi PostgreSQL’in kendi özel formatını kullanır, bu format zaten sıkıştırma içeriyor ancak pigz ile ek sıkıştırma yapabiliriz. -6 ise sıkıştırma seviyesidir (1-9 arası, 6 denge noktasıdır).

tmpfs Boyut Sınırını Aşmama Stratejileri

En sık karşılaşılan sorun: tmpfs dolunca arşivleme işleminin “No space left on device” hatasıyla çökmesi. Bu can sıkıcı durumu önlemek için birkaç strateji:

Boyut Kontrolü ile Güvenli Başlangıç:

#!/bin/bash
# Arşivleme öncesi boyut kontrolü

KAYNAK="/var/data/büyük_dizin"
TMPFS="/mnt/ramdisk"
GUVENLIK_FAKTORU=1.3  # %30 güvenlik marjı

# Kaynak boyutunu hesapla (sıkıştırma oranı tahmin: %40 azalma)
KAYNAK_BOYUT=$(du -sb "$KAYNAK" | cut -f1)
TAHMINI_ARSIV=$(echo "$KAYNAK_BOYUT * 0.6 * $GUVENLIK_FAKTORU" | bc | cut -d. -f1)

# tmpfs'te mevcut boş alan
BOSLUK=$(df -B1 "$TMPFS" | awk 'NR==2 {print $4}')

echo "Kaynak boyutu: $(numfmt --to=iec $KAYNAK_BOYUT)"
echo "Tahmini arşiv: $(numfmt --to=iec $TAHMINI_ARSIV)"
echo "tmpfs boşluğu: $(numfmt --to=iec $BOSLUK)"

if [ "$TAHMINI_ARSIV" -gt "$BOSLUK" ]; then
    echo "HATA: Yetersiz tmpfs alanı. İşlem iptal edildi."
    exit 1
fi

echo "Alan yeterli. Arşivleme başlıyor..."

zstd ile Hız ve Sıkıştırma Dengesi

Son yıllarda zstd (Zstandard) gerçekten dikkat çekici performans rakamları sunuyor. Gzip’e göre çok daha hızlı sıkıştırıp açarken benzer veya daha iyi sıkıştırma oranları elde ediliyor. tmpfs gibi hız odaklı bir senaryoda bu fark önemli:

# zstd kurulumu
sudo apt-get install zstd

# tar ile zstd kullanımı
tar -I zstd -cf /mnt/ramdisk/arşiv.tar.zst /kaynak/dizin/

# Hız odaklı, düşük sıkıştırma (1. seviye, maksimum hız)
tar -I "zstd -1" -cf /mnt/ramdisk/hizli.tar.zst /kaynak/dizin/

# Denge noktası (varsayılan seviye 3)
tar -I "zstd -3 -T0" -cf /mnt/ramdisk/dengeli.tar.zst /kaynak/dizin/
# -T0: Tüm CPU çekirdeklerini kullan

# Açma işlemi
tar -I zstd -xf /mnt/ramdisk/arşiv.tar.zst -C /hedef/dizin/

-T0 parametresi zstd’ye mevcut tüm işlemci çekirdeklerini kullanmasını söyler. Pigz’e benzer şekilde paralel sıkıştırma yapabilir.

Pratik karşılaştırma yapmak isterseniz:

# Aynı kaynağı farklı yöntemlerle arşivle, süreyi ölç
KAYNAK="/var/log"

echo "--- gzip ---"
time tar -czf /mnt/ramdisk/test_gzip.tar.gz "$KAYNAK" 2>/dev/null

echo "--- pigz ---"
time tar -I pigz -cf /mnt/ramdisk/test_pigz.tar.gz "$KAYNAK" 2>/dev/null

echo "--- zstd ---"
time tar -I "zstd -T0" -cf /mnt/ramdisk/test_zstd.tar.zst "$KAYNAK" 2>/dev/null

# Boyutları karşılaştır
ls -lh /mnt/ramdisk/test_*

# Temizlik
rm /mnt/ramdisk/test_*

tmpfs Kullanımını İzleme ve Uyarı Sistemi

Otomatik arşivleme betiklerinde tmpfs doluluk oranını izlemek önemli. Basit bir izleme fonksiyonu:

#!/bin/bash
# tmpfs_monitor.sh - Arşivleme sırasında RAM disk kullanımını izle

TMPFS="/mnt/ramdisk"
UYARI_ESIGI=80  # %80 dolunca uyar

izle_tmpfs() {
    while true; do
        KULLANIM=$(df "$TMPFS" | awk 'NR==2 {gsub(/%/,"",$5); print $5}')
        
        if [ "$KULLANIM" -ge "$UYARI_ESIGI" ]; then
            echo "[UYARI] $(date): tmpfs kullanımı %$KULLANIM seviyesinde!" >&2
            # Opsiyonel: e-posta veya Slack bildirimi gönderilebilir
        fi
        
        sleep 5
    done
}

# Arkaplan işlemi olarak başlat
izle_tmpfs &
MONITOR_PID=$!

echo "İzleme başladı (PID: $MONITOR_PID)"

# Asıl arşivleme işlemi buraya gelir
tar -I "zstd -T0" -cf "$TMPFS/büyük_arşiv.tar.zst" /data/büyük_dizin/

# İzlemeyi durdur
kill $MONITOR_PID 2>/dev/null
echo "Arşivleme ve izleme tamamlandı."

Dikkat Edilmesi Gereken Noktalar

Tmpfs üzerinde arşivleme yaparken birkaç konuyu aklınızda tutun:

  • Bellek baskısı: Sistem RAM’i başka işlemler için gerektiğinde Linux, tmpfs içeriğini swap’a taşıyabilir. Swap üzerinde tmpfs, amacını yitirir. Swap kullanımını vmstat 1 ile izleyin.
  • Güç kesintisi: tmpfs’teki veriler güç gidince kaybolur. Arşivleme tamamlanmadan sistemi kapatmayın ve arşiv kalıcı hedefe taşınmadan başarı sayılmasın.
  • OOM Killer: Sistem belleği tükenirse OOM Killer devreye girer ve arşivleme işleminizi öldürebilir. dmesg | grep oom ile bu durumu sonradan tespit edebilirsiniz.
  • Boyut dinamiği: tmpfs boyutu sabit değildir. size=4G ile bağlasanız bile gerçekte 4 GB RAM hemen ayrılmaz; kullandıkça artarak bu sınıra ulaşır. Bu davranış avantajlıdır ama planlamanızı buna göre yapın.
  • Dosya izinleri: /dev/shm genellikle herkese açık yazılabilir durumdadır. Hassas veri arşivliyorsanız özel bir bağlama noktası oluşturun ve izinleri kısıtlayın.

Sonuç

tmpfs üzerinde arşivleme, doğru uygulandığında disk I/O darboğazlarını önemli ölçüde azaltır ve özellikle HDD tabanlı sistemlerde dramatik hız artışları sağlar. SSD sistemlerde bile, aynı diske hem okuma hem yazma yapılmasının önüne geçmek açısından değerini korur.

Pratikte en çok fayda gördüğüm senaryolar şunlar oldu: büyük veritabanı dumpları, yoğun log arşivleme işlemleri ve ağ transferi öncesi sıkıştırma aşamaları. Bu üç senaryoda tmpfs’i benimsedikten sonra geri dönmek istemedim.

Başlangıç için şu sırayı öneririm: önce mevcut tmpfs boyutunuzu kontrol edin, bir test arşivi yapın, süreyi ölçün ve kendi altyapınızdaki farkı bizzat görün. Sayılar sizi ikna edecektir.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir