Linux'u saniyede 1.2 milyon JSON isteğini karşılayacak şekilde optimize etme

HTTP isteklerini işlemek için maksimum performansı elde etmek amacıyla Linux ortamının ayarlanmasına ilişkin ayrıntılı bir kılavuz yayımlandı. Önerilen yöntemler, Amazon EC2 ortamındaki (4 vCPU) libreactor kitaplığına dayalı JSON işlemcisinin performansını, Amazon Linux 224'nin standart ayarlarıyla saniyede 2 bin API isteğinden, çekirdek 4.14 ile 1.2 milyon isteğe yükseltmeyi mümkün kıldı. optimizasyondan sonra ikinci sırada (%436 artış) ve ayrıca isteklerin işlenmesindeki gecikmelerde %79 oranında azalmaya yol açtı. Önerilen yöntemler libreactor'a özel değildir ve nginx, Actix, Netty ve Node.js dahil olmak üzere diğer http sunucularını kullanırken çalışır (testlerde libreactor kullanıldı çünkü ona dayalı çözüm daha iyi performans gösterdi).

Linux'u saniyede 1.2 milyon JSON isteğini karşılayacak şekilde optimize etme

Temel optimizasyonlar:

  • Libreactor kodunu optimize etme. Techempower kitindeki R18 seçeneği temel olarak kullanıldı; bu, kullanılan CPU çekirdeği sayısını sınırlamak için kodun kaldırılmasıyla geliştirildi (optimizasyon, işi% 25-27 oranında hızlandırmaya izin verdi), GCC'de "-O3" seçenekleriyle bir araya getirildi (%5-10 artış) ve "-march-native" (%5-10), okuma/yazma çağrılarının recv/send ile değiştirilmesi (%5-10) ve pthreads kullanıldığında ek yükün azaltılması (%2-3) . Kod optimizasyonundan sonraki genel performans artışı %55 oldu ve verim 224 bin istek/s'den 347 bin istek/s'ye çıktı.
  • Spekülatif yürütme güvenlik açıklarına karşı korumayı devre dışı bırakın. Çekirdek yüklenirken "nospectre_v1 nospectre_v2 pti=off mds=off tsx_async_abort=off" parametrelerinin kullanılması performansın %28 oranında artmasına izin verdi ve verim 347k req/s'den 446k req/s'ye yükseldi. Ayrı olarak, "nospectre_v1" (Spectre v1 + SWAPGS'ye karşı koruma) parametresindeki artış %1-2, "nospectre_v2" (Spectre v2'ye karşı koruma) - %15-20, "pti=off" (Spectre v3/Meltdown) idi. - %6, "mds=off tsx_async_abort=off" (MDS/Zombieload ve TSX Eşzamansız Durdurma) - %6. L1TF/Foreshadow (l1tf=flush), iTLB çoklu isabet, Spekülatif Mağaza Atlaması ve SRBDS saldırılarına karşı koruma ayarları değişmeden bırakıldı; bu durum, test edilen yapılandırmayla kesişmedikleri için performansı etkilemedi (örneğin, KVM'ye özel, iç içe geçmiş) sanallaştırma ve diğer CPU modelleri).
  • Docker kapsayıcısını başlatırken "auditctl -a asla,task" komutunu kullanarak ve "--security-opt seccomp=unconfined" seçeneğini belirterek denetim ve sistem çağrısı engelleme mekanizmalarını devre dışı bırakma. Genel performans artışı %11 oldu ve verim 446 bin talep/sn'den 495 bin talep/sn'ye yükseldi.
  • İlgili çekirdek modüllerini boşaltarak iptables/netfilter'ı devre dışı bırakma. Belirli bir sunucu çözümünde kullanılmayan güvenlik duvarını devre dışı bırakma fikri, nf_hook_slow işlevinin yürütülmesinin %18 oranında zaman aldığına karar verilen profil oluşturma sonuçlarıyla ortaya çıktı. Nftables'ın iptables'a göre daha verimli çalıştığı belirtiliyor ancak Amazon Linux iptables kullanmaya devam ediyor. İptables devre dışı bırakıldıktan sonra performans artışı %22 oldu ve verim 495 bin talep/s'den 603 bin talep/s'ye yükseldi.
  • İşlemci önbelleği kullanımının verimliliğini artırmak için farklı CPU çekirdekleri arasında işleyicilerin geçişi azaltıldı. Optimizasyon, hem libreactor işlemlerinin CPU çekirdeklerine bağlanması (CPU Sabitleme) hem de çekirdek ağ işleyicilerinin sabitlenmesi (Alma Tarafı Ölçeklendirmesi) düzeyinde gerçekleştirildi. Örneğin, irqbalance devre dışı bırakıldı ve CPU'ya kuyruk benzeşimi /proc/irq/$IRQ/smp_affinity_list'te açıkça ayarlandı. Libreactor işlemini ve gelen paketlerin ağ kuyruğunu işlemek üzere aynı CPU çekirdeğini kullanmak için, soket oluşturulurken SO_ATTACH_REUSEPORT_CBPF bayrağı ayarlanarak bağlanan özel bir BPF işleyicisi kullanılır. Giden paketlerin sıralarını CPU'ya bağlamak için /sys/class/net/eth0/queues/tx- ayarları değiştirildi /xps_cpus. Genel performans artışı %38 oldu ve verim 603 bin talep/sn'den 834 bin talep/sn'ye yükseldi.
  • Kesme yönetiminin ve yoklama kullanımının optimizasyonu. ENA sürücüsünde adaptive-rx modunun etkinleştirilmesi ve sysctl net.core.busy_read'in değiştirilmesi performansı %28 artırdı (iş hacmi 834k req/s'den 1.06M req/s'ye yükseldi ve gecikme 361μs'den 292μs'ye düştü).
  • Ağ yığınında gereksiz engellemeye yol açan sistem hizmetlerinin devre dışı bırakılması. Dhclient'in devre dışı bırakılması ve IP adresinin manuel olarak ayarlanması, %6 performans artışıyla sonuçlandı ve verim 1.06M istek/s'den 1.12M istek/s'ye yükseldi. Dhclient'in performansı etkilemesinin nedeni, ham soket kullanılarak trafik analizi yapılmasıdır.
  • Döndürme Kilidi ile Mücadele. Ağ yığınını sysctl “net.core.default_qdisc=noqueue” ve “tc qdisc replacement dev eth0 root mq” aracılığıyla “noqueue” moduna geçirmek %2 performans artışı sağladı ve verim 1.12M req/s'den 1.15M'ye yükseldi istek/s.
  • GRO'yu (Genel Alma Aktarımı) "ethtool -K eth0 gro off" komutuyla devre dışı bırakmak ve kübik tıkanıklık kontrol algoritmasını sysctl "net.ipv4.tcp_congestion_control=reno" kullanarak reno ile değiştirmek gibi son küçük optimizasyonlar. Genel verimlilik artışı %4 oldu. Verim 1.15 milyon talep/sn'den 1.2 milyon talep/sn'ye yükseldi.

Makalede işe yarayan optimizasyonların yanı sıra beklenen performans artışına yol açmayan yöntemler de tartışılıyor. Örneğin, aşağıdakilerin etkisiz olduğu ortaya çıktı:

  • Libreactor'ı ayrı olarak çalıştırmak, performans açısından onu bir kapta çalıştırmaktan farklı değildi. Writev'yi send ile değiştirmek, epoll_wait'te maxevent'leri artırmak ve GCC sürümleri ve bayraklarıyla denemeler yapmanın hiçbir etkisi olmadı (etki yalnızca "-O3" ve "-march-native" bayrakları için farkedildi).
  • SCHED_FIFO ve SCHED_RR zamanlayıcılarını kullanarak Linux çekirdeğini 4.19 ve 5.4 sürümlerine yükseltmek, sysctl kernel.sched_min_granarity_ns, kernel.sched_wakeup_granarity_ns, Transparent_hugepages=never, skew_tick=1 ve Clocksource=tsc'yi değiştirmek performansı etkilemedi.
  • ENA sürücüsünde Boşaltma modlarını etkinleştirmenin (segmentasyon, dağılım toplama, rx/tx sağlama toplamı), "-O3" bayrağıyla derlemenin ve ena.rx_queue_size ve ena.force_large_llq_header parametrelerinin kullanılmasının hiçbir etkisi olmadı.
  • Ağ yığınındaki değişiklikler performansı artırmadı:
    • IPv6'yı devre dışı bırakın: ipv6.disable=1
    • VLAN'ı devre dışı bırakın: modprobe -rv 8021q
    • Paket kaynağı denetimini devre dışı bırak
      • net.ipv4.conf.all.rp_filter=0
      • net.ipv4.conf.eth0.rp_filter=0
      • net.ipv4.conf.all.accept_local=1 (olumsuz etki)
    • net.ipv4.tcp_sack = 0
    • net.ipv4.tcp_dsack=0
    • net.ipv4.tcp_mem/tcp_wmem/tcp_rmem
    • net.core.netdev_budget
    • net.core.dev_weight
    • net.core.netdev_max_backlog
    • net.ipv4.tcp_slow_start_after_idle=0
    • net.ipv4.tcp_moderate_rcvbuf=0
    • net.ipv4.tcp_timestamps=0
    • net.ipv4.tcp_low_latency = 1
    • SO_PRIORITY
    • TCP_NODELAY

    Kaynak: opennet.ru

Yorum ekle