Controllo della concorrenza da parte di Thread Pool in uno scenario di richieste intensive di CPU e I / O intensive?

0

Il mio obiettivo è capire come gestire i lavori provenienti dal lato client ad altissima frequenza, ogni lavoro ha un utilizzo intensivo della CPU o I / O, ma entrambi i tipi di lavoro arrivano continuamente sul mio server.

Ad esempio se ThreadPoolExecutor è configurato con 50 thread e la frequenza di richiesta è 100 req / sec e ogni lavoro con CPU richiede 2 secondi per completare e ogni lavoro I / O sta interrogando un database e con 100 req / secondo primi 50 lavori sono ad alta intensità di CPU e rimanenti sono una combinazione di CPU e amp; I / O intensivo. Quindi, in questo scenario, tutti i 50 thread saranno occupati a eseguire lavori intensivi della CPU e i client rimanenti dovranno attendere molto. Voglio risolvere questo problema utilizzando l'executor pool di thread distribuiti in modo che i lavori con utilizzo intensivo della CPU sfruttino il cluster e vadano ad altri nodi per l'esecuzione e il mio server esegua solo lavori di I / O intensivi. come posso progettare un server in questo scenario?

    
posta ahmad raza 07.01.2015 - 16:37
fonte

1 risposta

1

In generale, c'è ben poco che puoi fare qualsiasi cosa con le informazioni raccolte da un'attività. Il motivo è questo: una volta che avvii un'attività, devi lasciarla finire, non importa quale.

  • Non puoi sospenderlo per sempre. Alcune altre parti del codice potrebbero dipendere dal risultato dell'attività; sospenderlo significa che il codice dipendente aspetterà per sempre.
  • Non puoi ucciderlo. L'attività potrebbe aver apportato modifiche nel file system o nel database; potrebbe lasciare il sistema o il datastore in uno stato incoerente se si uccide l'attività nel mezzo dell'esecuzione.
  • Per lo stesso motivo per cui non puoi ucciderlo, non puoi nemmeno spostare un'attività in esecuzione su un altro computer o persino su un altro thread.

Fondamentalmente, una volta che un compito è in esecuzione, devi lasciarlo finire, indipendentemente dalle molte risorse necessarie.

L'unica altra azione correttiva che puoi eseguire è che se vedi un numero significativo di thread worker sono:

  • Esecuzione di alcune attività;
  • Non consumano molto tempo della CPU a causa del fatto che sono bloccati (bloccando I / O)

Quindi puoi forse creare qualche altro thread di lavoro e dare loro nuovi compiti, nella speranza che alcuni di essi siano intensivi della CPU e quindi recuperare i "cicli di CPU sprecati".

Alcuni progetti di pool di thread tentano semplicemente di aumentare opportunisticamente il numero di thread di lavoro (e di eseguirli simultaneamente nelle attività) fino al punto in cui visualizzano rendimenti marginali decrescenti.

link

Posso solo dare una panoramica approssimativa delle idee. Il feedback è benvenuto.

In primo luogo, alcune definizioni.

  • "CPU intensive" - attività che, una volta avviato l'esecuzione su un thread, continueranno ad essere eseguite sulla CPU fino al termine, facendo progressi continui lungo il percorso e raramente si offriranno volontariamente per una "pausa" (operazione di blocco ).

  • "IO intensive" - attività che, durante la sua esecuzione su un thread, tendono a richiedere frequentemente una "pausa" (inserimento in sleep o un'operazione di blocco) volontariamente. Questa "pausa" si verifica in genere quando l'attività è in attesa di un evento esterno, ad esempio in attesa che i dati leggano un file o da una query del database.

  • "CPU wasting" - attività che in apparenza assomigliano al tipo "CPU intensive", ma sono in effetti "busy-spinning" - eseguono un ciclo vuoto stretto senza fare progressi. Potrebbe essere ulteriormente suddiviso in "errori di programmazione (difetto software)" o "carico di lavoro dannoso".

Avviso Uso la parola "volontario" più volte. Ciò è dovuto al fatto che un sistema operativo può sospendere preventivamente un thread mentre passa al contesto in altri thread in modo che il sistema operativo possa supportare un numero totale di thread in eccesso eccessivo rispetto al numero di core della CPU. (I core della CPU tipici sono a una cifra o a dieci bassi, ma il numero totale tipico di thread nel sistema operativo è compreso tra centinaia e migliaia).

È possibile che un thread watchdog (con i privilegi amministrativi appropriati) richieda il sistema operativo per il tempo CPU consumato da ogni thread di lavoro. Questo può essere usato per decidere come "CPU intensive" è una particolare attività in esecuzione.

Inoltre, potrebbe essere possibile che il thread del watchdog si riattivi con un intervallo regolare per verificare quale sia il thread di ciascun worker. Se si vuole scoprire se un thread trascorre la maggior parte del proprio tempo a essere bloccato (in attesa di I / O), sarà necessario eseguire il drill down del motivo della sospensione del thread. Come descritto in precedenza, è necessario distinguere tra i thread che sono preventivati dal sistema operativo, rispetto ai thread che sono bloccati dalle proprie operazioni IO. Questo è fattibile su alcuni sistemi operativi, ma potrebbe essere impossibile su altri sistemi operativi.

Non ho mai usato nessuna di queste tecniche quindi non so quanto siano praticabili o efficaci queste tecniche.

    
risposta data 08.01.2015 - 04:40
fonte

Leggi altre domande sui tag