Come si può fare un cluster eseguire un'attività solo una volta?

12

Se avevi un'attività che volevi eseguire solo una volta su un cluster di server, a intervalli regolari quale sarebbe il modo migliore per raggiungere questo obiettivo? La definizione di cluster in questo caso è 2 o più server identici con sessioni distribuite posizionate dietro un servizio di bilanciamento del carico.

Caso di utilizzo: hai un'attività che è costosa da eseguire che dovrebbe essere eseguita una volta ogni X ore. Questo lavoro potrebbe ad esempio scorrere su un gruppo di record e aggiornare il loro stato.

  • Lo scenario peggiore è che l'esecuzione del lavoro invalida due volte i dati.
  • Il caso migliore è che il lavoro utilizzi le risorse su tutti i tuoi server.

Riepilogo dei requisiti:

  1. Il lavoro deve ancora essere eseguito anche se uno dei nodi è inattivo.
  2. Il lavoro deve essere eseguito solo una volta per programma.
  3. Se più processi vengono pianificati contemporaneamente o in momenti di sovrapposizione, il numero di lavori in esecuzione viene distribuito equamente tra i server.
  4. Le macchine devono avere lo stesso codice base e essere sincronizzate tramite NTP.
  5. La configurazione può variare tra nodo e nodo, in base alle variabili di ambiente.
  6. Il lavoro deve iniziare in tempo o entro un determinato intervallo del tempo assegnato. (diciamo 5 minuti per esempio)

Possibili soluzioni

  • Imposta un nodo come nodo principale, questo non funziona in quanto viola il precedente 1.
  • Effettuare una richiesta di bilanciamento del bilanciamento del carico per avviare il lavoro. Sfortunatamente, questo ha l'effetto collaterale che se hai più processi in esecuzione nello stesso momento, potrebbero essere tutti eseguiti dallo stesso computer.

Questo dovrebbe essere eseguito in Java, in un contenitore di servlet. Tuttavia non sta codificando i lavori che sto cercando.

Sicuramente questo è un problema risolto con la soluzione migliore conosciuta.

Domanda correlata link

Questo non è un duplicato in quanto la soluzione è insufficiente come da quei 5 requisiti sopra riportati. La soluzione più upvoted soffre di un problema di gara e la seconda soluzione viola il requisito 3

    
posta Wes 14.05.2011 - 21:56
fonte

2 risposte

14

Hai un database condiviso? L'ho fatto usando un database come arbitro in passato.

Fondamentalmente, ogni "lavoro" è rappresentato come una riga nel database. Pianifichi un lavoro aggiungendo una riga al database con l'orario in cui desideri eseguirlo, quindi ogni server esegue:

SELECT TOP 1 *
FROM jobs
WHERE state = 'NotRun'
ORDER BY run_time ASC

In questo modo, selezioneranno tutti il lavoro che è pianificato per eseguire next . Dormono tutti in modo che si sveglino quando il lavoro dovrebbe effettivamente funzionare. Quindi, lo fanno tutti:

UPDATE jobs
SET state = 'Running'
WHERE job_id = :id
  AND state = 'NotRun'

Dove :id è l'identificativo del lavoro che hai ottenuto nel passaggio precedente. Poiché l'aggiornamento è atomico, solo uno dei server aggiornerà effettivamente la riga, è possibile controllare il codice di stato del "numero di aggiornamenti di file" del database per determinare se si era il server che ha effettivamente aggiornato la riga, e quindi se tu sei il server che può eseguire il lavoro.

Se non hai "vinto" e non stai eseguendo il lavoro, torna immediatamente al passaggio 1. Se hai "vinto", pianifica il processo da eseguire in un'altra discussione, quindi attendi un paio di secondi prima di tornare al passaggio 1. In questo modo, i server che non hanno ottenuto il lavoro questa volta sono più propensi a riprendere un lavoro è programmato per essere eseguito immediatamente.

    
risposta data 15.05.2011 - 09:37
fonte
2

Diversi server di app dispongono di una funzione per "servizi di singleton cluster wide".

Ad esempio Weblogic ha una funzione di servizio Singleton configurata tramite la console di amministrazione web.

Devi scrivere una classe che implementa weblogic.cluster.singleton.SingletonService e usarla per dichiarare il servizio nella console di amministrazione. Il cluster si occupa di creare un'istanza della classe e di notificarti quando il servizio viene avviato o arrestato. L'interfaccia SingletonService ha un metodo activate () e un metodo deactivate ().

Le chiamate Weblogic si attivano () quando si avvia per la prima volta il servizio su uno dei nodi del cluster. Se il nodo selezionato si interrompe, il server admin "sposta" il servizio su un server diverso, chiamando activate () lì.

link

    
risposta data 31.08.2016 - 16:21
fonte

Leggi altre domande sui tag