Come guardare negli occhi di Cassandra senza perdere dati, stabilità e fiducia in NoSQL

Come guardare negli occhi di Cassandra senza perdere dati, stabilità e fiducia in NoSQL

Si dice che nella vita vale la pena provare tutto almeno una volta. E se sei abituato a lavorare con database relazionali, vale la pena provare nella pratica NoSQL, almeno per una crescita personale. Attualmente, a causa dello sviluppo vorticoso di questa tecnologia, ci sono molte opinioni contrastanti e accesi dibattiti su questo tema, il che alimenta ulteriormente l'interesse.
Se si esamina il cuore di tutti questi dibattiti, si può notare che sorgono a causa di un approccio errato. Coloro che utilizzano i database NoSQL proprio dove sono necessari sono soddisfatti e ottengono tutti i vantaggi di questa soluzione. Gli sperimentatori, che si affidano a questa tecnologia come panacea dove non è affatto applicabile, provano delusione, perdendo i punti di forza dei database relazionali senza acquisire vantaggi significativi.

Racconterò della nostra esperienza nell'implementazione di una soluzione basata sul database Cassandra: quali sfide abbiamo affrontato, come ci siamo districati da situazioni difficili, se siamo riusciti a ottenere un vantaggio dall'utilizzo di NoSQL e dove abbiamo dovuto investire sforzi/risorse aggiuntive.
L'obiettivo iniziale è costruire un sistema che registri le chiamate in un certo archivio.

Il principio di funzionamento del sistema è il seguente. I file in entrata hanno una struttura specifica che descrive la tipologia della chiamata. Successivamente, l'applicazione garantisce il salvataggio di questa struttura nelle colonne appropriate. Le chiamate salvate vengono quindi utilizzate per visualizzare informazioni sul consumo di traffico per gli abbonati (addebiti, chiamate, storia del saldo).

Come guardare negli occhi di Cassandra senza perdere dati, stabilità e fiducia in NoSQL

Perché abbiamo scelto Cassandra è abbastanza chiaro: scrive come una mitragliatrice, è facilmente scalabile e resistente ai guasti.

Quindi, ecco cosa ci ha insegnato l'esperienza.

Sì, una nodo che va giù non è una tragedia. Questo è il punto della tolleranza ai guasti di Cassandra. Ma una nodo può essere attiva e allo stesso tempo iniziare a calare in termini di prestazioni.Come si è scoperto, questo si riflette immediatamente sulle prestazioni dell'intero cluster.

Cassandra non offre le stesse garanzie di Oracle con i suoi vincoli.E se l'autore dell'applicazione non lo ha capito in anticipo, un duplicato che arriva per Cassandra non è affatto inferiore all'originale. Se è arrivato, lo inseriamo.

La versione gratuita di Cassandra 'out of the box' non è piaciuta ai professionisti della sicurezza: non ci sono registrazioni delle azioni degli utenti, né limitazioni dei diritti.. Le informazioni sulle chiamate riguardano i dati personali, il che significa che ogni tentativo di richiederli o modificarli deve essere registrato con la possibilità di audit successivi. Inoltre, è necessario essere consapevoli della necessità di separare i diritti a diversi livelli per diversi utenti. Un semplice ingegnere operativo e un super amministratore, che può liberamente eliminare l'intero keyspace, sono ruoli diversi, con responsabilità e competenze diverse. Senza tale distinzione dei diritti di accesso, il valore e l'integrità dei dati saranno messi in discussione più rapidamente rispetto a un livello di coerenza ANY.

Non abbiamo considerato che per le chiamate è necessaria sia un'analisi seria che campionamenti periodici in base a vari criteri. Poiché i record selezionati devono poi essere eliminati e riscritti (nell'ambito del compito dobbiamo supportare il processo di aggiornamento dei dati in seguito a dati inizialmente errati che ci sono stati forniti), Cassandra non è qui un alleato. Cassandra, come una cassaforte, è comoda per accumulare dati, ma non riesce a fare calcoli.

Ci siamo imbattuti in un problema di migrazione dei dati nelle aree di test. (5 nodi nel test contro 20 in produzione). In tal caso non sarà possibile utilizzare il dump.

Problema degli aggiornamenti dello schema dei dati dell'applicazione che scrive su Cassandra. Il rollback genererà un gran numero di tombstone, il che potrebbe in modo imprevedibile influire sulle prestazioni.. Cassandra è ottimizzata per la scrittura e, prima di scrivere, non pensa molto. Qualsiasi operazione sui dati esistenti in essa è anch'essa una scrittura. Cioè, eliminando il superfluo, generiamo solo un numero maggiore di scritture, e solo una parte di esse sarà contrassegnata come tombstone.

Timeout durante l'inserimento. Cassandra è ottima per la scrittura, ma a volte il flusso in ingresso può confonderla significativamente.. Questo accade quando l'applicazione inizia a ciclare su diversi record che non possono essere inseriti per qualche motivo. E avremo bisogno di un DBA vero e proprio, che controlli gc.log, i log system e debug per query lente, e le metriche di compaction pending.

Diverse aree geografiche nel cluster. Da dove leggere e dove scrivere?
È possibile separare la lettura dalla scrittura? E se sì, dovrebbe esserci un DC per la scrittura o per la lettura più vicino all'applicazione? E non rischiamo di trovarci in una vera e propria situazione di split brain se scegliamo impropriamente il livello di coerenza? Ci sono molte domande, molte impostazioni inesplorate, possibilità che vorremmo analizzare.

Come abbiamo risolto

Per evitare che il nodo si bloccasse, abbiamo disattivato il SWAP. E ora, in caso di mancanza di memoria, il nodo dovrebbe cadere, piuttosto che generare lunghe pause di garbage collection.

Quindi, non ci aspettiamo più logica nel database. Gli sviluppatori dell'applicazione stanno riqualificando e cominciano a proteggere attivamente il proprio codice. Un perfetto e chiaro separazione tra archiviazione e trattamento dei dati.

Abbiamo acquistato supporto da DataStax. La versione box di Cassandra non è più sviluppata (l'ultimo commit è stato nel febbraio 2018). Nel frattempo, DataStax offre un ottimo servizio e un'ampia gamma di soluzioni migliorate e adattate ai sistemi esistenti.

Voglio anche sottolineare che Cassandra non è molto pratica per le query di selezione. Ovviamente, CQL rappresenta un grande passo avanti per gli utenti (rispetto a Thrift). Ma se avete interi reparti abituati a giunture così comode, a una filtrazione libera su qualsiasi campo e a opportunità di ottimizzazione delle query, la soluzione basata su Cassandra appare per loro ostile e illogica. E abbiamo iniziato a risolvere il problema su come far eseguire le selezioni ai nostri colleghi.

Abbiamo considerato due opzioni. Nella prima opzione scriviamo le chiamate non solo in C*, ma anche nel database archiviato Oracle. Solo che, a differenza di C*, in questo database sono memorizzate solo le chiamate dell'attuale mese (profonità di memorizzazione sufficiente per i casi di riconfigurazione). Qui emerge subito il problema successivo: se scriviamo in modo sincrono, perdiamo tutti i vantaggi di C* riguardanti l'inserimento rapido; se in modo asincrono, non abbiamo garanzie che tutte le chiamate necessarie siano effettivamente arrivate in Oracle. C'era un vantaggio, ma grande: per l'uso rimane sempre il consueto PL/SQL Developer, quindi praticamente realizziamo il pattern 'Facciata'. Opzione alternativa. Implementiamo un meccanismo che estrae le chiamate da C*, recupera alcuni dati per arricchire da tabelle corrispondenti in Oracle, unisce i risultati ottenuti e ci fornisce il risultato ottenuto, che poi utilizziamo in qualche modo (annulliamo, ripetiamo, analizziamo, ammiriamo). Gli svantaggi: il processo risulta piuttosto a più fasi, e inoltre, non c'è un'interfaccia per il personale operativo.

Alla fine, ci siamo comunque fermati sulla seconda opzione. Per le estrazioni da diversi database abbiamo utilizzato Apache Spark. Essenza del meccanismo si è ridotta a codice Java, che estrae i dati da C* in base alle chiavi specificate (abbonato, ora della chiamata - chiavi della sezione) e i dati necessari per l'arricchimento da qualsiasi altro database. Dopodiché, li unisce nella propria memoria e restituisce il risultato nella tabella dei risultati. Abbiamo creato un'interfaccia web sopra Spark che è risultata abbastanza utilizzabile.

Come guardare negli occhi di Cassandra senza perdere dati, stabilità e fiducia in NoSQL

Nel risolvere il compito di aggiornamento dei dati, il team di prom-test ha nuovamente esaminato diverse opzioni. Sia la migrazione tramite Sstloader che la possibilità di suddividere il cluster nell'area di test in due parti, ciascuna delle quali viene alternata in un cluster con quello di prom, alimentandosi così da esso. Durante l'aggiornamento del test, era previsto il cambio di posto: la parte che lavorava nel test veniva pulita e immessa in prom, mentre l'altra iniziava a lavorare con i dati separatamente. Tuttavia, dopo aver riflettuto di nuovo, abbiamo valutato in modo più razionale quali dati valesse la pena trasferire e abbiamo capito che le chiamate di per sé sono un'entità non consistente per i test, rapidamente generata in caso di necessità, e che il set di dati di prom non ha valore per il trasferimento nel test. Ci sono diversi oggetti-accumulatori che vale la pena trasferire, ma sono letteralmente un paio di tabelle, non troppo pesanti. Pertanto, noi come soluzione, è tornato in aiuto Spark, grazie al quale abbiamo scritto e iniziato a utilizzare attivamente uno script per il trasferimento dei dati tra le tabelle prom-test.

La nostra attuale politica di deployment ci consente di lavorare senza rollback. Prima di prom, è previsto un obbligatorio caricamento su test, dove l'errore non è così costoso. In caso di fallimento, è sempre possibile eliminare il case space e ricaricare l'intero schema dall'inizio.

Per garantire la disponibilità continua di Cassandra è necessaria una DBA e non solo. Tutti coloro che lavorano con l'applicazione devono capire dove e come osservare la situazione corrente e come diagnosticare tempestivamente i problemi. Per questo motivo utilizziamo attivamente DataStax OpsCenter (Amministrazione e monitoraggio dei carichi di lavoro), metriche di sistema del driver Cassandra (numero di timeout in scrittura in C*, numero di timeout in lettura da C*, latenza massima, ecc.), monitoriamo il funzionamento dell'applicazione stessa che lavora con Cassandra.

Quando abbiamo considerato la domanda precedente, abbiamo capito dove potrebbe risiedere il rischio principale. Si tratta delle forme di visualizzazione dei dati che estraggono informazioni da più richieste indipendenti l'una dall'altra verso il data store. In questo modo, potremmo ottenere informazioni piuttosto incoerenti. Ma questo problema sarebbe stato altrettanto rilevante anche se avessimo lavorato solo con un data center. Quindi, la cosa più sensata da fare qui è, naturalmente, creare una funzione di lettura dei dati batch su un'applicazione esterna, che garantisca il recupero dei dati in un unico intervallo di tempo. Per quanto riguarda la divisione tra lettura e scrittura in termini di prestazioni, ci ha fermati il rischio che, in caso di perdita di connessione tra i DC, potremmo ottenere due cluster totalmente incoerenti tra loro.

Alla fine, attualmente ci siamo fermati a un livello di coerenza per la scrittura di EACH_QUORUM, per la lettura – LOCAL_QUORUM

Impressioni e conclusioni brevi

Per valutare la soluzione ottenuta dal punto di vista del supporto operativo e delle prospettive di sviluppo futuro, abbiamo deciso di riflettere su dove poter applicare ulteriormente tale sviluppo.

Se dovessi pensare in modo immediato, il punteggio dei dati per programmi come "Paga quando ti è comodo" (carichiamo in S* informazioni, calcolo su script Spark), gestione delle contestazioni con aggregazione per direzione, memorizzazione dei ruoli e calcolo secondo la matrice dei diritti di accesso degli utenti.

Come vediamo, il repertorio è ampio e vario. E se dovessimo scegliere il campo tra sostenitori e oppositori di NoSQL, ci uniremo ai sostenitori, poiché abbiamo ottenuto i nostri vantaggi, proprio lì dove ci aspettavamo.

Anche la versione di Cassandra out-of-the-box consente di effettuare scalabilità orizzontale in tempo reale, risolvendo in modo assolutamente indolore la questione dell'aumento dei dati nel sistema. Siamo riusciti a portare in un contesto separato un meccanismo ad alta intensità di carico per il calcolo degli aggregati sulle chiamate, e a separare schema e logica dell'applicazione, liberandoci dalla cattiva pratica di scrivere job personalizzati e oggetti nel database stesso. Abbiamo ottenuto la possibilità di scegliere e configurare, per accelerare, in quali DC eseguire il calcolo e in quali inserire i dati, mettendoci al riparo da possibili cadute di singoli nodi, così come in generale del DC.

Applicando la nostra architettura ai nuovi progetti, e avendo già qualche esperienza, vorremmo subito tenere conto delle sfumature descritte sopra e non commettere alcuni errori, smussare alcuni angoli acuti che non siamo riusciti ad evitare inizialmente.

Ad esempio, monitorare tempestivamente gli aggiornamenti della stessa Cassandra, poiché molti dei problemi che abbiamo affrontato erano già noti e sono stati corretti.

Non installare sia il DB che Spark sugli stessi nodi (o separare rigorosamente in base alla quantità consentita di utilizzo delle risorse), poiché Spark potrebbe consumare più RAM del consentito e potremmo rapidamente incontrare il problema numero 1 della nostra lista.

Potenziare il monitoraggio e le competenze operative già nella fase di test del progetto. Considerare fin da subito tutti i potenziali consumatori della nostra soluzione, poiché la struttura del DB alla fine dipenderà proprio da questo.

Rivedere più volte lo schema risultante per identificarne le possibili ottimizzazioni. Avere chiaro quali campi è possibile serializzare. Comprendere quali tabelle aggiuntive dobbiamo creare per considerare e restituire in modo corretto e ottimale le informazioni richieste (ad esempio, considerando che gli stessi dati possono essere memorizzati in diverse tabelle, tenendo conto di suddivisioni differenti in base a vari criteri, possiamo risparmiare notevolmente tempo della CPU durante le richieste di lettura).

Bene prevedere fin da subito l'aggiunta di TTL e la pulizia dei dati obsoleti.

Durante l'esportazione dei dati da Cassandra la logica dell'applicazione deve funzionare secondo il principio FETCH, in modo che non tutte le righe vengano caricate in memoria in una sola volta, ma vengano selezionate a blocchi.

È preferibile verificare la resilienza del sistema prima di passare al sistema descritto effettuando una serie di test di crash, come la perdita di dati in un data center, il ripristino di dati danneggiati su un certo periodo, e il degrado della rete tra i data center. Tali test non solo consentiranno di valutare i pro e i contro dell'architettura proposta, ma forniranno anche una buona pratica per ingegneri che li eseguono, e le competenze acquisite non saranno affatto superflue in caso di guasti del sistema che si verifichino in produzione.

Se lavoriamo con informazioni critiche (come dati per la fatturazione, calcolo del debito del cliente), è importante prestare attenzione agli strumenti che possono ridurre i rischi derivanti dalle peculiarità del DBMS. Ad esempio, utilizzare l'utility nodesync (Datastax) sviluppando una strategia ottimale per il suo utilizzo, in modo da non generare un carico eccessivo su Cassandra per garantire la consistenza e utilizzarla solo per determinate tabelle in determinati periodi.

E così, dopo sei mesi di esperienza con Cassandra? In generale, non ci sono problemi irrisolti. Non abbiamo avuto gravi guasti o perdite di dati. Sì, abbiamo dovuto riflettere sulla compensazione di alcuni problemi che non si erano mai verificati prima, ma alla fine questo non ha in alcun modo influenzato la nostra soluzione architettonica. Se vuoi e non temi di provare qualcosa di nuovo, e non vuoi deluderti troppo, preparati al fatto che nulla è gratis. Dovrai dedicarti a studiare, approfondire la documentazione e costruire le tue

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster