„Linux“ optimizavimas, kad būtų galima apdoroti 1.2 milijono JSON užklausų per sekundę

Buvo paskelbtas išsamus vadovas, kaip suderinti Linux aplinką, kad būtų pasiektas maksimalus HTTP užklausų apdorojimo našumas. Siūlomi metodai leido padidinti JSON procesoriaus, pagrįsto libreactor biblioteka, našumą Amazon EC2 aplinkoje (4 vCPU) nuo 224 tūkst. API užklausų per sekundę su standartiniais Amazon Linux 2 su 4.14 branduoliu nustatymais iki 1.2 mln. antra po optimizavimo (padidėjimas 436 %), taip pat 79 % sumažėjo užklausų apdorojimo vėlavimai. Siūlomi metodai nėra būdingi libreactor ir veikia naudojant kitus http serverius, įskaitant nginx, Actix, Netty ir Node.js (testuose buvo naudojamas libreactor, nes juo pagrįstas sprendimas parodė geresnį našumą).

„Linux“ optimizavimas, kad būtų galima apdoroti 1.2 milijono JSON užklausų per sekundę

Pagrindiniai optimizavimai:

  • „Libractor“ kodo optimizavimas. Kaip pagrindas buvo panaudota R18 parinktis iš Techempower rinkinio, kuri buvo patobulinta pašalinus kodą, kad būtų apribotas naudojamų procesoriaus branduolių skaičius (optimizavimas leido pagreitinti darbą 25-27%), surinkimas GCC naudojant „-O3“ parinktis. (padidėjimas 5–10 %) ir „-march-native“ (5–10 %), skaitymo / rašymo skambučius pakeičiant recv / send (5–10 %) ir sumažinant pridėtines išlaidas naudojant pgijas (2–3 %) . Bendras našumo padidėjimas po kodo optimizavimo buvo 55%, o pralaidumas padidėjo nuo 224k req/s iki 347k req/s.
  • Išjungti apsaugą nuo spekuliacinio vykdymo pažeidžiamumų. Naudojant parametrus „nospectre_v1 nospectre_v2 pti=off mds=off tsx_async_abort=off“ įkeliant branduolį buvo galima padidinti našumą 28%, o pralaidumas padidėjo nuo 347k req/s iki 446k req/s. Atskirai, parametro „nospectre_v1“ (apsauga nuo Spectre v1 + SWAPGS) padidėjimas buvo 1–2%, „nospectre_v2“ (apsauga nuo Spectre v2) – 15–20%, „pti=off“ (Spectre v3/Meltdown) – 6 %, „mds=off tsx_async_abort=off“ (MDS/Zombieload ir TSX asinchroninis nutraukimas) – 6 %. Apsaugos nuo L1TF/Foreshadow (l1tf=flush), iTLB multihit, Speculative Store Bypass ir SRBDS atakų nustatymai liko nepakeisti, o tai neturėjo įtakos našumui, nes nesikerta su išbandyta konfigūracija (pvz., būdinga KVM, įdėta). virtualizacija ir kiti CPU modeliai).
  • Audito ir sistemos skambučių blokavimo mechanizmų išjungimas naudojant komandą „auditctl -a never,task“ ir nurodant parinktį „--security-opt seccomp=unconfined“ paleidžiant doko konteinerį. Bendras našumo padidėjimas buvo 11%, o pralaidumas padidėjo nuo 446 495 rekv/s iki XNUMX XNUMX rekv/s.
  • Iptables/netfilter išjungimas iškraunant susijusius branduolio modulius. Idėją išjungti ugniasienę, kuri nebuvo naudojama konkrečiame serverio sprendime, paskatino profiliavimo rezultatai, pagal kuriuos sprendžiant, kad funkcijai nf_hook_slow vykdyti prireikė 18% laiko. Pažymima, kad nftables veikia efektyviau nei iptables, tačiau Amazon Linux ir toliau naudoja iptables. Išjungus iptables, našumas padidėjo 22%, o pralaidumas padidėjo nuo 495 603 rekv/s iki XNUMX XNUMX rekv/s.
  • Sumažintas tvarkyklių migravimas tarp skirtingų procesoriaus branduolių, siekiant pagerinti procesoriaus talpyklos naudojimo efektyvumą. Optimizavimas buvo atliktas tiek laisvųjų procesų susiejimo su procesoriaus branduoliais lygiu (CPU prisegimas), tiek prisegiant branduolio tinklo tvarkykles (Receive Side Scaling). Pavyzdžiui, irqbalance buvo išjungtas, o eilės giminingumas su procesoriumi buvo aiškiai nustatytas /proc/irq/$IRQ/smp_affinity_list. Norint naudoti tą patį procesoriaus šerdį libreactor procesui ir gaunamų paketų tinklo eilei apdoroti, naudojamas tinkintas BPF tvarkytuvas, prijungtas nustatant SO_ATTACH_REUSEPORT_CBPF vėliavėlę kuriant lizdą. Norint susieti siunčiamų paketų eiles su CPU, parametrai /sys/class/net/eth0/queues/tx- buvo pakeisti /xps_cpus. Bendras našumo padidėjimas buvo 38%, o pralaidumas padidėjo nuo 603 834 rekv/s iki XNUMX XNUMX rekv/s.
  • Pertraukimų tvarkymo ir apklausos naudojimo optimizavimas. Įjungus adaptyvųjį rx režimą ENA tvarkyklėje ir manipuliavus sysctl net.core.busy_read, našumas padidėjo 28 % (pralaida padidėjo nuo 834 1.06 rek/s iki 361 M req/s, o delsa sumažėjo nuo 292 μs iki XNUMX μs).
  • Išjungiamos sistemos paslaugos, dėl kurių bereikalingas blokavimas tinklo krūvoje. Išjungus „dhclient“ ir rankiniu būdu nustačius IP adresą, našumas padidėjo 6%, o pralaidumas padidėjo nuo 1.06 mln. užk./s iki 1.12 mln. Priežastis, dėl kurios „dhclient“ paveikia našumą, yra srauto analizė naudojant neapdorotą lizdą.
  • Kova su Spin Lock. Perjungus tinklo krūvą į „noqueue“ režimą naudojant sysctl „net.core.default_qdisc=noqueue“ ir „tc qdisc pakeisti dev eth0 root mq“, našumas padidėjo 2 %, o pralaidumas padidėjo nuo 1.12 mln. req/s iki 1.15 mln. reikal./s.
  • Paskutiniai smulkūs optimizavimai, pvz., GRO (Generic Receive Offload) išjungimas komanda „ethtool -K eth0 gro off“ ir kubinio perkrovos valdymo algoritmo pakeitimas reno naudojant sysctl „net.ipv4.tcp_congestion_control=reno“. Bendras našumo padidėjimas buvo 4%. Pralaidumas padidėjo nuo 1.15 mln. rekv/s iki 1.2 mln.

Be efektyvių optimizacijų, straipsnyje taip pat aptariami metodai, kurie nepadidėjo laukiamo našumo. Pavyzdžiui, šie veiksmai pasirodė neveiksmingi:

  • Atskirai paleidus libreactor našumas nesiskyrė nuo paleidimo konteineryje. Writev pakeitimas siuntimu, maksimalių įvykių padidinimas epoll_wait ir eksperimentavimas su GCC versijomis ir vėliavėlėmis neturėjo jokio poveikio (poveikis buvo pastebimas tik „-O3“ ir „-march-native“ vėliavėlėms).
  • Linux branduolio atnaujinimas į 4.19 ir 5.4 versijas, naudojant SCHED_FIFO ir SCHED_RR planuoklius, manipuliuojant sysctl kernel.sched_min_granularity_ns, kernel.sched_wakeup_granularity_ns, transparent_hugepages=never, skew_tick=ts ir nepaveikė našumo.
  • ENA tvarkyklėje iškrovimo režimų įjungimas (segmentavimas, sklaidos rinkimas, rx/tx kontrolinė suma), kūrimas naudojant vėliavėlę „-O3“ ir ena.rx_queue_size bei ena.force_large_llq_header parametrų naudojimas neturėjo jokio poveikio.
  • Tinklo paketo pakeitimai nepagerino našumo:
    • Išjungti IPv6: ipv6.disable=1
    • Išjungti VLAN: modprobe -rv 8021q
    • Išjungti paketo šaltinio tikrinimą
      • net.ipv4.conf.all.rp_filter=0
      • net.ipv4.conf.eth0.rp_filter=0
      • net.ipv4.conf.all.accept_local=1 (neigiamas poveikis)
    • 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

    Šaltinis: opennet.ru

Добавить комментарий