Linux optimizatzea segundoko 1.2 milioi JSON eskaera kudeatzeko

Gida zehatza argitaratu da Linux ingurunea doitzeko HTTP eskaerak prozesatzeko errendimendu handiena lortzeko. Proposaturiko metodoek Amazon EC2 ingurunean (4 vCPU) libreactor liburutegian oinarritutako JSON prozesadorearen errendimendua handitzea ahalbidetu zuten segundoko 224 mila API eskaeratik Amazon Linux 2-ren ezarpen estandarrekin 4.14 nukleoarekin 1.2 milioi eskaera bakoitzeko. bigarren optimizazioaren ondoren (%436ko igoera), eta eskaerak prozesatzeko atzerapenak %79 murriztea ere ekarri zuen. Proposatutako metodoak ez dira libreactor-en espezifikoak eta beste http zerbitzariak erabiltzen dituztenean funtzionatzen dute, nginx, Actix, Netty eta Node.js barne (probetan libreactor erabili zen, horretan oinarritutako soluzio batek errendimendu hobea erakusten zuelako).

Linux optimizatzea segundoko 1.2 milioi JSON eskaera kudeatzeko

Oinarrizko optimizazioak:

  • Libreactor kodea optimizatzea. Oinarri gisa Techempower kit-eko R18 aukera erabili zen, hau da, kodea kenduz erabilitako CPU nukleoen kopurua mugatzeko (optimizazioak lana % 25-27 bizkortzea ahalbidetzen zuen), GCC-n muntatuz "-O3" aukerekin. (% 5-10eko igoera) eta "-march-native" (% 5-10), irakurtzeko/idazteko deiak recv/send-ekin ordezkatuz (%5-10) eta gainkostuak murriztuz pthread-ak erabiltzean (%2-3). . Kodea optimizatu ondoren errendimendu orokorra % 55eko igoera izan zen, eta 224 eskari/seg.tik 347ra igo zen.
  • Desgaitu exekuzio espekulatiboen ahultasunen aurkako babesa. β€œnospectre_v1 nospectre_v2 pti=off mds=off tsx_async_abort=off” parametroak erabiltzean nukleoa kargatzean errendimendua % 28 handitzea ahalbidetzen zuen, eta 347k req/s-tik 446k req/s-ra igo zen. Bereiz, "nospectre_v1" parametrotik (Spectre v1 + SWAPGS babesa) % 1-2 izan zen, "nospectre_v2" (Spectre v2 babesa) - % 15-20, "pti=off" (Spectre v3/Meltdown) - % 6, "mds=off tsx_async_abort=off" (MDS/Zombieload eta TSX Abort asinkronoa) - %6. L1TF/Foreshadow (l1tf=flush), iTLB multihit, Speculative Store Bypass eta SRBDS erasoen aurkako babeserako ezarpenak aldatu gabe geratu ziren, eta horrek ez zuen errendimenduan eraginik izan, probatutako konfigurazioarekin gurutzatzen ez zirelako (adibidez, KVMrako espezifikoak, habiaratuak). birtualizazioa eta beste CPU eredu batzuk).
  • Auditoria eta sistema deiak blokeatzeko mekanismoak desgaitzea "auditctl -a never,task" komandoa erabiliz eta "--security-opt seccomp=unconfined" aukera zehaztuz docker edukiontzia abiaraztean. Errendimenduaren igoera orokorra % 11koa izan zen, eta errendimendua 446 eskakizunetik 495ra.
  • iptables/netfilter desgaitu lotutako nukleoaren moduluak deskargatuz. Suebakia desgaitzeko ideia, zerbitzari-soluzio zehatz batean erabiltzen ez zena, profilaren emaitzek bultzatu zuten, nf_hook_slow funtzioak denboraren %18 behar zuen exekutatzeko. Kontuan izan da nftables iptables baino eraginkorrago funtzionatzen duela, baina Amazon Linux-ek iptables erabiltzen jarraitzen du. iptables desgaitu ondoren, errendimenduaren igoera % 22koa izan zen, eta errendimendua 495k req/s-tik 603k req/s-ra igo zen.
  • PUZaren nukleo desberdinen artean kudeatzaileen migrazioa murriztu da prozesadorearen cachearen erabileraren eraginkortasuna hobetzeko. Optimizazioa gauzatu zen bai libreaktore-prozesuak PUZaren nukleoetara lotzeko mailan (CPU Pinning), bai nukleoaren sare-kudeatzaileen bidez (Receive Side Scaling) bidez. Adibidez, irqbalance desgaitu egin zen eta PUZarekiko ilara-afintasuna esplizituki ezarri zen /proc/irq/$IRQ/smp_affinity_list-en. PUZaren nukleo bera libreactor prozesua eta sarrerako paketeen sare-ilara prozesatzeko, BPF kudeatzaile pertsonalizatua erabiltzen da, socketa sortzean SO_ATTACH_REUSEPORT_CBPF bandera ezarriz konektatuta. Irteerako paketeen ilarak CPUra lotzeko, /sys/class/net/eth0/queues/tx- ezarpenak aldatu dira /xps_cpus. Errendimenduaren igoera orokorra % 38koa izan zen, eta errendimendua 603 eskakizunetik 834ra igo zen.
  • Etenen kudeaketa eta galdeketaren erabilera optimizatzea. ENA kontrolatzailean Adaptive-rx modua gaituz eta sysctl net.core.busy_read manipulatzeak % 28 handitu zuen errendimendua (erritmoa 834k req/s-tik 1.06M req/s-ra igo zen, eta latentzia 361ΞΌs-tik 292ΞΌs-ra jaitsi zen).
  • Sare-pilean alferrikako blokeoak eragiten dituzten sistema-zerbitzuak desgaitzea. Dhclient desgaitu eta IP helbidea eskuz ezartzeak % 6ko errendimendua handitu du eta 1.06 M eskari/s-tik 1.12 M eskakizun/s izatera igaro da. dhclient-ek errendimenduan eragiten duen arrazoia socket gordina erabiliz trafikoaren analisian dago.
  • Spin Lock borrokan. Sare-pila "noqueue" modura aldatzeak sysctl "net.core.default_qdisc=noqueue" eta "tc qdisc replace dev eth0 root mq" bidez aldatzeak % 2ko errendimendua handitu zuen, eta 1.12M req/s-tik 1.15Mra igo zen. eskaria/s.
  • Azken optimizazio txikiak, hala nola GRO (Generic Receive Offload) desgaitzea "ethtool -K eth0 gro off" komandoarekin eta kongestio kubikoaren kontrol algoritmoa reno-rekin ordezkatzea sysctl "net.ipv4.tcp_congestion_control=reno" erabiliz. Produktibitatearen igoera orokorra %4koa izan zen. Errendimendua 1.15 milioi eskari/s-tik 1.2 milioi eskari/s-ra igo da.

Funtzionatu zuten optimizazioez gain, esperotako errendimenduaren igoera ekarri ez zuten metodoak ere aztertzen ditu artikuluak. Adibidez, ondokoak ez dira eraginkorrak izan:

  • Libreactor bereizita exekutatzen ez zen errendimenduan edukiontzi batean exekutatzen. writev send-ekin ordezkatzeak, epoll_wait-en gehienezko gertaerak handitzeak eta GCC bertsioekin eta banderarekin esperimentatzeak ez zuen eraginik izan (efektua "-O3" eta "-march-native" banderetan bakarrik nabaritu zen).
  • Linux nukleoa 4.19 eta 5.4 bertsioetara eguneratzea, SCHED_FIFO eta SCHED_RR programatzaileak erabiliz, sysctl kernel.sched_min_granularity_ns, kernel.sched_wakeup_granularity_ns, transparent_hugepages=never, skew_sources=1 eta clocktick-ek ez zuen eraginik egin.
  • ENA kontrolatzailean, Deskarga moduak (segmentazioa, dispertsio-bilketa, rx/tx checksum) gaitzeak, "-O3" banderarekin eraikitzeak eta ena.rx_queue_size eta ena.force_large_llq_header parametroak erabiltzeak ez zuen eraginik izan.
  • Sareko pilaren aldaketek ez dute errendimendua hobetu:
    • Desgaitu IPv6: ipv6.disable=1
    • Desgaitu VLAN: modprobe -rv 8021q
    • Desgaitu paketeen iturburuaren egiaztapena
      • net.ipv4.conf.all.rp_filter=0
      • net.ipv4.conf.eth0.rp_filter=0
      • net.ipv4.conf.all.accept_local=1 (efektu negatiboa)
    • 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_PRIORITATEA
    • TCP_NODELAY

    Iturria: opennet.ru

Gehitu iruzkin berria