Puncte:3

Ajustați Linux și Nignx pentru a gestiona 10k conexiuni @10Gbps Server

drapel br

Tocmai am primit un nou server de 10 Gbps cu 8 nuclee CPU, 64 GB RAM și 1 TB NVMe

OS Centos 7.9 kernel 3.10.0-1160.36.2.el7.x86_64 a încercat și kernel-ml 5.13
SELinux este dezactivat.
firewalld și irqbalance s-au oprit

Am făcut test de rețea folosind iperf3, viteza este confirmată în jur de 9,5 Gbps.

Apoi, un alt test folosind servere de 10 x 1 Gbps pentru a descărca un fișier static de pe server, serverul a reușit să împingă aproape cei 10 Gbps complet pe cele 10 servere cu ușurință.

Așa că am pus serverul în producție, care deservește clienții care descarcă fișiere statice folosind Nginx. Este capabil să ofere o performanță stabilă până când ajunge la ~2.000 de conexiuni, apoi performanța începe să scadă semnificativ. Văd că traficul scade atunci când conexiunile cresc, așa că deservirea a peste 4.000 de conexiuni oferă doar 2 Gbps!

Imaginea 1 arată Trafic și HTTP

Cel mai confuz este că CPU este aproape inactiv, RAM este gratuită, utilizarea IO este scăzută datorită NVMe și RAM mare, dar atunci când serverul are mii de conexiuni, viteza devine lentă la toate serviciile HTTP, FTP, SSH, chiar și actualizarea yum durează atât de mult timpul să răspunzi. Pare o congestie în rețea sau pachete sau o oarecare accelerare în kernel sau nic.

htop top nload

Am încercat cele mai multe sfaturi de tuning

ifconfig eth0 txqueuelen 20000
ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
        ether 00:16:3e:c2:f5:21 txqueuelen 20000 (Ethernet)
        Pachete RX 26012067560 octeți 1665662731749 (1,5 TiB)
        Erori RX 0 a scăzut 0 depășiri 0 cadru 0
        Pachete TX 30684216747 octeți 79033055227212 (71,8 TiB)
        Erori TX 0 a scăzut 0 depășiri 0 purtător 0 coliziuni 0

tc -s -d qdisc arată dev eth0

qdisc mq 1: rădăcină
    Trimis 7733649086021 octeți 1012203012 pkt (scăzut 0, depășește 0 cozi 169567)
    întârziere 4107556b 2803p cozi 169567
qdisc pfifo_fast 0: benzi parentale 1:8 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
    Trimis 2503685906926 octeți 1714686297 pkt (scăpat 0, depășește 0 cozi 1447)
    întârziere 4107556b 2803p cozi 1447
qdisc pfifo_fast 0: benzi părinte 1:7 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
    Trimis 532876060762 octeți 366663805 pkt (scăpat 0, depășește 0 cozi 7790)
    Întârziere 0b 0p cozi 7790
qdisc pfifo_fast 0: benzi părinte 1:6 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
    Trimis 563510390106 octeți 387948990 pkt (scăpat 0, depășește 0 cozi 9694)
    Întârziere 0b 0p cozi 9694
qdisc pfifo_fast 0: benzi părinte 1:5 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
    Trimis 563033712946 octeți 387564038 pkt (scăzut 0, depășește 0 cozi 10259)
    Întârziere 0b 0p cozi 10259
qdisc pfifo_fast 0: benzi părinte 1:4 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
    Trimis 562982455659 octeți 387451904 pkt (scăpat 0, depășește 0 cozi 10706)
    Întârziere 0b 0p cozi 10706
qdisc pfifo_fast 0: benzi părinte 1:3 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
    Trimis 559557988260 octeți 385263948 pkt (scăpat 0, depășește 0 cozi 9983)
    Întârziere 0b 0p cozi 9983
qdisc pfifo_fast 0: benzi părinte 1:2 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
    Trimis 528903326344 octeți 364105031 pkt (scăpat 0, depășește 0 cozi 7718)
    întârziere 0b 0p cozi 7718
qdisc pfifo_fast 0: benzi parentale 1:1 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
    Trimis 1919099245018 octeți 1313486295 pkt (scăzut 0, depășește 0 cozi 111970)
    întârziere 0b 0p cozi 111970

ethtool -k eth0

Caracteristici pentru eth0:
rx-checksumming: activat [fixat]
tx-checksumming: activat
        tx-checksum-ipv4: dezactivat [remediat]
        tx-checksum-ip-generic: activat
        tx-checksum-ipv6: dezactivat [remediat]
        tx-checksum-fcoe-crc: dezactivat [remediat]
        tx-checksum-sctp: dezactivat [remediat]
împrăștia-aduna: pe
        tx-scatter-gather: on
        tx-scatter-gather-fraglist: dezactivat [remediat]
tcp-segmentation-offload: dezactivat
        tx-tcp-segmentation: off
        tx-tcp-ecn-segmentation: off
        tx-tcp6-segmentare: dezactivat
        tx-tcp-mangleid-segmentation: off
udp-fragmentare-descărcare: activat
generic-segmentare-descărcare: off
generic-receive-offload: oprit
mare-recepție-descărcare: oprit [fix]
rx-vlan-offload: oprit [remediat]
tx-vlan-offload: dezactivat [remediat]
filtre-ntuple: dezactivat [fix]
primire-hashing: dezactivat [fixat]
highdma: activat [fixat]
rx-vlan-filter: activat [fixat]
vlan-challenged: dezactivat [remediat]
tx-lockless: dezactivat [fixat]
netns-local: dezactivat [fixat]
tx-gso-robust: oprit [remediat]
tx-fcoe-segmentation: off [fix]
tx-gre-segmentation: off [fix]
tx-ipip-segmentation: off [fixat]
tx-sit-segmentation: dezactivat [fixat]
tx-udp_tnl-segmentation: off [fixat]
fcoe-mtu: oprit [fixat]
tx-nocache-copy: off
loopback: dezactivat [fixat]
rx-fcs: oprit [fixat]
rx-all: oprit [fixat]
tx-vlan-stag-hw-insert: dezactivat [fixat]
rx-vlan-stag-hw-parse: dezactivat [remediat]
rx-vlan-stag-filter: dezactivat [fixat]
busy-poll: dezactivat [fixat]
tx-gre-csum-segmentation: off [fixat]
tx-udp_tnl-csum-segmentation: dezactivat [fixat]
tx-gso-partial: dezactivat [fixat]
tx-sctp-segmentation: off [fixat]
rx-gro-hw: oprit [fixat]
l2-fwd-offload: oprit [fixat]
hw-tc-offload: oprit [remediat]
rx-udp_tunnel-port-offload: dezactivat [remediat]

sysctl -p

vm.max_map_count = 1048575
net.ipv4.tcp_timestamps = 0
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.tcp_ecn = 0
net.ipv4.tcp_sack = 1
net.ipv4.tcp_syncookies = 0
net.ipv4.conf.all.log_martians = 1
vm.swappiness = 10
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65536
net.core.netdev_max_backlog = 250000
fs.file-max = 100000
net.ipv4.ip_local_port_range = 13000 65000
net.ipv4.udp_rmem_min = 8192
net.ipv4.udp_wmem_min = 8192
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0
net.ipv4.tcp_slow_start_after_idle = 0
net.core.rmem_max = 2147483647
net.core.rmem_default = 2147483647
net.core.wmem_max = 2147483647
net.core.wmem_default = 2147483647
net.core.optmem_max = 2147483647
net.ipv4.tcp_rmem = 4096 87380 2147483647
net.ipv4.tcp_wmem = 4096 65536 2147483647
net.ipv4.tcp_low_latency = 1
net.ipv4.tcp_adv_win_scale = 1
net.ipv4.tcp_keepalive_time = 60
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 5
net.ipv4.tcp_max_tw_buckets = 2000000
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_keepalive_probes = 5
net.netfilter.nf_conntrack_max = 655360
net.netfilter.nf_conntrack_tcp_timeout_established = 10800
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

ulimit -a

dimensiunea fișierului de bază (blocuri, -c) 0
dimensiunea segmentului de date (kbytes, -d) nelimitat
prioritate de programare (-e) 0
dimensiunea fișierului (blocuri, -f) nelimitată
semnale în așteptare (-i) 256680
memorie maximă blocată (kbytes, -l) nelimitată
dimensiunea maximă a memoriei (kbytes, -m) nelimitată
fișiere deschise (-n) 100000
dimensiunea conductei (512 octeți, -p) 8
Cozi de mesaje POSIX (octeți, -q) 819200
prioritate în timp real (-r) 0
dimensiunea stivei (kbytes, -s) 100000
timp CPU (secunde, -t) nelimitat
max. procese utilizator (-u) 100000
memorie virtuală (kbytes, -v) nelimitată
blocări de fișiere (-x) nelimitate

nginx.conf

worker_proceses auto;
worker_rlimit_nofile 100000;

fire_pool fire implicite=256 max_queue=65536;

evenimente {
    conexiuni_muncitor 65536;
    worker_aio_requests 65536;
    multi_accept pe;
    accept_mutex activat;
    utilizați epoll;
}

http {
    server_tokens dezactivat;
    server_names_hash_max_size 4096;
    server_names_hash_bucket_size 128;

    tcp_nopush activat;
    tcp_nodelay activat;
    client_body_timeout 12;
    client_header_timeout 12;
    keepalive_timeout 15;
    keepalive_requests 1000;
    send_timeout 10;

    fire aio=implicit;
    sendfile activat;
    sendfile_max_chunk 512k;
    open_file_cache max=100000 inactiv=10m;
    open_file_cache_valid 10m;
    open_file_cache_min_uses 10;
    open_file_cache_errors activat;

    gzip off;
}

Deci întrebarea este: Cum se servesc conexiuni de 10k cu trafic de 10 Gbps care descarcă fișiere statice? Este o problemă de linux sau nginx sau hardware?

Brandon Xavier avatar
drapel us
Există un ghid specific pe care l-ați urmat pentru reglajul dvs.? În special, sunt curios despre: A) alegerea de a nu activa cadrele jumbo B) afinitatea/pinningul IRQ - văd că ați dezactivat irqbalance, dar nu se menționează fixarea IRQ-urilor NIC la un anumit CPU C) diferiții parametri care au fost modificați din valorile implicite (ne pare rău, dar determinarea acestui lucru doar din configurația dvs. de rulare nu este cu adevărat o utilizare bună a timpului nimănui ;-)
JonS avatar
drapel br
Am citit multe articole online https://www.kernel.org/doc/ols/2009/ols2009-pages-169-184.pdf https://fasterdata.es.net/host-tuning/linux/ https://darksideclouds.wordpress.com/2016/10/10/tuning-10gb-nics-highway-to-hell/ A) Pentru că, după cum știu, trebuie să fie activat pe toate switch-urile, dispozitivele de rețea și clienții de conectare, deci este util doar pentru transferul de date între servere de mare viteză. B) Nu am setat afinitatea deoarece aceasta este o mașină virtuală, o pot seta? C) Presupun că parametrii impliciti sunt cunoscuți de oricine a petrecut timp bun în linux și nginx și pot fi găsiți online.
JonS avatar
drapel br
într-adevăr, toate întreruperile NIC se duc doar la un singur CPU https://pastebin.com/9JTbgt5J, deci este un blocaj, cum să setați afinitatea irq pe VM virtio?
Puncte:3
drapel br
Joe

A răspuns deja de Brandon. Activați irqbalance. Rulați numad și reglat. Nu mai încercați să reglați dacă nu aveți o anumită sarcină de lucru care o necesită.Unde sunt rezultatele testelor dvs. de lucru din testarea a 2000-10000 de solicitări înainte de implementare? Această problemă nu ar fi trebuit niciodată văzută în producție. În mod clar ar fi fost identificat prin testare. Utilizarea în lumea reală va descoperi adesea erori neobișnuite, dar multe/majoritatea erorilor de configurare și aplicații pot fi identificate și corectate în timpul testării. Există multe documente disponibile cu privire la afinitatea irq. Mă îndoiesc că cazul tău de utilizare poate face mai bine decât utilizarea instrumentelor de reglare încorporate. Mai mult ca sigur, reglarea manuală va funcționa mai rău.

JonS avatar
drapel br
Am activat irqbalance, acum întreruperile sunt echilibrate pe cele 8 nuclee CPU, dar problema încă există, se pare că este o problemă la manipularea corectă a pachetelor. Am activat large-receive-offload și tcp-segmentation-offload, dar nu o diferență mare.
Brandon Xavier avatar
drapel us
Sperăm că lucrați la gazdă înainte de a ajusta oaspetele.
Puncte:1
drapel sz

Ieșirea de la top spune că nucleul tău este inundat de întreruperi ușoare de la toate conexiunile de intrare. Conexiunile vin atât de repede încât întreruperile hardware declanșate de placa de rețea așteaptă întreruperi soft mai repede decât le poate rezolva nucleul.Acesta este motivul pentru care utilizarea CPU, RAM și IO este atât de scăzută; sistemul continuă să fie întrerupt de conexiunile de intrare. Ceea ce aveți nevoie aici este un echilibrator de încărcare.

JonS avatar
drapel br
Folosim deja load-balancer pentru a trimite trafic la 2 servere cu aceeași configurație, așa că vreau ca fiecare server să gestioneze multe conexiuni cu lățime de bandă mare. Adăugarea mai multor nuclee CPU rezolvă problema întreruperilor soft?
JonS avatar
drapel br
într-adevăr, toate întreruperile NIC se duc doar la un singur CPU https://pastebin.com/9JTbgt5J, deci este un blocaj, cum să setați afinitatea irq pe VM virtio?

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.