Perché le applicazioni di rete basate su eventi sono intrinsecamente più veloci di quelle thread?

StackOverflow https://stackoverflow.com/questions/290128

Domanda

Abbiamo letto tutti i benchmark e conosciamo i fatti: i server di rete asincroni basati su eventi sono più veloci delle loro controparti thread. Pensa a lighttpd o Zeus vs. Apache o IIS. Perché?

È stato utile?

Soluzione

Penso che non sia la domanda basata su eventi o basata su thread: si tratta di un I / O multiplex non bloccante, socket selezionabili, soluzione vs pool di thread.

Nel primo caso stai gestendo tutti gli input che arrivano indipendentemente da ciò che li sta usando, quindi non ci sono blocchi sulle letture, un singolo 'listener'. Il thread di listener singolo passa i dati a quelli che possono essere thread di lavoro di tipi diversi, anziché uno per ogni connessione. Ancora una volta, nessun blocco sulla scrittura di nessuno dei dati, quindi il gestore dati può semplicemente eseguirlo separatamente. Poiché questa soluzione è principalmente di lettura / scrittura di I / O, non occupa molto tempo della CPU, quindi l'applicazione può impiegarlo per fare quello che vuole.

In una soluzione di pool di thread hai singoli thread che gestiscono ciascuna connessione, quindi devono condividere il tempo per passare da un contesto all'altro, ascoltando. In questa soluzione le operazioni CPU + IO sono nello stesso thread - che ottiene una suddivisione del tempo - quindi si finisce per attendere il completamento delle operazioni di IO op per thread (blocco) che tradizionalmente si potrebbe fare senza usare il tempo della CPU.

Google per I / O non bloccanti per maggiori dettagli- e puoi probabilmente trovare anche alcuni confronti rispetto ai pool di thread.

(se qualcuno può chiarire questi punti, sentiti libero)

Altri suggerimenti

Le applicazioni guidate dagli eventi sono non intrinsecamente più veloci.

Da Perché gli eventi sono una cattiva idea (per server ad alta concorrenza) :

We examine the claimed strengths of events over threads and show that the
weaknesses of threads are artifacts of specific threading implementations
and not inherent to the threading paradigm. As evidence, we present a
user-level thread package that scales to 100,000 threads and achieves
excellent performance in a web server.

Era il 2003. Sicuramente lo stato del threading sui moderni sistemi operativi è migliorato da allora.

Scrivere il nucleo di un server basato su eventi significa reinventare il multitasking cooperativo (stile Windows 3.1) nel codice, molto probabilmente su un sistema operativo che supporta già un corretto multitasking preventivo e senza il vantaggio di un cambio di contesto trasparente. Ciò significa che è necessario gestire lo stato sull'heap che verrebbe normalmente implicato dal puntatore dell'istruzione o memorizzato in una variabile di stack. (Se la tua lingua li ha, le chiusure attenuano significativamente questo dolore. Cercare di farlo in C è molto meno divertente.)

Questo significa anche che ottieni tutti gli avvertimenti che implica il multitasking cooperativo. Se uno dei gestori di eventi impiega del tempo per essere eseguito per qualsiasi motivo, blocca quel thread di eventi. Ritardo richieste totalmente non correlate. Anche lunghe operazioni dispendiose per la CPU devono essere inviate altrove per evitarlo. Quando si parla del nucleo di un server ad alta concorrenza, "operazione lunga" è un termine relativo, nell'ordine dei microsecondi per un server che dovrebbe gestire 100.000 richieste al secondo. Spero che il sistema di memoria virtuale non debba mai estrarre pagine dal disco per te!

Ottenere buone prestazioni da un'architettura basata su eventi può essere complicato, specialmente se si considera la latenza e non solo la velocità effettiva. (Naturalmente, ci sono molti errori che puoi fare anche con i thread. La concorrenza è ancora dura.)

Un paio di domande importanti per l'autore di una nuova applicazione server:

  • Come funzionano i thread sulle piattaforme che intendi supportare oggi? Saranno il tuo collo di bottiglia?
  • Se sei ancora bloccato con un'implementazione del thread non valida: perché nessuno lo sta risolvendo?

Dipende davvero da cosa stai facendo; la programmazione basata su eventi è certamente complicata per le applicazioni non banali. Essere un web server è davvero un problema molto banale e ben compreso e sia i modelli basati su eventi che quelli filettati funzionano abbastanza bene sui sistemi operativi moderni.

Lo sviluppo corretto di applicazioni server più complesse in un modello di eventi è generalmente piuttosto complicato: le applicazioni con thread sono molto più facili da scrivere. Questo può essere il fattore decisivo piuttosto che le prestazioni.

In realtà non si tratta dei thread. Riguarda il modo in cui i thread vengono utilizzati per soddisfare le richieste. Per qualcosa come lighttpd hai un singolo thread che serve connessioni multiple tramite eventi. Per le versioni precedenti di apache hai avuto un processo per connessione e il processo si è svegliato sui dati in arrivo, quindi hai finito con un numero molto grande quando c'erano molte richieste. Ora, tuttavia, con MPM anche Apache è basato sugli eventi, vedi evento MPM apache .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top