Server web con memorizzazione nella cache di file di grandi dimensioni nginx 10/20 / 40Gbps [20Gbps raggiunto]


10

In questa domanda vorrei scoprire la migliore configurazione / hardware possibile per fornire 40 Gbps da un singolo server.

Situazione

Abbiamo un server proxy di condivisione video che scarica i picchi dai server di archiviazione lenti dietro di esso. Tutto il traffico è solo HTTP. Il server funge da proxy inverso (file che non sono memorizzati nella cache sul server) e da server Web (file archiviati su unità locali).

Attualmente ci sono qualcosa come 100 TB di file e in crescita sui server di archiviazione back-end.

Il meccanismo di memorizzazione nella cache è implementato in modo indipendente e questa domanda non riguarda la memorizzazione nella cache in quanto funziona molto bene: attualmente offre 14 Gbps, passa ai server back-end solo 2 Gbps. Quindi l'uso della cache è buono.

Obbiettivo

Ottieni una velocità di 40 Gbps o persino superiore da una singola macchina.

Hardware 1

HW: Supermicro SC825, X11SSL-F, Xeon E3-1230v5 (4C/8T@3.4GHz), RAM DDR4 da 16 GB, 2x Supermicro 10G STGN-i1S (LACP L3 + 4)

SSD: 1x 512 GB Samsung, 2x 500 GB Samsung, 2x480 GB Intel 535, 1x 240 GB Intel S3500

Sistema:

  • irqbalancer si è fermato
  • set_irq_affinity per ogni interfaccia (tramite script nel tarball del driver ixgbe)
  • ixgbe-4.3.15
  • Scadenza scheduler I / O
  • iptables vuoto (moduli scaricati)
  • File system: XFS

nginx:

  • sendfile off
  • fili aio
  • directio 1M
  • tcp_nopush on
  • tcp_nodelay on

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

Come visto nei grafici, siamo riusciti a spingere 12,5 Gbps. Sfortunatamente il server non ha risposto.

Ci sono 2 cose che hanno attirato la mia attenzione. Il primo è un'elevata quantità di IRQ. In questo caso purtroppo non ho grafici da / proc / interrupt. La seconda cosa era il carico di sistema elevato, che penso sia stato causato da kswapd0 che aveva problemi a lavorare solo con 16G di RAM.

Hardware 2

HW: Supermicro SC119TQ, X10DRW-i, 2x Xeon E5-2609v4 (8C/8T@1.70GHz), 128GB DDR4 RAM, 2x Supermicro 10G STGN-i1S

SSD, la configurazione del sistema è la stessa dell'hardware 1. Nginx è sendfile attivo (aio / sendfile ulteriormente confrontato).

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

Questo sembra migliore, quindi ora che abbiamo un server, che funziona in picchi, possiamo provare alcune ottimizzazioni.

Discussioni Sendfile vs aio

Ho provato a disabilitare sendfile e usare invece i thread aio.

  • sendfile off
  • fili aio
  • directio 1M (che corrisponde a tutti i file che abbiamo)

vs

  • file di trasmissione attivo

Poi alle 15:00 sono tornato a sendfile e ricaricato nginx (quindi ci è voluto un po 'di tempo per terminare le connessioni esistenti). È bello che l'utilizzo dell'azionamento (misurato da iostat) sia diminuito. Non è cambiato nulla sul traffico (purtroppo zabbix ha deciso di non raccogliere i dati da bond0).

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

sendfile on / off

Ho appena provato a attivare / disattivare l'invio. Nulla è cambiato tranne la riprogrammazione degli interrupt.

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

irqbalancer come server / cron / disabilitato

Come menzionato @lsd ho provato a configurare irqbalancer per essere eseguito tramite cron:

*/5 * * * *   root    /usr/sbin/irqbalance --oneshot --debug 3 > /dev/null

Purtroppo nel mio caso non ha aiutato. Una delle schede di rete ha iniziato a comportarsi in modo strano:

inserisci qui la descrizione dell'immagine

Non sono riuscito a trovare ciò che non andava nei grafici e, come è successo il giorno successivo, ho effettuato l'accesso al server e ho visto che un core era al 100% (utilizzo del sistema).

Ho cercato di avviare irqbalance come servizio, il risultato è stato sempre lo stesso.

Quindi ho deciso di utilizzare lo script set_irq_affinity e il problema è stato risolto immediatamente e il server ha inviato nuovamente 17Gbps.

Hardware 3

Abbiamo effettuato l'aggiornamento al nuovo hardware: chassis 2U 24 (+2) (6xSFF), 2x Xeon E5-2620v4, RAM DDR4 da 64 GB (moduli 4x16GB), 13x SSD, 2x schede di rete Supermicro (con chip Intel). Le nuove CPU hanno migliorato molto le prestazioni.

La configurazione corrente rimane: file di invio, ecc. L'unica differenza è che consentiamo a una sola CPU di gestire entrambe le schede di rete (tramite lo script set_irq_affinity).

È stato raggiunto il limite di 20 Gbps.

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

Prossimo obiettivo? 30Gbps.


Sentiti libero di spararmi idee su come migliorare le prestazioni. Sarò felice di provarlo dal vivo e condividere alcuni grafici pesanti qui.

Qualche idea su come gestire una grande quantità di SoftIRQ sulla CPU?

Questa non è una domanda sulla pianificazione della capacità: ho già l'hardware e il traffico. Posso sempre dividere il traffico su più server (cosa che dovrò comunque fare in futuro) e risolvere il problema con denaro. Questa è tuttavia una domanda sull'ottimizzazione del sistema e il tuning delle prestazioni in uno scenario reale dal vivo.



4
Dici che non si tratta della pianificazione della capacità, ma mi sembra che provare a spingere 40 Gbps attraverso un singolo server sia indicativo di problemi di capacità.
Ceejayoz,

5
Solo un aspetto interessante, in un vecchio lavoro hanno disattivato il servizio di irqbalance, ma hanno comunque eseguito un cron job che eseguiva irqbalance ogni 15 minuti circa. Quindi abbiamo ancora tratto vantaggio dall'irqbalance, ma non dalla frequenza del servizio.
lsd

Aggiornamento: aggiunto il test on / off di sendfile. @lsd: proverò ad usare irqbalance come standalone tramite cron la prossima settimana. Vediamo quale sarà l'impatto.
Yarik Dot,

1
Cosa hai usato per creare i grafici?
Johnny V,

Risposte:


9

Disclaimer : lo stesso consiglio si applica a tutti i servizi che spingono più di 10 Gbps. Incluso ma non limitato a bilanciamento del carico, server di cache, server Web (HAProxy, Varnish, nginx, tomcat, ...)

Quello che vuoi fare è sbagliato, non farlo

Utilizzare invece un CDN

I CDN hanno lo scopo di fornire contenuto statico memorizzabile. Utilizza lo strumento giusto per il lavoro (akamai, MaxCDN, cloudflare, cloudfront, ...)

Qualsiasi CDN, anche gratuito, farà meglio di qualsiasi cosa tu possa ottenere da solo.

Scala in orizzontale invece

Mi aspetto che un singolo server gestisca out-of-the-box 1-5Gbps senza troppe modifiche (nota: serve solo file statici). Gli 8-10 Gbps sono generalmente a portata di mano con una messa a punto avanzata.

Tuttavia, ci sono molti limiti a ciò che una singola scatola può contenere. Dovresti preferire ridimensionare in orizzontale.

Esegui un singolo box, prova cose, misura, benchmark, ottimizza ... fino a quando quel box non è affidabile e affidabile e le sue capacità sono ben determinate, quindi metti più scatole simili con un bilanciamento del carico globale di fronte.

Esistono alcune opzioni globali di bilanciamento del carico: la maggior parte dei CDN può farlo, roundrobin DNS, ELB / Google load balancer ...

Ignoriamo le buone pratiche e facciamolo comunque

Comprensione del modello di traffico

            WITHOUT REVERSE PROXY

[request ]  user ===(rx)==> backend application
[response]  user <==(tx)===     [processing...]

Ci sono due cose da considerare: la larghezza di banda e la direzione (emissione o ricezione).

I file di piccole dimensioni sono 50/50 tx / rx perché le intestazioni HTTP e l'overhead TCP sono più grandi del contenuto del file.

I file di grandi dimensioni sono 90/10 tx / rx perché la dimensione della richiesta è trascurabile rispetto alla dimensione della risposta.

            WITH REVERSE PROXY

[request ]  user ===(rx)==> nginx ===(tx)==> backend application
[response]  user <==(tx)=== nginx <==(rx)===     [processing...]

Il proxy inverso inoltra tutti i messaggi in entrambe le direzioni. Il carico è sempre 50/50 e il traffico totale viene raddoppiato.

Diventa più complesso con la memorizzazione nella cache abilitata. Le richieste possono essere inoltrate sul disco rigido, i cui dati possono essere memorizzati nella cache.

Nota : ignorerò l'aspetto della cache in questo post. Ci concentreremo su come ottenere 10-40 Gbps sulla rete. Sapendo se i dati provengono dalla cache e l'ottimizzazione della cache è un altro argomento, viene spinto oltre il filo in entrambi i modi.

Limitazioni monocromatiche

Il bilanciamento del carico è monocromatico (in particolare il bilanciamento TCP). L'aggiunta di core non lo rende più veloce ma può renderlo più lento.

Lo stesso vale per il bilanciamento HTTP con modalità semplici (ad es. IP, URL, basate su cookie. Il proxy inverso legge le intestazioni al volo, non analizza né elabora le richieste HTTP in senso stretto).

In modalità HTTPS, la decrittografia / crittografia SSL è più intensa di tutto il resto necessario per il proxy. Il traffico SSL può e deve essere suddiviso su più core.

SSL

Dato che fai tutto su SSL. Ti consigliamo di ottimizzare quella parte.

Crittografare e decodificare al volo 40 Gbps è un bel risultato.

Prendi un processore di ultima generazione con le istruzioni AES-NI (utilizzate per le operazioni SSL).

Ottimizza l'algoritmo utilizzato dai certificati. Esistono molti algoritmi. Vuoi quello che è il più efficace sulla tua CPU (esegui il benchmarking) MENTRE viene supportato dai client ED è abbastanza sicuro (nessuna crittografia eccessiva necessaria).

IRQ e pinning centrale

La scheda di rete sta generando interrupt (IRQ) quando ci sono nuovi dati da leggere e la CPU viene anticipata per gestire immediatamente la coda. È un'operazione in esecuzione nel kernel e / o nei driver di dispositivo ed è rigorosamente monocore.

Può essere il più grande consumatore di CPU con miliardi di pacchetti in uscita in tutte le direzioni.

Assegna alla scheda di rete un numero IRQ univoco e fissalo a un core specifico (vedi le impostazioni di Linux o BIOS).

Pin il proxy inverso ad altri core. Non vogliamo che queste due cose interferiscano.

Adattatore Ethernet

La scheda di rete sta facendo molto del lavoro pesante. Tutti i dispositivi e i produttori non sono uguali in termini di prestazioni.

Dimentica l'adattatore integrato sulle schede madri (non importa se server o scheda madre consumer), fanno semplicemente schifo.

Offload TCP

TCP è un protocollo molto intenso in termini di elaborazione (checksum, ACK, ritrasmissione, riassemblaggio di pacchetti, ...) Il kernel gestisce gran parte del lavoro ma alcune operazioni possono essere scaricate sulla scheda di rete se lo supporta.

Non vogliamo solo una carta relativamente veloce , ne vogliamo una con tutte le campane e i fischi.

Dimentica Intel, Mellanox, Dell, HP, qualunque cosa. Non supportano tutto ciò.

C'è solo un'opzione sul tavolo: SolarFlare - L'arma segreta delle aziende HFT e della CDN.

Il mondo è diviso in due tipi di persone: " Quelli che conoscono SolarFlare " e " Quelli che non lo sanno ". (il primo set è strettamente equivalente a " persone che fanno rete a 10 Gbps e si preoccupano di ogni bit "). Ma sto divagando, concentriamoci: D

Ottimizzazione TCP del kernel

Sono disponibili opzioni sysctl.confper i buffer di rete del kernel. Cosa fanno o non fanno queste impostazioni. Davvero non lo so.

net.core.wmem_max
net.core.rmem_max
net.core.wmem_default
net.core.rmem_default

net.ipv4.tcp_mem
net.ipv4.tcp_wmem
net.ipv4.tcp_rmem

Giocare con queste impostazioni è il segno definitivo della sovraottimizzazione (cioè generalmente inutile o controproducente).

Eccezionalmente, ciò potrebbe avere senso dati i requisiti estremi.

(Nota: 40 Gbps su una singola scatola sono eccessivamente ottimizzati. Il percorso ragionevole è ridimensionare orizzontalmente.)

Alcuni limiti fisici

Banda di memoria

Alcuni numeri sulla larghezza di banda della memoria (principalmente in GB / s): http://www.tweaktown.com/articles/6619/crucial-ddr4-memory-performance-overview-early-look-vs-ddr2-ddr3/index.html

Supponiamo che l'intervallo sia 150-300 Gbps per la larghezza di banda della memoria (limite massimo in condizioni ideali).

Tutti i pacchetti devono essere nella memoria ad un certo punto. Il semplice inserimento di dati a una velocità di linea di 40 Gbps è un carico pesante sul sistema.

Rimarrà il potere di elaborare i dati? Bene, non esageriamo troppo con le nostre aspettative. Sto solo dicendo ^^

Bus PCI-Express

PCIe 2.0 è 4 Gb / s per corsia. PCIe 3.0 è 8 Gbps per corsia (non tutto è disponibile per la scheda PCI).

Una scheda di rete a 40 Gbps con una singola porta Ethernet promette di più rispetto al bus PCIe se il connettore ha una lunghezza inferiore a 16x rispetto alle specifiche v3.0.

Altro

Potremmo andare oltre altri limiti. Il punto è che l'hardware ha forti limitazioni inerenti alla legge della fisica.

Il software non può fare di meglio dell'hardware su cui è in esecuzione.

La spina dorsale di rete

Tutti questi pacchetti devono eventualmente andare da qualche parte, attraversando switch e router. Gli switch e il router da 10 Gbps sono [quasi] una merce. I 40 Gbps non lo sono.

Inoltre, la larghezza di banda deve essere end-to-end, quindi che tipo di collegamenti hai con l'utente?

L'ultima volta che ho controllato con il mio ragazzo del datacenter per un piccolo progetto da 10 milioni di utenti, era abbastanza chiaro che ci sarebbero stati solo collegamenti 2x a 10 Gbit a Internet.

Dischi fissi

iostat -xtc 3

Le metriche sono divise per lettura e scrittura. Controlla la coda (<1 è buono), la latenza (<1 ms è buono) e la velocità di trasferimento (maggiore è il migliore).

Se il disco è lento, la soluzione è quella di inserire un SSD maggiore e più grande nel raid 10. (nota che la larghezza di banda dell'SSD aumenta linearmente con le dimensioni dell'SSD).

Scelta della CPU

IRQ e altri colli di bottiglia funzionano solo su un core, quindi puntano alla CPU con le massime prestazioni single core (ovvero la frequenza più alta).

La crittografia / decrittografia SSL richiede le istruzioni AES-NI, quindi punta solo all'ultima revisione della CPU.

I vantaggi SSL da più core sono quindi mirati a molti core.

Per farla breve: la CPU ideale è la più recente con la più alta frequenza disponibile e molti core. Basta scegliere il più costoso e probabilmente è così: D

inviare file()

Sendfile ON

Semplicemente il più grande progresso dei kernel moderni per i server web ad alte prestazioni.

Nota finale

1 SolarFlare NIC 40 Gbps (pin IRQ and core)
2 SolarFlare NIC 40 Gbps (pin IRQ and core)
3 nginx master process
4 nginx worker
5 nginx worker
6 nginx worker
7 nginx worker
8 nginx worker
...

Una cosa bloccata su una CPU. Questa è la strada da percorrere.

Una scheda di rete che conduce al mondo esterno. Una scheda di rete che porta alla rete interna. La suddivisione delle responsabilità è sempre buona (anche se la doppia scheda di rete a 40 Gbps può essere eccessiva).

Sono molte le cose da mettere a punto, alcune delle quali potrebbero essere oggetto di un piccolo libro. Divertiti a fare il benchmarking di tutto ciò. Torna a pubblicare i risultati.


Le schede di rete Solarflare sono state ordinate alcune settimane fa per essere testate. Ora aspetto che il supporto di Solarflare consigli su come ottimizzare il sistema per ottenere il massimo. prestazione possibile. Dopo questo test condividerò la configurazione e i risultati.
Yarik Dot,

1
Standing Ovation ....
James Pulley,

Solo un rapido aggiornamento sui dischi rigidi: l'utilizzo di qualsiasi tipo di raid in questo scenario (unità ssd) non funziona correttamente. Poiché gli SSD sono indossati in modo diverso, hanno prestazioni diverse e con un SSD lento nel raid, le prestazioni dell'intero raid possono essere scadenti. Lo scenario migliore, che funziona meglio per noi, è l'utilizzo di unità singole, senza alcun raid HW / SW.
Yarik Dot

0

Non posso ancora commentare a causa della reputazione, quindi devo aggiungere una risposta invece ...

Nel primo esempio hai detto:

Ci sono 2 cose che hanno attirato la mia attenzione. Il primo è un'elevata quantità di IRQ. In questo caso purtroppo non ho grafici da / proc / interrupt. La seconda cosa era il carico di sistema elevato, che penso sia stato causato da kswapd0 che aveva problemi a lavorare solo con 16G di RAM.

Assolutamente d'accordo sul fatto che questi sono punti importanti.

  1. Prova a utilizzare l'agente collectd, che può raccogliere IRQ e archiviare utilizzando RRD.

  2. Hai un grafico dell'utilizzo della memoria?

    In superficie, questo sembra un problema alla CPU, l'elevato softirq% potrebbe semplicemente puntare il dito sulla memoria, se ci sono molti errori di pagina rigidi o deboli. Penso che la cessione sia l'improvvisa escalation degli IRQ, a spese della CPU di sistema intorno alle 19:00.

Da quello che posso vedere dalle specifiche, tutto sembra uguale a parte:

  • la memoria
  • i modelli di CPU - a meno che non mi sbagli, i benchmark indicherebbero che dovrebbero essere simili, e in questo tipo di casi preferirei la scatola con meno core più veloci.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.