2013-03-16 11 views
6

Sto progettando un'applicazione che richiede un gruppo distribuito di elaboratori che devono consumare in modo asincrono e produrre dati in un flusso specifico. Ad esempio:Esiste un framework di pipeline di elaborazione dati distribuiti o un buon modo per organizzarne uno?

  • Il componente A recupera le pagine.
  • Componente B analizza le pagine da A.
  • Componente C esercizi analizzati pezzi da B.

Ci sono ovviamente più appena tre componenti coinvolti.

Ulteriori requisiti:

  • Ogni componente deve essere un processo separato (o un insieme di processi).
  • I produttori non sanno nulla dei loro consumatori. In altre parole, il componente A produce solo dati, non conoscendo quali componenti consumano tali dati.

Questo è un tipo di flusso di dati risolto dai sistemi orientati alla topologia come Storm. Mentre Storm sembra buono, sono scettico; è un sistema Java ed è basato su Thrift, nessuno dei quali sono un fan.

Attualmente mi sto orientando verso un approccio pub/sub-style che utilizza AMQP come trasporto dati, con HTTP come protocollo per la condivisione/archiviazione dei dati. Ciò significa che il modello di coda AMQP diventa un'API pubblica: in altre parole, il consumatore deve sapere quale host e coda AMQP viene utilizzato dal produttore, cosa di cui non sono particolarmente soddisfatto, ma potrebbe valerne la pena.

Un altro problema con l'approccio AMQP è che ogni componente dovrà avere logica molto simile per:

  • Collegamento alla coda
  • Gestione degli errori di connessione
  • dati
  • serializzazione/deserializzazione in un formato comune
  • Esecuzione dei lavoratori effettivi (goroutines o sottoprocessi che si biforcano)
  • ridimensionamento dinamico dei lavoratori
  • Tolleranza agli errori di registrazione
  • Nodo
  • metriche Processing
  • coda di limitazione
  • priorità Queue (alcuni lavoratori sono meno importanti di altri)

... e tanti altri piccoli dettagli che ogni componente avrà bisogno.

Anche se un consumatore è logicamente molto semplice (si pensi ai lavori di MapReduce, qualcosa come la divisione del testo in token), c'è molto standard. Certamente posso fare tutto da solo - ho molta familiarità con AMQP e code e tutto il resto - e avvolgo tutto in un pacchetto comune condiviso da tutti i componenti, ma poi sono già sulla strada per inventare un framework.

Esiste un buon quadro per questo tipo di cose?

Nota che ti sto chiedendo specificamente di Go. Voglio evitare Hadoop e l'intero stack Java.

Modifica: sono stati aggiunti alcuni punti per maggiore chiarezza.

risposta

0

Immagino che stiate cercando una coda di messaggi, come beanstalkd, RabbitMQ, o ØMQ (pronunciato zero-MQ). L'essenza di tutti questi strumenti è che forniscono metodi push/receive per le code FIFO (o non FIFO) e alcuni addirittura hanno pub/sub.

Quindi, un componente mette i dati in una coda e un altro legge. Questo approccio è molto flessibile nell'aggiunta o rimozione di componenti e nel ridimensionamento di ciascuno di essi su o giù.

La maggior parte di questi strumenti dispone già di librerie per Go (ØMQ è molto popolare tra i Gopher) e altre lingue, quindi il tuo codice di sicurezza è molto piccolo. Basta importare una libreria e iniziare a ricevere e spingere i messaggi.

E per ridurre questo sovraccarico ed evitare la dipendenza da una particolare API, puoi scrivere un pacchetto sottile del tuo che utilizza uno di questi sistemi di code messaggi per fornire chiamate push/ricevere molto semplici e utilizzare questo pacchetto in tutti i tuoi strumenti .

+0

Apprezzo la risposta, ma praticamente hai semplicemente ripetuto quello che ho scritto nella mia domanda. AMQP è quello che sto prendendo in considerazione, e ho familiarità con le code, ma non sono felice di dover scrivere tutto da solo. Ad esempio, ogni "componente" deve eseguire un certo numero di lavoratori paralleli (goroutine o processi biforcati); gestire questi lavoratori, consentendo al numero di lavoratori di scalare in modo dinamico, e così via, è qualcosa che ogni componente dovrà avere, quindi deve essere trasformato in un aiuto comune. –

+0

@AlexanderStaubo vedo. Ci scusiamo per la risposta ingenua allora. Non sono a conoscenza di cose del genere per Go, ad eccezione di ciò che [Iron.io] (http://www.iron.io) offre con i suoi servizi Worker e MQ. – Mostafa

0

Capisco che si desidera evitare Hadoop + Java, ma invece di passare il tempo a sviluppare il proprio framework, è possibile dare un'occhiata a Cascading. Fornisce uno strato di astrazione su lavori MapReduce sottostanti.

Best summarized on Wikipedia, It [CSS] segue un 'fonte-pipe-sink' paradigma, dove i dati vengono acquisiti da fonti, segue 'tubi' riutilizzabili che eseguono dati processi di analisi, dove i risultati sono memorizzati nel file di output o "lavandini". I pipe vengono creati indipendentemente dai dati che elaboreranno. Una volta legato a fonti e sink di dati, è chiamato "flusso". Questi flussi possono essere raggruppati in una "cascata" e lo scheduler dei processi assicurerà che un dato flusso non venga eseguito fino a quando tutte le sue dipendenze non saranno soddisfatte. Tubi e flussi possono essere riutilizzati e riordinati per supportare le diverse esigenze aziendali.

Si consiglia inoltre di avere uno sguardo ad alcuni dei loro esempi, Log Parser, Log Analysis, TF-IDF (soprattutto this flow diagram).

+0

Grazie, ma questa domanda riguarda Go. –

1

Poiché Go ha canali CSP, suggerisco che Go offre un'opportunità speciale per implementare un framework per il parallelismo che sia semplice, conciso e tuttavia completamente generale. Dovrebbe essere possibile fare piuttosto meglio della maggior parte dei quadri esistenti con un codice un po 'meno. Java e JVM non possono avere nulla di simile.

Richiede solo l'implementazione dei canali utilizzando i trasporti TCP configurabili.Ciò consisterebbe

  • un'API scrittura canale-end, tra cui alcuni specificazione generale del server destinati fine lettura
  • una lettura canale-end API, compreso l'ascolto configurazione della porta e il supporto per select
  • smistamento unmarshalling colla per trasferire i dati/- probabilmente encoding/gob

un successo l'accettazione di prova di un tale quadro dovrebbe essere che un programma utilizzando i canali deve essere divisibile tra più processori e ancora r etain lo stesso comportamento funzionale (anche se le prestazioni sono diverse).

Ci sono quite a few progetti di rete a livello di trasporto esistenti in Go. Notevole è ZeroMQ (0MQ) (gozmq, zmq2, zmq3).

+0

Sono d'accordo. Alla fine ho deciso di scrivere un quadro semplice per fare ciò di cui ho bisogno; Pubblicherò presto un link Github al progetto nel caso in cui qualcun altro fosse interessato e forse volesse dare una mano. –

Problemi correlati