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

Dicono che tutto nella vita vale la pena provare almeno una volta. E se sei abituato a lavorare con DBMS relazionali, allora vale la pena conoscere NoSQL nella pratica, prima di tutto, almeno per lo sviluppo generale. Ora, a causa del rapido sviluppo di questa tecnologia, ci sono molte opinioni contrastanti e accesi dibattiti su questo argomento, che alimentano soprattutto l'interesse.
Se approfondisci l'essenza di tutte queste controversie, puoi vedere che sorgono a causa dell'approccio sbagliato. Chi utilizza i database NoSQL esattamente dove serve si ritiene soddisfatto e riceve tutti i vantaggi da questa soluzione. E gli sperimentatori che si affidano a questa tecnologia come una panacea laddove non è affatto applicabile rimangono delusi, avendo perso i punti di forza dei database relazionali senza ottenere vantaggi significativi.

Vi racconterò la nostra esperienza nell'implementazione di una soluzione basata sul DBMS Cassandra: cosa abbiamo dovuto affrontare, come siamo usciti da situazioni difficili, se siamo riusciti a trarre vantaggio dall'utilizzo di NoSQL e dove abbiamo dovuto investire ulteriori sforzi/fondi .
Il compito iniziale è costruire un sistema che registri le chiamate in una sorta di archivio.

Il principio di funzionamento del sistema è il seguente. L'input include file con una struttura specifica che descrive la struttura della chiamata. L'applicazione garantisce quindi che questa struttura venga archiviata nelle colonne appropriate. In futuro, le chiamate salvate verranno utilizzate per visualizzare informazioni sul consumo di traffico per gli abbonati (addebiti, chiamate, storico del saldo).

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

È abbastanza chiaro il motivo per cui hanno scelto Cassandra: scrive come una mitragliatrice, è facilmente scalabile e tollerante ai guasti.

Quindi, questo è ciò che l’esperienza ci ha dato

Sì, un nodo guasto non è una tragedia. Questa è l'essenza della tolleranza agli errori di Cassandra. Ma un nodo può essere vivo e allo stesso tempo iniziare a soffrire in termini di prestazioni. Come si è scoperto, ciò influisce immediatamente sulle prestazioni dell'intero cluster.

Cassandra non ti proteggerà laddove Oracle ti ha salvato con i suoi vincoli. E se l'autore della domanda non lo ha capito in anticipo, allora il doppio arrivato a Cassandra non è peggiore dell'originale. Una volta arrivato, lo inseriremo.

IB ha fortemente detestato la Cassandra libera fuori dagli schemi: Non esiste alcuna registrazione delle azioni dell'utente, nessuna differenziazione dei diritti. Le informazioni relative alle chiamate sono considerate dati personali, ciò significa che ogni tentativo di richiederle/modificarle in qualsiasi modo dovrà essere registrato con possibilità di successivo controllo. Inoltre, è necessario essere consapevoli della necessità di separare i diritti a diversi livelli per i diversi utenti. Un semplice tecnico operativo e un super amministratore che può eliminare liberamente l'intero spazio delle chiavi sono ruoli, responsabilità e competenze diverse. Senza tale differenziazione dei diritti di accesso, il valore e l’integrità dei dati verranno immediatamente messi in discussione più velocemente che con il livello di coerenza ANY.

Non abbiamo tenuto conto del fatto che le chiamate richiedono sia un’analisi seria che un campionamento periodico per una varietà di condizioni. Poiché i record selezionati dovrebbero poi essere cancellati e riscritti (come parte dell'attività, dobbiamo supportare il processo di aggiornamento dei dati quando i dati inizialmente sono entrati nel nostro ciclo in modo errato), Cassandra non è nostra amica qui. Cassandra è come un salvadanaio: è comodo mettere le cose dentro, ma non puoi contarci.

Abbiamo riscontrato un problema durante il trasferimento dei dati alle zone di test (5 nodi nel test contro 20 nel ballo di fine anno). In questo caso non è possibile utilizzare il dump.

Il problema con l'aggiornamento dello schema dei dati di un'applicazione che scrive su Cassandra. Un rollback genererà un gran numero di pietre tombali, che possono portare a perdite di produttività in modi imprevedibili.. Cassandra è ottimizzata per la registrazione e non pensa molto prima di scrivere. Anche qualsiasi operazione con dati esistenti è una registrazione. Cioè, eliminando ciò che non è necessario, produrremo semplicemente ancora più record e solo alcuni di essi saranno contrassegnati con lapidi.

Timeout durante l'inserimento. Cassandra è bellissima nella registrazione, ma a volte il flusso in arrivo può lasciarla perplessa in modo significativo. Ciò accade quando l'applicazione inizia a scorrere diversi record che non possono essere inseriti per qualche motivo. E avremo bisogno di un vero DBA che monitorerà gc.log, i log di sistema e di debug per query lente e metriche sulla compattazione in sospeso.

Diversi data center in un cluster. Da dove leggere e dove scrivere?
Forse diviso in lettura e scrittura? E se sì, dovrebbe esserci un DC più vicino all'applicazione per la scrittura o la lettura? E non ci ritroveremo con un vero e proprio cervello diviso se scegliamo il livello di coerenza sbagliato? Ci sono molte domande, molte impostazioni sconosciute, possibilità con cui vuoi davvero armeggiare.

Come abbiamo deciso

Per evitare che il nodo affondasse, SWAP è stato disabilitato. E ora, se manca memoria, il nodo dovrebbe abbassarsi e non creare grandi pause gc.

Pertanto, non facciamo più affidamento sulla logica del database. Gli sviluppatori di applicazioni si stanno riqualificando e stanno iniziando a prendere attivamente precauzioni nel proprio codice. Separazione chiara e ideale tra archiviazione ed elaborazione dei dati.

Abbiamo acquistato il supporto da DataStax. Lo sviluppo di Cassandra in scatola è già cessato (l'ultimo impegno è avvenuto a febbraio 2018). Allo stesso tempo, Datastax offre un servizio eccellente e un gran numero di soluzioni modificate e adattate per le soluzioni IP esistenti.

Voglio anche sottolineare che Cassandra non è molto comoda per le query di selezione. Naturalmente CQL rappresenta un grande passo avanti per gli utenti (rispetto a Trift). Ma se hai interi dipartimenti abituati a join così convenienti, filtraggio gratuito per qualsiasi campo e funzionalità di ottimizzazione delle query, e questi dipartimenti stanno lavorando per risolvere reclami e incidenti, allora la soluzione su Cassandra sembra loro ostile e stupida. E abbiamo iniziato a decidere come i nostri colleghi avrebbero dovuto realizzare i campioni.

Abbiamo considerato due opzioni: nella prima opzione, scriviamo le chiamate non solo in C*, ma anche nel database Oracle archiviato. Solo che, a differenza di C*, questo database memorizza le chiamate solo per il mese corrente (profondità di memorizzazione delle chiamate sufficiente per i casi di ricarica). Qui abbiamo subito riscontrato il seguente problema: se scriviamo in modo sincrono, perdiamo tutti i vantaggi del C* associati all'inserimento rapido, se scriviamo in modo asincrono non vi è alcuna garanzia che tutte le chiamate necessarie arrivino in Oracle. C'era un vantaggio, ma grosso: per il funzionamento rimane lo stesso familiare PL/SQL Developer, cioè praticamente implementiamo il modello "Facade", un'opzione alternativa. Implementiamo un meccanismo che scarica le chiamate da C*, estrae alcuni dati per l'arricchimento dalle tabelle corrispondenti in Oracle, unisce i campioni risultanti e ci fornisce il risultato, che poi in qualche modo utilizziamo (rollback, ripetizione, analisi, ammirazione). Contro: il processo è piuttosto articolato in più fasi e inoltre non esiste un'interfaccia per i dipendenti operativi.

Alla fine abbiamo optato per la seconda opzione. Apache Spark è stato utilizzato per campionare da vasetti diversi. L'essenza del meccanismo è stata ridotta al codice Java che, utilizzando le chiavi specificate (abbonato, ora della chiamata - chiavi della sezione), estrae i dati da C*, nonché i dati necessari per l'arricchimento da qualsiasi altro database. Dopodiché li unisce nella sua memoria e visualizza il risultato nella tabella risultante. Abbiamo disegnato una faccia di ragnatela sulla scintilla e si è rivelata abbastanza utilizzabile.

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

Nel risolvere il problema dell'aggiornamento dei dati dei test industriali, abbiamo considerato ancora una volta diverse soluzioni. Entrambi i trasferimenti tramite Sstloader e la possibilità di dividere il cluster nella zona test in due parti, ciascuna delle quali appartiene alternativamente allo stesso cluster con quello promozionale, essendone quindi alimentata. Durante l'aggiornamento del test, è stato pianificato di scambiarli: la parte che ha funzionato nel test viene cancellata ed entrata in produzione, e l'altra inizia a lavorare con i dati separatamente. Tuttavia, dopo averci ripensato, abbiamo valutato in modo più razionale i dati che valeva la pena trasferire e ci siamo resi conto che le chiamate stesse sono un'entità incoerente per i test, generati rapidamente se necessario, e che è il set di dati promozionali che non ha alcun valore per il trasferimento al test. Esistono diversi oggetti di archiviazione che vale la pena spostare, ma si tratta letteralmente di un paio di tavoli e non molto pesanti. Pertanto noi come soluzione, Spark è venuto di nuovo in soccorso, con l'aiuto del quale abbiamo scritto e iniziato a utilizzare attivamente uno script per il trasferimento di dati tra tabelle, prom-test.

La nostra attuale politica di distribuzione ci consente di lavorare senza rollback. Prima della promozione c'è un giro di prova obbligatorio, dove un errore non è così costoso. In caso di fallimento, puoi sempre abbandonare il casespace e ripetere l'intero schema dall'inizio.

Per garantire una disponibilità continuativa a Cassandra serve un dba e non solo lui. Chiunque lavori con l'applicazione deve capire dove e come guardare la situazione attuale e come diagnosticare i problemi in modo tempestivo. Per fare ciò, utilizziamo attivamente DataStax OpsCenter (amministrazione e monitoraggio dei carichi di lavoro), metriche di sistema Cassandra Driver (numero di timeout per la scrittura su C*, numero di timeout per la lettura da C*, latenza massima, ecc.), monitoriamo l'operazione dell'applicazione stessa, collaborando con Cassandra.

Quando abbiamo pensato alla domanda precedente, abbiamo capito dove potrebbe risiedere il nostro rischio principale. Si tratta di moduli di visualizzazione dati che visualizzano i dati provenienti da diverse query indipendenti nell'archivio. In questo modo possiamo ottenere informazioni abbastanza incoerenti. Ma questo problema sarebbe altrettanto rilevante se lavorassimo con un solo data center. Quindi la cosa più ragionevole qui è, ovviamente, creare una funzione batch per leggere i dati su un'applicazione di terze parti, che garantirà che i dati vengano ricevuti in un unico periodo di tempo. Per quanto riguarda la divisione in lettura e scrittura in termini di prestazioni, qui siamo stati fermati dal rischio che con qualche perdita di connessione tra i DC potremmo ritrovarci con due cluster completamente incoerenti tra loro.

Di conseguenza, per ora arrestato al livello di coerenza per la scrittura EACH_QUORUM, per la lettura - LOCAL_QUORUM

Brevi impressioni e conclusioni

Per valutare la soluzione risultante dal punto di vista del supporto operativo e delle prospettive di ulteriore sviluppo, abbiamo deciso di pensare a dove altro potrebbe essere applicato tale sviluppo.

Subito dopo, poi scoring dei dati per programmi come “Paga quando conviene” (carichiamo le informazioni in C*, calcoliamo tramite script Spark), contabilizzazione dei sinistri con aggregazione per area, memorizzazione dei ruoli e calcolo dei diritti di accesso degli utenti in base al ruolo matrice.

Come potete vedere, il repertorio è ampio e vario. E se scegliamo il campo dei sostenitori/avversari di NoSQL, allora ci uniremo ai sostenitori, poiché abbiamo ricevuto i nostri vantaggi, ed esattamente dove ci aspettavamo.

Anche l'opzione Cassandra pronta all'uso consente il ridimensionamento orizzontale in tempo reale, risolvendo in modo assolutamente indolore il problema dell'aumento dei dati nel sistema. Siamo stati in grado di spostare un meccanismo a carico molto elevato per il calcolo degli aggregati di chiamate in un circuito separato e anche di separare lo schema e la logica dell'applicazione, eliminando la cattiva pratica di scrivere lavori e oggetti personalizzati nel database stesso. Abbiamo avuto la possibilità di scegliere e configurare, per velocizzare, su quali DC eseguiremo i calcoli e su quali registreremo i dati, ci siamo assicurati contro i crash sia dei singoli nodi che del DC nel suo insieme.

Applicando la nostra architettura a nuovi progetti, e avendo già una certa esperienza, vorrei tenere immediatamente conto delle sfumature sopra descritte e prevenire alcuni errori, smussare alcuni angoli acuti che inizialmente non potevano essere evitati.

Per esempio, tieni traccia degli aggiornamenti di Cassandra in modo tempestivoperché molti dei problemi che abbiamo riscontrato erano già noti e risolti.

Non inserire sia il database stesso che Spark sugli stessi nodi (o dividere rigorosamente per la quantità di utilizzo consentito delle risorse), poiché Spark può consumare più OP del previsto e otterremo rapidamente il problema numero 1 dal nostro elenco.

Migliorare il monitoraggio e la competenza operativa nella fase di test del progetto. Inizialmente, prendi in considerazione il più possibile tutti i potenziali consumatori della nostra soluzione, perché è da questo che dipenderà in definitiva la struttura del database.

Ruotare più volte il circuito risultante per un'eventuale ottimizzazione. Seleziona quali campi possono essere serializzati. Capire quali tabelle aggiuntive dovremmo creare per tenerne conto nel modo più corretto e ottimale, per poi fornire le informazioni richieste su richiesta (ad esempio, supponendo di poter memorizzare gli stessi dati in tabelle diverse, tenendo conto di disaggregazioni diverse a seconda criteri diversi, possiamo risparmiare notevolmente tempo CPU per le richieste di lettura).

Media Provvedere immediatamente ad allegare TTL e pulire i dati obsoleti.

Durante il download dei dati da Cassandra La logica dell'applicazione dovrebbe funzionare secondo il principio FETCH, in modo che non tutte le righe vengano caricate in memoria contemporaneamente, ma vengano selezionate in batch.

Si consiglia prima di trasferire il progetto alla soluzione descritta verificare la tolleranza agli errori del sistema eseguendo una serie di crash test, come la perdita di dati in un data center, il ripristino di dati danneggiati per un certo periodo, l'interruzione della rete tra data center. Tali test consentiranno non solo di valutare i pro e i contro dell’architettura proposta, ma forniranno anche una buona pratica di riscaldamento per gli ingegneri che li condurranno, e l’abilità acquisita sarà tutt’altro che superflua se i guasti del sistema vengono riprodotti in produzione.

Se lavoriamo con informazioni critiche (come dati per la fatturazione, calcolo del debito dell'abbonato), vale anche la pena prestare attenzione agli strumenti che ridurranno i rischi derivanti dalle caratteristiche del DBMS. Ad esempio, utilizzare l'utilità nodesync (Datastax), avendo sviluppato in ordine una strategia ottimale per il suo utilizzo per motivi di coerenza, non creare un carico eccessivo su Cassandra e utilizzarlo solo per determinate tabelle in un determinato periodo.

Cosa succede a Cassandra dopo sei mesi di vita? In generale, non ci sono problemi irrisolti. Inoltre, non abbiamo consentito alcun incidente grave o perdita di dati. Sì, abbiamo dovuto pensare a compensare alcuni problemi che prima non si erano presentati, ma alla fine questo non ha offuscato molto la nostra soluzione architetturale. Se vuoi e non hai paura di provare qualcosa di nuovo, e allo stesso tempo non vuoi essere troppo deluso, preparati al fatto che nulla è gratis. Dovrai capire, approfondire la documentazione e assemblare il tuo rastrello individuale più che nella vecchia soluzione legacy, e nessuna teoria ti dirà in anticipo quale rastrello ti sta aspettando.

Fonte: habr.com

Aggiungi un commento