Implementazione di un servizio distribuito n-Produttori / 1-Consumatore per il sistema di missione critica
Sto cercando di implementare una versione distribuita di multi-produttore / 1-consumatore per un sistema di missione critica. Sto cercando buone alternative all'attuale approccio basato su RDBMS.

Il problema
Il sistema è composto da serveral (50+) produttori che producono continuamente migliaia di istanze al secondo. Ogni istanza è una struttura piatta, ben definita, con timestamp. Ogni istanza viene archiviata in una singola coda dai produttori.
Dall'altro lato, ho un consumatore che consuma le istanze in modo FIFO.
Produttori e consumatore vengono eseguiti su macchine diverse collegate da una rete privata TCP / IP.
Per ragioni di completezza, ci sono due requisiti forti
- Il consumatore non può consumare due volte la stessa risorsa. È un errore.
- Ogni risorsa deve essere consumata dal consumatore. Se una risorsa viene persa, è una perdita
Inoltre, la soluzione deve essere eseguita su server Linux e Windows.
Approccio attuale
Nella versione attuale, il sistema implementa questa soluzione utilizzando un database relazionale come bus dati.

C'è un server database che supporta tutti i produttori e il consumatore. I produttori inseriscono le risorse in una determinata tabella e il consumatore consuma le risorse da quella tabella come rappresentato nell'immagine sopra.
Il modello di transazione server database / JDBC consente di controllare gli inserimenti / eliminazioni per evitare il danneggiamento della coda.
Questo approccio attuale funziona bene ma:
- Introduce l'overhead di mantenere un intero server di database relazionale per un'attività in cui non è richiesta alcuna relazione di dati;
- Il server di database relazionale deve adattarsi ai requisiti della missione critica, cosa difficile da ottenere su alcune impostazioni reali quando l'istanza del server di database non è dedicata
Alternative
Qui sto elencando alcune alternative all'attuale approccio al bus di dati del server di database relazionale:
Dedicare un server di database relazionale leggero
Questo sembra essere l'approccio più semplice: utilizzare un server di database relazionale leggero e dedicato come HSQLDB, Apache Derby o H2.
Professionisti
Hanno un overhead notevolmente inferiore da mantenere rispetto a un RDBMS come MS SQL Server, Oracle DB Server o persino MySQL. Inoltre, sono necessarie meno modifiche al codice e test poiché sono fondamentalmente motori SQL come quelli utilizzati nella soluzione corrente.
Contro
Sono server di database relazionali, quindi risulta che esiste ancora un certo livello di overhead per eseguire un'attività senza relazioni. Un altro punto è l'aspetto critico della missione. Usiamo Derby DB internamente da secoli per la supervisione del sistema in tempo reale sia in modalità embedded che di rete. Funziona alla grande, né crash né danneggiamento dei dati. Tuttavia, il volume di transazioni / sec per quel nuovo utilizzo è maggiore.
Server Redis
A prima vista, Redis sembra perfetto per questo caso d'uso. In memoria, veloce, senza overhad per la relazione dei dati, semplice. Ampiamente utilizzato come bus di dati e segnalato come affidabile. Ma non per Windows. Come detto nei documenti, Redis su Windows non è consigliato . Il port di Microsoft Windows non è più mantenuto , l'ultima data di rilascio è 2016, quindi allegare Redis al sistema non sembra promettere bene.
Implementare una soluzione da zero
In definitiva, è un problema produttore-consumatore. L'implementazione di un servizio di rete utilizzando TCP o qualcosa di più elegante come Camel e utilizzando la coda concorrente internamente oltre a un motore di persistenza locale sarà costoso in termini di tempo, reinventare la ruota ma è ancora un'opzione.
Queste sono le alternative che stiamo considerando finora. Apprezzo se qualcuno può fornire suggerimenti o consigli.
Risposte
Sembra che tu stia cercando una coda di messaggi. A seconda del tuo stack tecnologico, ci sono varie implementazioni di coda distribuita che potrebbero interessarti, ad esempio ZeroMQ o RabbitMQ.
Alcuni approcci come ZeroMQ possono essere eseguiti senza avere un broker di messaggi, il che significa che i produttori ei consumatori parlano direttamente senza bisogno di un altro servizio o di un database per orchestrare / mediare la coda. Essere senza broker ha il vantaggio di essere molto più semplice da gestire operativamente rispetto a code di messaggi mediate, ed essere più semplice da capire, scalare e personalizzare, ma lo svantaggio principale è che manca dei servizi solitamente forniti dai broker, quindi se un partecipante è offline, i messaggi potrebbero andare persi. Se è necessario che il messaggio venga elaborato in modo affidabile, è necessario progettare i produttori in modo che siano in grado di gestire il tentativo di invio se il consumatore non è disponibile, sarà necessario aggiungere un meccanismo per il riconoscimento della consegna riuscita e essere progettato per essere idempotente (essere in grado di rilevare messaggi duplicati e scartarli). Il vantaggio principale di essere senza broker è che sei libero di implementare il comportamento del broker tanto o meno quanto la tua applicazione ha bisogno, quindi non sei legato a uno specifico comportamento del broker.
Una coda di messaggi mediata come RabbitMQ è in qualche modo più semplice durante l'uso, poiché il broker aggiunge un livello di persistenza e affidabilità della messaggistica alla struttura del sistema di code piuttosto che richiedere al produttore e ai consumatori di implementarli, ma aggiunge la complessità e il sovraccarico della gestione del broker e il broker aggiunge latenza, quindi potrebbe non essere adatto per scenari in cui i millisecondi sono importanti o in cui il livello di scalabilità target supera quello che si può ottenere in un sistema mediato.
esiste ancora un certo livello di overhead per eseguire un'attività senza relazioni
Ti suggerisco di profilare la tua applicazione per scoprire effettivamente se è davvero importante o meno. È probabile che se un database SQL in-process non è sufficiente per un'applicazione non simultanea, è molto probabile che lo si utilizzi in modo inefficiente, piuttosto che a causa di problemi di prestazioni nella gestione delle relazioni stesse.