Transazioni e code distribuite, ruby, erlang

5

Ho un problema che coinvolge diverse macchine, code di messaggi e transazioni. Quindi, ad esempio, un utente fa clic su una pagina Web, il clic invia un messaggio a un'altra macchina che aggiunge un pagamento all'account dell'utente. Ci possono essere molte migliaia di clic al secondo. Tutti gli aspetti della transazione devono essere tolleranti ai guasti.

Non ho mai avuto a che fare con qualcosa di simile prima, ma un po 'di lettura suggerisce che questo è un problema ben noto.

Quindi alle mie domande. Ho ragione nel ritenere che il modo sicuro per farlo sia con un commit a due fasi, ma il protocollo sta bloccando e quindi non otterrò le prestazioni richieste? Sembra che i DB come redis e il sistema di accodamento dei messaggi come Rescue, RabbitMQ ecc non mi aiutino molto - anche se implemento una sorta di commit a due fasi, i dati andranno persi se redis si arresta perché è essenzialmente solo memoria .

Tutto ciò mi ha indotto a guardare a erlang - ma prima di entrare e iniziare a imparare una nuova lingua, mi piacerebbe davvero capire meglio se ne vale la pena. In particolare, ho ragione nel pensare che a causa delle sue capacità di elaborazione parallele, erlang è una scelta migliore per implementare un protocollo di blocco come il commit a due fasi, o sono confuso?

    
posta chrispanda 13.10.2011 - 09:13
fonte

3 risposte

1

In base al commento, non hai un commit a due fasi. Hai due diversi problemi di commit monofase normali.

Una soluzione semplice (ma probabilmente errata) sarebbe quella di avere il sito web, quando cliccato, inserire un record nel database. Questo può essere fatto a livello transazionale durante l'elaborazione web, quindi c'è un'alta probabilità che l'utente sappia che il suo clic è stato preso. Ma a quel punto non sapranno che il pagamento è stato effettuato.

Un sistema separato potrebbe interrogare il db (ho detto che probabilmente era sbagliato) in cerca di voci. Se trova una voce, può eliminare transzionalmente quella riga e modificare il record di pagamento. Questo rende un semplice sistema riavviabile.

Se vuoi che sia un po 'più in tempo reale, puoi usare una coda, con semantica delle transazioni a entrambe le estremità e una coda duratura (cioè basata su disco) nel mezzo.

Il clic web farebbe accodamento transazionale di qualcosa. Il gestore code si prenderà cura di mantenerlo su disco se questo è appropriato. Alla fine del pagamento, è possibile deselezionare un articolo e registrare il pagamento. Non è richiesto il commit a due fasi (più o meno) perché non si ha mai a che fare con risorse distribuite. Se il tuo server in coda si arresta in modo anomalo, dovresti in qualche modo essere in grado di rilevare se l'ultimo elemento in coda è già nel database, ma dovrebbe essere risolvibile con qualche tipo di ID di richiesta nel messaggio.

A meno che non abbia completamente frainteso la domanda. Dato che non capisco quali due risorse stai provando a fare il commit a due fasi tra ...

    
risposta data 14.10.2011 - 21:09
fonte
1

Ho usato Redis con code di messaggi per un piccolo sistema distribuito a 24 nodi. È molto bello, ad alte prestazioni e facile da usare, con molti collegamenti linguistici. Lo uso con Python e PHP. Ha anche una funzione che serializza ogni operazione su disco, e in caso di interruzione di corrente è possibile riprodurre il registro. Forse potresti provare a prototipare una soluzione al tuo problema e vedere se fa il lavoro. La curva di apprendimento non è così ripida come quella di Erlang. : -)

    
risposta data 20.01.2012 - 14:42
fonte
0

Finché il tuo messaggio accoda il middleware è riavviabile e può garantire esattamente l'elaborazione una volta, starai bene. Le tue app dovrebbero lasciare cadere le loro richieste in coda e lo strumento middleware si prenderà cura di persistere e gestire l'attività di riprova. Alla fine del "livello dati", devi solo assicurarti che la transazione al DB e il riconoscimento al middleware avvengano correttamente.

Questo può essere gestito da un vero strumento di commit di fase XA 2, oppure puoi aggirarlo.

Ad esempio, forse, salva l'ID del messaggio univoco nel DB quando registri il pagamento, e prima di scrivere un pagamento fai un controllo che l'ID del messaggio univoco non sia mai stato visto prima.

    
risposta data 06.01.2012 - 12:05
fonte

Leggi altre domande sui tag