Il modo più veloce per mantenere un flusso di eventi ordinato solo per l'append

1

Sto cercando di mantenere un flusso di eventi e voglio che sia:

  • veloce in termini di latenza e velocità effettiva, con almeno 100.000 eventi al secondo
  • ordinato (non per data / ora, poiché è necessario ordinare in modo coerente più eventi nello stesso millisecondo)
  • per gli eventi inviati da un singolo thread, devono essere persistenti nell'ordine in cui vengono inviati
  • replicato / in grado di fallire in qualche modo

Le mie opzioni sembrano essere:

  1. Aggiungi un file e invialo a un altro server che aggiunge anche un file, in attesa di una risposta prima di considerarlo persistente
  2. Utilizzare un database che consideri qualcosa di permanente una volta che una richiesta è stata restituita da due nodi

Quale è più veloce? Quali sono i migliori database da utilizzare per l'opzione 2?

    
posta ocf1 25.07.2018 - 23:41
fonte

1 risposta

1

In primo luogo, anziché reinventare la ruota, dovresti almeno considerare un sistema di streaming / q di eventi esistente, come

  • link
  • o link
  • o MongoDB (con la sua funzione di replica) direttamente.

In secondo luogo, se hai bisogno di fare qualcosa di simile, e quelle soluzioni non sono abbastanza veloci (o hanno qualche altro difetto) - sei quasi sicuro che il più veloce che puoi fare è accodare a un file (o più direi che la soluzione sarà probabilmente limitata da I / O su disco.

Il bit sull'invio sulla rete può essere più veloce o più veloce, ma non a lungo termine, dato che deve essere scritto anche su un file. L'unico modo per sconfiggerlo è dividere il contenuto su più macchine (quindi nessuna macchina contiene TUTTI i dati).

Se hai bisogno della ridondanza di più copie su più computer e ti preoccupi veramente delle prestazioni, potresti pensare a un protocollo basato su UDP (con logica di ripristino ovviamente) per la condivisione dei dati, poiché TCP può facilmente rallentare la condivisione piuttosto bit.

Nota: UDP può essere MOLTO più veloce del TCP diretto (quindi quindi più veloce di HTTP), perché puoi creare tentativi e ACK direttamente nel tuo protocollo. E perché puoi utilizzare MULTICAST per ridurre notevolmente l'utilizzo della larghezza di banda della tua rete.

Una cosa SEMPLICE da implementare con cui si può iniziare è scrivere un programma 'tee', quindi prendere il flusso di input degli eventi e dividere i dati tra alcuni gruppi di server N downstream (non ha IO disco stesso), quindi contare su quei server downstream per scrivere sul disco.

Quindi lo splitter può iniettare contatori di sequenza fornendo un ordine totale sugli eventi.

Quindi, se vuoi essere attraente, assicurati che il tuo ACK del protocollo abbia ricevuto correttamente gli eventi e quando ricevi abbastanza ACKS (per un dato evento) - smetti di inviarlo di nuovo. In questo modo, puoi probabilmente evitare assolutamente di inviare nuovamente un pacchetto, anche se alcuni vengono rilasciati.

E puoi utilizzare MUTLICAST per inviare i tuoi pacchetti UDP, riducendo notevolmente la larghezza di banda della tua rete.

Quindi i server downstream potrebbero (a seconda del livello di tolleranza per la perdita di dati in caso di arresto anomalo) - potrebbero raggruppare centinaia o migliaia di messaggi, comprimerli e scriverli in un singolo file su disco. (La compressione può dare un notevole incremento delle prestazioni poiché si inviano molti meno dati sul disco e la struttura dei record degli eventi è spesso abbastanza comprimibile).

Tutti insieme, è possibile utilizzare MOLTA meno larghezza di banda della rete inviando i propri dati ai server di scrittura helper di quanto si sarebbe dovuto inviare inviando la scala tramite TCP (HTTP). Ed è possibile ottenere il numero di copie di ciascun evento scritto su un numero di server downstream. Usa la compressione per limitare l'IO del disco (e possibilmente anche della rete). E tu hai una soluzione abbastanza efficiente.

    
risposta data 26.07.2018 - 02:33
fonte

Leggi altre domande sui tag