TCP/IP Yığın Optimizasyonu: Linux’ta Ağ Performansını Artırma
Yüksek trafikli bir sunucuda ağ performansı sorunlarıyla boğuşmaya başladığında, ilk içgüdü genellikle donanım yükseltmesi yapmak olur. Oysa çoğu zaman sorun tamamen yazılım katmanında, daha doğrusu Linux çekirdeğinin TCP/IP yığın ayarlarında yatıyor. Doğru parametrelerle optimize edilmiş bir sistem, aynı donanımla çok daha iyi performans verebilir. Bu yazıda, gerçek dünya senaryolarından yola çıkarak TCP/IP yığın optimizasyonunu derinlemesine ele alacağız.
TCP/IP Yığın Optimizasyonu Neden Gerekli?
Linux çekirdeği, varsayılan TCP/IP ayarlarını oldukça muhafazakar bir şekilde yapılandırır. Bu ayarlar, genel amaçlı kullanım için makul olmakla birlikte, yüksek bant genişliği, düşük gecikme veya yüksek eşzamanlı bağlantı sayısı gerektiren ortamlar için yetersiz kalır.
Şöyle düşün: Bir e-ticaret sitesi Black Friday günü çöküyor, loglar incelendiğinde CPU ve disk kullanımının normal seviyelerde olduğu görülüyor. Sorun ne? Büyük ihtimalle TCP bağlantı kuyruğu dolup taşmış ya da soket tampon boyutları yetersiz kalmış. İşte bu noktada kernel parametrelerini anlamak ve optimize etmek kritik önem taşıyor.
Mevcut Durumu Analiz Etmek
Optimizasyona geçmeden önce mevcut durumu doğru okumak gerekiyor. Kör ayarlama yapmak bazen işleri daha da kötüleştirebilir.
Temel Ağ İstatistiklerini Okumak
# Genel ağ istatistikleri
ss -s
# Detaylı TCP bağlantı durumu
ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn
# Paket kayıplarını ve hataları görmek
netstat -s | grep -E "segments|retransmit|failed|error"
# Arayüz bazlı istatistikler
ip -s link show eth0
Bu komutların çıktısında dikkat etmen gereken birkaç önemli nokta var. ss -s çıktısında TIME_WAIT durumundaki bağlantı sayısı yüzleri geçiyorsa, soket yeniden kullanım ayarlarına bakmak gerekir. Retransmit sayısı sürekli artıyorsa tampon boyutları veya ağ kalitesi sorunlu demektir.
Kernel Parametrelerinin Mevcut Değerlerini Görmek
# Tüm ağ ile ilgili kernel parametrelerini listele
sysctl -a | grep -E "net.core|net.ipv4.tcp|net.ipv4.ip"
# Belirli parametreleri kontrol et
sysctl net.core.rmem_max
sysctl net.ipv4.tcp_rmem
sysctl net.ipv4.tcp_wmem
sysctl net.ipv4.tcp_max_syn_backlog
Bu değerleri bir yere not et. Optimizasyon sonrasında karşılaştırma yapmak için başlangıç noktasını bilmek şart.
Temel Optimizasyon Parametreleri
Soket Tampon Boyutları
TCP performansının en kritik bileşeni tampon boyutlarıdır. Yetersiz tampon, bant genişliğini tam kullanamamana neden olur. Bu özellikle yüksek gecikme (yüksek RTT) olan bağlantılarda belirgin şekilde ortaya çıkar.
Bandwidth-Delay Product (BDP) hesabı yaparak doğru tampon boyutunu belirleyebilirsin:
BDP = Bant Genişliği (bit/s) x RTT (saniye)
Örneğin 1 Gbps bağlantı ve 50ms RTT için: 1,000,000,000 x 0.05 = 50,000,000 bit = 6.25 MB
# /etc/sysctl.conf veya /etc/sysctl.d/99-network-tuning.conf dosyasına ekle
# Maksimum soket alım tamponu (bytes)
net.core.rmem_max = 134217728
# Maksimum soket gönderim tamponu (bytes)
net.core.wmem_max = 134217728
# Varsayılan soket alım tamponu
net.core.rmem_default = 31457280
# Varsayılan soket gönderim tamponu
net.core.wmem_default = 31457280
# TCP alım tamponu: minimum, varsayılan, maksimum
net.ipv4.tcp_rmem = 4096 87380 134217728
# TCP gönderim tamponu: minimum, varsayılan, maksimum
net.ipv4.tcp_wmem = 4096 65536 134217728
Bağlantı Kuyruğu ve Backlog Ayarları
Bir web sunucusuna aynı anda çok sayıda bağlantı geldiğinde, tüm bu bağlantılar hemen işlenemez. Kernel bunları bir kuyrukta tutar. Bu kuyruğun yeterince büyük olmaması, bağlantıların düşürülmesine neden olur.
# SYN kuyruğu (half-open connections)
net.ipv4.tcp_max_syn_backlog = 65536
# Tüm protokoller için maksimum bağlantı kuyruğu
net.core.somaxconn = 65535
# Ağ arayüzüne gelen paket kuyruğu
net.core.netdev_max_backlog = 65536
# TCP için maksimum orphan soket sayısı
net.ipv4.tcp_max_orphans = 262144
Bu parametreler özellikle yüksek trafikli web sunucularında, load balancer’larda ve büyük veri transferi yapan sistemlerde kritik önem taşıyor. nginx veya HAProxy gibi uygulamaların kendi backlog ayarlarını da bu değerlerle uyumlu hale getirmeyi unutma.
TIME_WAIT Problemi ve Çözümü
Yüksek trafikli sunucularda en sık karşılaşılan sorunlardan biri TIME_WAIT durumunda bekleyen bağlantıların birikmesidir. Her TCP bağlantısı kapandıktan sonra kernel, bu bağlantıyı bir süre (varsayılan 60 saniye) TIME_WAIT durumunda tutar. Bu, port tükenmesine yol açabilir.
# TIME_WAIT durumundaki bağlantıları say
ss -tan | grep TIME_WAIT | wc -l
# Detaylı görünüm
ss -tan state time-wait | head -20
Çözüm için şu parametreleri kullan:
# TIME_WAIT soketlerinin yeniden kullanımına izin ver
net.ipv4.tcp_tw_reuse = 1
# FIN_WAIT_2 timeout süresi (saniye)
net.ipv4.tcp_fin_timeout = 30
# Yerel port aralığını genişlet
net.ipv4.ip_local_port_range = 1024 65535
# TCP keepalive ayarları
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 10
Burada bir uyarı: tcp_tw_recycle parametresi eski çekirdeklerde mevcut olmakla birlikte, NAT arkasındaki istemcilerle ciddi sorunlara yol açabileceği için kullanmaktan kaçın. 4.12+ çekirdeklerde zaten kaldırılmıştır.
TCP Tıkanıklık Kontrolü ve Algoritma Seçimi
Linux çekirdeği, farklı ağ ortamları için çeşitli tıkanıklık kontrol algoritmaları sunar. Doğru algoritmayı seçmek önemli performans kazanımları sağlayabilir.
# Mevcut tıkanıklık kontrol algoritmalarını listele
sysctl net.ipv4.tcp_available_congestion_control
# Aktif algoritmayı gör
sysctl net.ipv4.tcp_congestion_control
# BBR algoritmasını yükle (kernel 4.9+)
modprobe tcp_bbr
echo "tcp_bbr" >> /etc/modules-load.d/modules.conf
BBR (Bottleneck Bandwidth and Round-trip propagation time): Google tarafından geliştirilen bu algoritma, özellikle uzun mesafeli ve yüksek bant genişliğine sahip bağlantılarda mükemmel performans gösteriyor. Veri merkezi uygulamaları için kesinlikle denenmeye değer.
CUBIC: Varsayılan algoritma, genel amaçlı kullanım için iyi performans sağlar.
HTB (Hierarchical Token Bucket): QoS gereksinimleri olan ortamlar için idealdir.
# BBR'ı aktif et
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
# Aktif olup olmadığını doğrula
sysctl net.ipv4.tcp_congestion_control
lsmod | grep bbr
Gerçek dünya testi: Bir CDN müşterisi, BBR’a geçtikten sonra transatlantik bağlantılarda throughput değerinin yaklaşık 2-3 kat arttığını raporladı. CUBIC ile 40 Mbps alınan bir bağlantıdan BBR ile 120 Mbps’ye çıkıldı.
SYN Flood Koruması
Optimizasyon yaparken güvenliği ihmal etmemek gerekiyor. SYN flood saldırıları, TCP yığınını etkili şekilde kullanabileceğin bir alandır.
# SYN cookies - SYN flood koruması
net.ipv4.tcp_syncookies = 1
# Ters yol filtrelemesi (IP spoofing koruması)
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# ICMP redirect'leri reddet
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
# Source routing'i devre dışı bırak
net.ipv4.conf.all.accept_source_route = 0
Gerçek Senaryo: E-Ticaret Sunucusu Optimizasyonu
Bir e-ticaret platformu, yoğun trafik dönemlerinde “connection reset” hataları alıyordu. Sunucu kaynaklarının dolmadığı görülmesine rağmen bağlantılar düşüyordu.
Analiz adımları:
# Düşen bağlantıları tespit et
netstat -s | grep "connections reset"
netstat -s | grep "SYNs to LISTEN"
# Soket durumunu incele
ss -s
# Çıktı: many connections in SYN_RECV state
# Kernel log'larında uyarı ara
dmesg | grep -i "syn|backlog|dropped"
Sorun tespiti: tcp_max_syn_backlog değeri 128 olarak kalıyordu ve yoğun trafik döneminde bu kuyruk dolup taşıyordu. Ayrıca TIME_WAIT bağlantıları 40.000’i geçmişti.
Uygulanan optimizasyon dosyası:
# /etc/sysctl.d/99-ecommerce-tuning.conf
# Bağlantı kuyrukları
net.ipv4.tcp_max_syn_backlog = 65536
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65536
# Tampon boyutları
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.ipv4.tcp_rmem = 4096 87380 134217728
net.ipv4.tcp_wmem = 4096 65536 134217728
# TIME_WAIT optimizasyonu
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.ip_local_port_range = 1024 65535
# SYN koruması
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_syn_retries = 3
net.ipv4.tcp_synack_retries = 3
# Keepalive
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_keepalive_probes = 5
# BBR
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
Değişiklikleri kalıcı olarak uygulamak için:
# Değişiklikleri hemen uygula
sysctl -p /etc/sysctl.d/99-ecommerce-tuning.conf
# Tüm sysctl dosyalarını yeniden yükle
sysctl --system
# Değişikliği doğrula
sysctl net.ipv4.tcp_max_syn_backlog
Sonuç: Yoğun trafik dönemlerinde bağlantı hatası sıfıra indi, sayfa yükleme süreleri ortalama %15 azaldı.
Ağ Arayüzü Seviyesinde Optimizasyon
TCP/IP yığını sadece kernel parametrelerinden ibaret değil. NIC (Network Interface Card) seviyesinde de optimizasyon yapılabilir.
# NIC ayarlarını görüntüle
ethtool eth0
# Ring buffer boyutlarını artır
ethtool -G eth0 rx 4096 tx 4096
# Mevcut ring buffer boyutlarını gör
ethtool -g eth0
# Offload özelliklerini gör
ethtool -k eth0
# TSO (TCP Segmentation Offload) aktif et
ethtool -K eth0 tso on
# GRO (Generic Receive Offload) aktif et
ethtool -K eth0 gro on
# Interrupt coalescing ayarla
ethtool -C eth0 rx-usecs 50 tx-usecs 50
Bu ayarların kalıcı olması için /etc/network/interfaces veya systemd-networkd konfigürasyonuna eklemeyi unutma. NetworkManager kullanan sistemlerde ise dispatcher script yazman gerekebilir.
İzleme ve Doğrulama
Optimizasyon yaptıktan sonra etkiyi ölçmek şart. Kör uçmak olmaz.
# TCP istatistiklerini sürekli izle
watch -n 2 'ss -s'
# Retransmit oranını izle
watch -n 5 'netstat -s | grep retransmit'
# Bant genişliği testi (iperf3 ile)
# Sunucu tarafında
iperf3 -s
# İstemci tarafında
iperf3 -c SUNUCU_IP -t 30 -P 4
# Gecikme ölçümü
ping -c 100 -i 0.2 HEDEF_IP | tail -2
Uzun vadeli izleme için sar aracından yararlanabilirsin:
# Ağ istatistiklerini kaydet
sar -n DEV 1 60
# TCP istatistikleri
sar -n TCP 1 60
# Geçmiş verileri görüntüle
sar -n DEV -f /var/log/sysstat/sa$(date +%d)
Büyük Dosya Transferi Senaryosu
Bir yedekleme sistemi, sunucular arası büyük dosya transferlerinde beklenen hızın çok altında kalıyordu. 10 Gbps bağlantıda yalnızca 2-3 Gbps hız elde ediliyordu.
# Mevcut pencere ölçekleme durumunu kontrol et
sysctl net.ipv4.tcp_window_scaling
# TCP pencere boyutunu izle
ss -tin dst HEDEF_IP
Sorun, otomatik tampon boyutlandırmanın (autotuning) devre dışı olmasıydı. Şu parametrelerle düzeltildi:
# Otomatik tampon boyutlandırma
net.ipv4.tcp_moderate_rcvbuf = 1
# Pencere ölçekleme
net.ipv4.tcp_window_scaling = 1
# Büyük transferler için tampon boyutları
net.ipv4.tcp_rmem = 4096 87380 268435456
net.ipv4.tcp_wmem = 4096 65536 268435456
net.core.rmem_max = 268435456
net.core.wmem_max = 268435456
# No-cache flag - büyük dosya transferi için
net.ipv4.tcp_low_latency = 0
Bu değişikliklerden sonra transfer hızı 8.5 Gbps’ye çıktı.
Dikkat Edilmesi Gereken Noktalar
Her optimizasyon her ortam için geçerli değil. Birkaç kritik uyarı:
- Aşırı tampon boyutu: Çok büyük tampon boyutları, bufferbloat sorununa yol açabilir. Özellikle düşük bant genişlikli bağlantılarda gecikme artışına neden olur.
- tcp_tw_recycle kullanımı: Eski belgelerde bu parametreyi görürsen, NAT ortamlarında ciddi bağlantı sorunları yarattığı için kesinlikle kullanma.
- Test ortamı önce: Üretim sunucusuna direkt uygulamadan önce aynı workload’ı simüle eden bir test ortamında dene.
- Değişiklikleri kademeli yap: Tüm parametreleri bir anda değiştirmek sorun çıkarsa neyin sorun yarattığını bulmayı zorlaştırır.
- Uygulama katmanı: Kernel optimizasyonu tek başına yeterli değil. Nginx, Apache veya uygulama sunucunun kendi bağlantı ve tampon ayarları da optimize edilmeli.
Sonuç
TCP/IP yığın optimizasyonu, doğru yapıldığında donanım maliyeti olmadan ciddi performans artışları sağlayan güçlü bir araç. Ancak sihirli bir konfigürasyon dosyası kopyala-yapıştır yaklaşımıyla iş yapmıyor. Her ortamın kendine özgü dinamikleri var.
Doğru yaklaşım şu sırayı takip ediyor: Önce mevcut durumu ölç, darboğazı tespit et, hedeflenen iyileştirmeyi belirle, parametreleri kademeli olarak değiştir, sonuçları ölç ve karşılaştır. Bu döngüyü takip ettiğinde hem daha iyi sonuçlar alırsın hem de bir şeyler ters gittiğinde nerede sorun olduğunu hızla bulabilirsin.
BBR algoritması, büyütülmüş SYN backlog’u ve optimize edilmiş tampon boyutları, çoğu yüksek trafikli senaryoda ciddi fark yaratıyor. Başlangıç noktası olarak bu üç alan üzerine yoğunlaşmanı tavsiye ederim. Sonrasında daha spesifik ihtiyaçlara göre derinleştirmeye devam edebilirsin.
