6

Ho una coda di lavoro (utilizzando Amazon SQS) che trasferisce i lavori a molte macchine per il recupero e l'elaborazione di vari documenti su HTTP. Ci sono centinaia di host diversi a cui si accede e non esiste un ordine prevedibile per i lavori.Metodo per coda di lavoro auto-riorganizzante

Per essere educato, non voglio che il mio sistema martello ripetutamente su un singolo host. Quindi, se ottengo un lavoro # 123 per recuperare qualcosa da example.com, ma vedo che ho recuperato un'altra cosa da esempio.com negli ultimi X secondi, dovrei passare a qualcos'altro e salvare il lavoro # 123 per dopo.

La domanda è: qual è un buon modo per implementare questo modello?

Sembra che il primo passo consista nel far sì che i responsabili del lavoro mantengano una lista da qualche parte di tutti i domini e l'ultima volta che è stato effettuato l'accesso a qualcosa su quel dominio. Suppongo che potrebbe essere una semplice tabella DB.

Ci sono quindi molte opzioni possibili su cosa fare se un elaboratore di messaggi ottiene un lavoro che deve essere rinviato.

  1. Basta spingere una copia del messaggio verso la fine della coda e buttarla via senza eseguirla. Spero che, per la prossima volta, sia passato abbastanza tempo. Ciò può causare molti messaggi SQS ridondanti, soprattutto se un grande gruppo di lavori per lo stesso dominio passa in una sola volta.

  2. Dormire per molti secondi è necessario fino a quando la cortesia impone che il lavoro possa essere eseguito. Ciò può causare molti processori di coda che non fanno nulla contemporaneamente.

  3. Accettare il lavoro, ma salvarlo in una coda locale da qualche parte su ciascun processore di coda. Immagino che ogni processore possa "rivendicare" un certo numero di lavori in questo modo, e quindi scegliere di elaborarli in qualsiasi ordine raggiunga la massima cortesia. Questo può essere ancora imprevedibile, perché ogni processore di coda deve essere consapevole dei domini colpiti da tutti gli altri.

  4. Stabilire code separate per ogni dominio e disporre di un processo dedicato a ciascuna coda. Ogni processo dovrebbe essere messo in pausa per X secondi tra l'esecuzione di ogni lavoro, quindi c'è un sacco di sovraccarico del processo di sonno, ma forse questa non è una cosa così brutta.

Hai qualche esperienza con la progettazione di questo genere di cose? Quale strategia consiglieresti?

+0

Sei bloccato al 100% su SQS? Ci sono buoni progetti che NON ti costringono a fare una soluzione per dominio, ma richiedono un controllo diretto della coda che presumo che SQS non fornisca (per essere precisi, possibilità di "sfogliare" la coda senza prendere il comando elemento, e possibilità di prendere l'elemento Nth anziché il top - in pratica, trattando la coda come una lista doppiamente collegata senza inserimento e non una coda pura). – DVK

risposta

0

Si consiglia di impostare una coda per ciascun dominio e un processore per coda.

La maggior parte dei server non dovrebbe avere problemi con le richieste emesse costantemente in serie, purché si tenga d'occhio la quantità totale di trasferimento (ad esempio, si dovrebbe evitare l'indicizzazione di file superiore a poche centinaia di KB a meno che non si abbia un vero ne ho bisogno).

Suppongo che tu stia anche obbedendo alle regole di robots.txt.

2

Code separate per ciascun dominio e una coda di domini.

Ogni processore dovrebbe:

  1. Scegliere un dominio dalla coda di domini.
  2. Se il dominio non è stato aggiornato di recente, selezionare l'attività principale dalla coda di dominio.
  3. Riporta il dominio alla fine della coda di dominio.
  4. Se abbiamo un compito da eseguire, fallo.
  5. Sospensione fino a quando è il momento di controllare il capo della coda di dominio o la coda di dominio viene aggiornata.

Può essere d'aiuto se si organizza la coda dei domini come coda a priorità di tempo - memorizzare i domini nell'ordine del prossimo tempo di aggiornamento.

+0

Se si dispone di un numero sufficiente di domini distinti e si anticipa il conflitto sulla coda dei domini, è possibile farlo in modo che i processori reinseriscano i domini nella propria coda * local *. Quindi modificare il passaggio 1 in "Se local_queue_size

+0

@j_random_hacker: Non sono sicuro che sia una buona idea. Le code locali complicano il flusso di dati e i benefici sono dubbi. Se non hai abbastanza processori, aggiungi altro. Se la tua coda di dominio è troppo grande, aggiungi un po 'di sharding. –

+0

@Alex: Se capisco cosa intendi per "sharding", l'unica complicazione del flusso di dati che il mio suggerimento introdurrà - vale a dire, il ritorno dei domini locali alla coda globale - si verificherebbe esattamente quando lo sharding semplice lascia uno o più processori inattivo. È effettivamente "auto-sharding" più un meccanismo di recupero. Ovviamente si potrebbe omettere il meccanismo di recupero per un'implementazione più semplice che ha tutti i vantaggi (e le inefficienze) di sharding senza la necessità di definire a priori i frammenti. –

Problemi correlati