Veri merkezlerinde sunucularımızı 25GbE veya 100GbE (Mellanox ConnectX, Intel E810 vb.) ağ kartlarıyla donatıp Arista veya Cisco TOR (Top-of-Rack) anahtarlara bağladığımızda, fiziksel katmanda devasa bir bant genişliği elde ederiz. Ancak Linux çekirdeğinin varsayılan ağ yığını (Network Stack) parametreleri, hala 1GbE bağlantılar ve düşük bellekli sistemlerle uyumlu olacak şekilde muhafazakar değerlerle gelir.
25GbE bir hatta standart 1500 byte MTU ile saniyede yaklaşık 2.1 milyon paket (Mpps) akar. Eğer NIC Ring Buffer, SoftIRQ kuyrukları, CPU NUMA hizalaması ve TCP tampon bellekleri (sysctl) bu hıza göre ayarlanmazsa; ağ kartınız %30 yükteyken bile paket düşürmeye (rx_missed_errors, dropped) ve depolama/sanallaştırma trafiğinde ani gecikme sıçramaları (latency spikes) yaratmaya başlar.
Bugünkü yazımızda, paketlerin fiber kablodan çıkıp uygulama veya sanal makine katmanına ulaşana kadar geçtiği tüm darboğazları adım adım optimize ediyoruz.
1. Donanım Katmanı: NIC Ring Buffer ve Birleştirme (Coalescing) Ayarları
Ağ kartına gelen paketler, Linux çekirdeği tarafından işlenmeden önce NIC üzerindeki Ring Buffer (FIFO kuyruğu) alanında bekletilir. Çoğu kurumsal kart maksimum 4096 veya 8192 descriptor desteklerken, varsayılan olarak 512 veya 1024 ile gelir. Yoğun bir Ceph recovery veya vMotion/Live Migration anında bu küçük tampon mikrosaniyeler içinde taşar.
Adım 1: Mevcut Ring Buffer kapasitesini kontrol edin ve maksimuma çıkarın
# Maksimum desteklenen (Pre-set maximums) ve aktif (Current hardware settings) değerleri görün
ethtool -g eno1
Örnek çıktı:
Pre-set maximums:
RX: 8192
TX: 8192
Current hardware settings:
RX: 1024
TX: 1024
Tamponu maksimuma çekmek için:
# RX ve TX Ring Buffer boyutunu 4096 (veya kartın desteklediği 8192) değerine yükseltin
sudo ethtool -G eno1 rx 4096 tx 4096
Adım 2: Donanım Seviyesi Paket Düşmelerini Yakalamak
Standart ip -s link çıktısı her zaman kartın içindeki FIFO taşmalarını göstermez. Gerçek donanım düşmelerini görmek için:
ethtool -S eno1 | grep -iE 'drop|miss|err|fifo|over'
- rx_missed_errors / rx_fifo_errors artıyorsa: NIC paketi almış ancak CPU (SoftIRQ) zamanında çekemediği için Ring Buffer taşmıştır. Ring Buffer büyütülmeli ve CPU IRQ dağılımı kontrol edilmelidir.
2. CPU, NUMA ve Kesme (IRQ / RSS) Optimizasyonu
Çok soketli (Dual-Socket) kurumsal sunucularda (örneğin HP DL380 Gen10/Gen11) PCIe yuvaları doğrudan belirli bir CPU soketine (NUMA Node 0 veya Node 1) bağlıdır. Ağ kartınız NUMA Node 1 üzerindeki PCIe hattındaysa ancak ağ kesmelerini (ksoftirqd) NUMA Node 0 üzerindeki çekirdekler işliyorsa, her paket işlemci soketleri arasındaki UPI/Infinity Fabric hattından geçmek zorunda kalır ve gecikme katlanır.
Ağ Kartının Hangi NUMA Düğümünde Olduğunu Bulmak:
# Ağ kartının bağlı olduğu yerel NUMA düğümünü ve CPU listesini öğrenin
cat /sys/class/net/eno1/device/numa_node
cat /sys/class/net/eno1/device/local_cpulist
Çoklu Kuyruk (RSS – Receive Side Scaling) Sayısını Doğrulamak:
Modern NIC’ler gelen trafiği birden fazla CPU çekirdeğine paralel dağıtmak için RSS kuyrukları kullanır:
# Aktif kanal (Combined queue) sayısını görüntüleyin ve optimize edin
ethtool -l eno1
sudo ethtool -L eno1 combined 16
Pratik Kural: 25GbE/100GbE kartlarda yüksek hızda tekil akışlar yerine binlerce paralel bağlantı varsa, irqbalance servisinin kesmeleri rastgele NUMA düğümlerine dağıtmasını önlemek için üreticinin set_irq_affinity.sh betiğiyle IRQ’ları sadece kartın bağlı olduğu yerel NUMA düğümündeki çekirdeklere sabitleyin (pinning).
3. Çekirdek Ağ Yığını (sysctl.conf) İnce Ayarları
Linux çekirdeğinin NAPI (New API) yoklama mekanizması ve TCP tamponları 10GbE+ hızlar için genişletilmelidir. /etc/sysctl.d/99-vmninja-network.conf dosyasını oluşturup aşağıdaki üretim ortamı (production-grade) parametrelerini uygulayabilirsiniz:
# --- 1. NAPI & SoftIRQ Kuyruk Kapasitesi ---
# Ağ kartından çekirdeğe alınan paketlerin CPU kuyruğundaki maksimum limiti (Varsayılan: 1000)
net.core.netdev_max_backlog = 65536
# Tek bir NAPI yoklama döngüsünde (polling cycle) işlenecek maksimum paket sayısı (Varsayılan: 300 / 600 microseconds)
net.core.netdev_budget = 600
net.core.netdev_budget_usecs = 8000
# --- 2. Soket Tampon Bellek Limitleri (25GbE / 100GbE BDP Uyumu) ---
# Maksimum Okuma (RMEM) ve Yazma (WMEM) soket tamponlarını 64MB'a kadar esnetin
net.core.rmem_max = 67108864
net.core.wmem_max = 67108864
net.core.rmem_default = 33554432
net.core.wmem_default = 33554432
net.core.optmem_max = 4194304
# TCP Otomatik Ayarlama (Autotuning): min, default, max (Byte cinsinden -> Max 64MB)
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864
# --- 3. Bağlantı Kuyrukları ve Zamanlayıcılar ---
# SYN ve Accept kuyruklarını yüksek eşzamanlı (concurrency) trafiğe göre büyütün
net.core.somaxconn = 32768
net.ipv4.tcp_max_syn_backlog = 32768
# Boşta kalan bağlantıların hızını düşüren yavaş başlangıç (Slow Start Restart) özelliğini kapatın (Ceph/iSCSI/NVMe-TCP için kritik!)
net.ipv4.tcp_slow_start_after_idle = 0
# MTU Probing: Ağda Jumbo Frame (MTU 9000) uyumsuzluğu varsa Kara Delik (Blackhole) oluşmasını önler
net.ipv4.tcp_mtu_probing = 1
# --- 4. Modern Tıkanıklık Kontrolü: TCP BBR + fq ---
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
Ayarları canlı sisteme yüklemek için:
sudo sysctl --system
Neden tcp_slow_start_after_idle = 0 Çok Kritik?
Depolama ağlarında (Ceph, NVMe/TCP, iSCSI) veya veritabanı replikasyonlarında bağlantı sürekli açık kalır (persistent connection) ancak trafik kesikli (bursty) akar. Varsayılan Linux ayarında (1), bağlantı birkaç saniye boş kaldığında TCP pencere boyutu (cwnd) sıfırlanır ve bir sonraki I/O dalgasında hat tekrar yavaş başlangıç (slow start) moduna girer. Bu parametreyi 0 yapmak mikrosaniyelik I/O gecikmelerini dramatik biçimde düşürür.
4. TCP BBR vs. CUBIC: Ne Zaman Hangisi?
- CUBIC (Varsayılan): Paket kaybını (packet loss) ağ tıkanıklığının tek işareti kabul eder. En ufak bir paket kaybında (örneğin switch mikro-patlaması / microburst) gönderim hızını anında %30 oranında keser.
- BBR (Bottleneck Bandwidth and Round-trip propagation time): Paket kaybına değil, hattın gerçek bant genişliğine ve RTT (gecikme) süresine odaklanır. Özellikle veri merkezleri arası (Cross-DC replikasyon, DR senaryoları, WAN/Metro Ethernet) ve yüksek hızlı (25G/100G) hatlarda CUBIC’e göre çok daha kararlı ve yüksek吞吐量 (throughput) sağlar.
- Not: BBR’nin tam verimle çalışması için paket zamanlamasını (pacing) yöneten fq (Fair Queue) disipliniyle birlikte kullanılması gerekir.
5. Jumbo Frames (MTU 9000) ve Sanallaştırma (vhost_net / Multiqueue)
Depolama (SAN/NAS/Ceph) ve vMotion/Migration VLAN’larında MTU 9000 (Jumbo Frames) kullanmak, aynı miktarda veriyi 6 kat daha az paket başlığı (header) ve CPU kesmesiyle taşımanızı sağlar.
Ancak Jumbo Frame geçişinde altın kural uçtan uca tutarlılıktır:
- Sanal makine arayüzü (
eth0/ens18) - Hipervizör köprüsü (
vmbr0/vSwitch/OVS) - Fiziksel Bond ve NIC arayüzleri (
bond0/eno1) - Fiziksel Switch portları (Arista/Cisco üzerinde
mtu 9216)
Doğrulama (Parçalanmadan / Fragmentation olmadan 8972 byte + 28 byte ICMP/IP header = 9000 byte testi):
ping -M do -s 8972 -c 4 10.100.20.15
Eğer Frag needed and DF set hatası alıyorsanız, aradaki L2/L3 katmanlarından birinde MTU hala 1500 kalmıştır.
KVM / Proxmox VE Sanal Ağ Kartı (virtio-net) İnce Ayarı:
Sanal makinenin kendisi de yüksek ağ trafiği (örneğin sanal Load Balancer, WAF, Kubernetes Worker veya DB düğümü) işliyorsa, tek bir virtio-net kuyruğu tek bir vCPU çekirdeğini %100 doldurarak darboğaz yaratır. Sanal makinenin ağ kartı ayarlarında Multiqueue değerini sanal makinenin vCPU sayısına (veya maksimum 8/16’ya) eşitleyin.