
Nonostante l'abbondanza di dati ovunque, i DBMS analitici rimangono ancora piuttosto esotici. Sono poco conosciuti e ancora meno utilizzati in modo efficace. Molti continuano a "mangiare il cactus" con MySQL o PostgreSQL, progettati per altri scenari, a lottare con NoSQL o a pagare eccessivamente per soluzioni commerciali. ClickHouse cambia le regole del gioco e abbassa significativamente la barriera d'ingresso nel mondo dei DBMS analitici.
Relazione dal BackEnd Conf 2018 e pubblicata con il permesso del relatore.


Chi sono e perché parlo di ClickHouse? Sono il Direttore Sviluppo di LifeStreet, che utilizza ClickHouse. Inoltre, sono il fondatore di Altinity, partner di Yandex, che promuove ClickHouse e aiuta Yandex a rendere ClickHouse ancora più di successo. Sono anche disponibile a condividere conoscenze su ClickHouse.

E no, non sono il fratello di Petya Zaitsev. Spesso mi fanno questa domanda. No, non siamo fratelli.

«È di pubblico dominio» che ClickHouse:
- È molto veloce,
- È molto conveniente,
- È utilizzato in Yandex.
È meno noto in quali aziende e come venga utilizzato.

Vi parlerò di come, dove e per cosa viene utilizzato ClickHouse, oltre a Yandex.
Ti spiegherò come compiti specifici vengono risolti con ClickHouse in diverse aziende, quali strumenti ClickHouse puoi utilizzare per le tue esigenze e come sono stati utilizzati in varie aziende.
Ho selezionato tre esempi che mostrano ClickHouse da angolazioni diverse. Penso che sarà interessante.

La prima domanda è: «A cosa serve ClickHouse?». Sembra una domanda piuttosto ovvia, ma le risposte sono più di una.

- La prima risposta è legata alle prestazioni. ClickHouse è molto veloce. L'analisi su ClickHouse è altrettanto veloce. Può spesso essere utilizzato dove altri strumenti funzionano molto lentamente o in modo inefficace.
- La seconda risposta riguarda il costo. E soprattutto il costo di scalabilità. Ad esempio, Vertica è un ottimo database. Funziona molto bene se hai un numero limitato di terabyte di dati. Ma quando si tratta di centinaia di terabyte o petabyte, il costo delle licenze e del supporto diventa considerevole. Ed è costoso. ClickHouse, invece, è gratuito.
- La terza risposta riguarda il costo operativo. Questo approccio è un po' diverso. RedShift è un'ottima alternativa. Su RedShift puoi creare rapidamente una soluzione. Funzionerà bene, ma ogni ora, ogni giorno e ogni mese pagherai un costo piuttosto elevato ad Amazon, perché è un servizio piuttosto costoso. Anche Google BigQuery è simile. Chi lo ha utilizzato sa che può lanciare alcune query e ricevere fatture improvvise da centinaia di dollari.
In ClickHouse questi problemi non ci sono.

Dove viene utilizzato ClickHouse oggi? Oltre a Yandex, ClickHouse è utilizzato in molte diverse aziende e attività.
- Prima di tutto, è usato per l'analisi delle applicazioni web, cioè è un caso d'uso nato da Yandex.
- Molte aziende AdTech utilizzano ClickHouse.
- Numerose aziende che necessitano di analizzare i log operativi provenienti da fonti diverse.
- Alcune aziende utilizzano ClickHouse per il monitoraggio dei log di sicurezza. Li caricano in ClickHouse, generano rapporti e ottengono i risultati di cui hanno bisogno.
- Le aziende iniziano a utilizzarlo anche per l'analisi finanziaria, cioè gradualmente anche le grandi imprese si stanno avvicinando a ClickHouse.
- CloudFlare. Se qualcuno segue ClickHouse, sicuramente ha sentito parlare di questa azienda. È uno dei contributori più importanti della community. Hanno un'installazione di ClickHouse molto significativa. Ad esempio, hanno creato il Kafka Engine per ClickHouse.
- Le compagnie di telecomunicazione hanno cominciato a utilizzarlo. Diverse aziende utilizzano ClickHouse sia come proof of concept che già in produzione.
- Un'azienda utilizza ClickHouse per monitorare i processi produttivi. Testano i microchip, registrando un gran numero di parametri, circa 2.000 caratteristiche. Poi analizzano – se si tratta di un buon lotto o di un cattivo lotto.
- Analisi blockchain. C'è un'azienda russa, Bloxy.info. Si dedicano all'analisi della rete Ethereum. Anche questo lo hanno realizzato su ClickHouse.

Inoltre, la dimensione non conta. Ci sono molte aziende che utilizzano un piccolo server. E questo consente loro di risolvere i loro problemi. E ancora più aziende utilizzano grandi cluster composti da molti server o decine di server.
E se guardiamo ai record, abbiamo:
- Yandex: oltre 500 server, conservano 25 miliardi di registrazioni al giorno.
- LifeStreet: 60 server, circa 75 miliardi di registrazioni al giorno. Meno server, più registrazioni rispetto a Yandex.
- CloudFlare: 36 server, 200 miliardi di record al giorno che conservano. Hanno anche meno server e ancora più dati che conservano.
- Bloomberg: 102 server, circa un trilione di record al giorno. Record per numero di record.

Geograficamente, anche questo è molto. Questa mappa mostra la heatmap in cui ClickHouse è utilizzato nel mondo. Qui si evidenzia chiaramente la Russia, la Cina e l'America. Ci sono poche nazioni europee. Si possono individuare 4 cluster.
Questa è un'analisi comparativa, qui non bisogna cercare cifre assolute. È un'analisi dei visitatori che leggono materiali in lingua inglese sul sito di Altinity, perché non ci sono parlanti russi. E Russia, Ucraina, Bielorussia, quindi la parte di lingua russa della comunità, sono gli utenti più numerosi. Poi ci sono gli Stati Uniti e il Canada. La Cina sta recuperando rapidamente. Sei mesi fa, la Cina era quasi assente, ora ha già superato l'Europa e continua a crescere. Anche l'anziana Europa non resta indietro, e, stranamente, la Francia è il leader nell'uso di ClickHouse.

Perché sto raccontando tutto questo? Per mostrare che ClickHouse sta diventando la soluzione standard per l'analisi dei big data ed è già molto utilizzato in vari ambiti. Se lo stai già utilizzando, sei sulla strada giusta. Se non lo stai ancora usando, non preoccuparti: non sarai solo e non mancherà il supporto, poiché molte persone già lo stanno adottando.

Questi sono esempi di utilizzo reale di ClickHouse in diverse aziende.
- Il primo esempio è una rete pubblicitaria: la migrazione da Vertica a ClickHouse. Conosco diverse aziende che hanno già effettuato il passaggio da Vertica o sono in fase di migrazione.
- Il secondo esempio riguarda un data warehouse transazionale su ClickHouse. Questo esempio è costruito su anti-pattern. Tutto ciò che non si dovrebbe fare in ClickHouse secondo i consigli degli sviluppatori è stato fatto qui. E nonostante ciò, funziona così bene che è decisamente più efficace rispetto a una tipica soluzione transazionale.
- Il terzo esempio riguarda il calcolo distribuito su ClickHouse. C'era una domanda su come integrare ClickHouse nell'ecosistema Hadoop. Mostrerò un esempio di come un'azienda ha realizzato su ClickHouse qualcosa di simile a un contenitore map reduce, gestendo la localizzazione dei dati, per affrontare un compito molto complesso.

- LifeStreet è un'azienda Ad Tech che dispone di tutte le tecnologie correlate a una rete pubblicitaria.
- Si occupa dell'ottimizzazione degli annunci e del bidding programmatico.
- Una grande quantità di dati: circa 10 miliardi di eventi al giorno. Inoltre, gli eventi possono suddividersi in diversi sotto-eventi.
- Molti clienti utilizzano questi dati, non solo persone, ma anche vari algoritmi che si occupano del bidding programmatico.

L'azienda ha percorso un lungo e difficile cammino. Ne ho parlato al HighLoad. Inizialmente, LifeStreet è passata da MySQL (con una breve sosta su Oracle) a Vertica. È possibile trovare questa storia.
All'inizio tutto è andato molto bene, ma è diventato chiaro abbastanza rapidamente che i dati crescevano e Vertica era costoso. Pertanto, abbiamo cercato diverse alternative. Alcune di esse sono elencate qui. In effetti, abbiamo realizzato un proof of concept o talvolta dei test di prestazioni su quasi tutti i database disponibili sul mercato dal 2013 al 2016, che erano compatibili con le funzionalità richieste. E su alcuni di essi ne ho parlato anche al HighLoad.

C'era la necessità di migrare da Vertica in primo luogo, poiché i dati stavano crescendo. E cresceva in modo esponenziale da diversi anni. Poi hanno raggiunto un punto di stallo, ma nonostante ciò. Prevedendo questa crescita, le esigenze aziendali riguardo al volume di dati per cui fare analytics, era chiaro che presto si sarebbe parlato di petabyte. E pagare per i petabyte è già molto costoso, quindi si cercava un'alternativa dove andare.

Dove andare? Per un lungo periodo, non era affatto chiaro dove dirigersi, perché da un lato ci sono database commerciali, che sembrano funzionare bene. Alcuni funzionano quasi altrettanto bene di Vertica, altri meno. Ma sono tutti costosi, non si riusciva a trovare nulla di più economico e migliore.
Dall'altro lato, ci sono soluzioni open source, che non sono molte, cioè, per l'analisi, si possono contare sulle dita. E sono gratuite o a basso costo, ma funzionano lentamente. E spesso mancano delle funzionalità necessarie e utili.
E per unire ciò che c'è di buono nei database commerciali e tutto ciò che è gratuito nel mondo open source, non c'era nulla.

Non c'era nulla fino a quando improvvisamente Yandex non tirò fuori, come un coniglio da un cappello, ClickHouse. E fu una soluzione inaspettata, ma ancora oggi ci si domanda: «Perché?», eppure.

E subito nell'estate del 2016 abbiamo iniziato a esplorare cos'è ClickHouse. E si è rivelato che a volte può essere più veloce di Vertica. Abbiamo testato diversi scenari su diverse query. E se la query utilizzava solo una tabella, ossia senza join, ClickHouse era due volte più veloce di Vertica.
Non mi sono risparmiato e ho controllato altri test di Yandex qualche giorno fa. Lì la situazione è la stessa: ClickHouse è due volte più veloce di Vertica, quindi ne parlano frequentemente.
Ma se ci sono join nelle query, le cose diventano meno chiare. E ClickHouse può risultare più lento di Vertica di due volte. Ma se si modifica leggermente la query e la si riscrive, sono più o meno equivalenti. Non male. E gratis.

E avendo ottenuto i risultati dei test e avendo guardato la situazione da diversi angoli, LifeStreet ha optato per ClickHouse.

Ricordo che era il 2016. Era come nella barzelletta sui topi che piangevano e si pungerebbero, ma continuavano a mangiare il cactus. E se ne è parlato dettagliatamente, ci sono video e altro.

Per questo motivo non entrerò nei dettagli, ma condividerò solo i risultati e alcune cose interessanti di cui non avevo parlato all'epoca.
I risultati sono:
- Migrazione riuscita e il sistema è già in produzione da oltre un anno.
- Le prestazioni e la flessibilità sono aumentate. Delle 10 miliardi di registrazioni che eravamo in grado di conservare al giorno per poco tempo, ora LifeStreet ne conserva 75 miliardi al giorno e può farlo per 3 mesi o più. In picco, si salvano fino a un milione di eventi al secondo. Oltre un milione di query SQL al giorno arrivano in questo sistema, principalmente da vari bot.
- Sebbene ClickHouse utilizzi più server rispetto a Vertica, ci sono stati risparmi anche sull'hardware, poiché Vertica usava dischi SAS piuttosto costosi. In ClickHouse venivano usati dischi SATA. Perché? Perché in Vertica l'inserimento è sincronizzato. E la sincronizzazione richiede dischi che non rallentino troppo, e anche una rete veloce, quindi è un'operazione abbastanza costosa. In ClickHouse, invece, l'inserimento è asincrono. Inoltre, è possibile scrivere tutto localmente, senza costi aggiuntivi, il che consente di inserire i dati in ClickHouse molto più rapidamente, anche su dischi non tra i più veloci. Per quanto riguarda la lettura, è più o meno la stessa: la lettura su dischi SATA, se sono in RAID, è comunque abbastanza veloce.
- Nonostante non ci siano limitazioni di licenza, ovvero 3 petabyte di dati su 60 server (20 server costituiscono una replica) e 6 trilioni di record tra fatti e aggregati. Niente di simile era possibile con Vertica.

Ora passerò a cose pratiche in questo esempio.
- Primo: uno schema efficace. Molto dipende dallo schema.
- Secondo: generazione di SQL efficace.

Una tipica query OLAP è un select. Alcune colonne vanno in group by, altre colonne vanno in funzioni aggregate. C'è un where, che può essere considerato come un taglio del cubo. L'intero group by può essere visto come una proiezione. Per questo motivo si parla di analisi multidimensionale dei dati.

Spesso questo è modellato sotto forma di uno schema a stella, dove c'è un fatto centrale e le caratteristiche di quel fatto ai lati, nei raggi.

Dal punto di vista del design fisico, di come questo è rappresentato nelle tabelle, di solito si crea una rappresentazione normalizzata. È possibile denormalizzare, ma ciò comporta un costo elevato per lo spazio su disco e non è molto efficiente per le query. Pertanto, di solito si crea una rappresentazione normalizzata, ossia una tabella dei fatti e molte tabelle di dimensioni.
Tuttavia, in ClickHouse questo funziona male. Ci sono due motivi:
- Il primo è che in ClickHouse i join non sono molto buoni, ci sono dei join, ma non sono ottimali. Al momento sono carenti.
- Il secondo è che le tabelle non vengono aggiornate. Di solito in queste piccole tabelle intorno allo schema a stella, è necessario cambiare qualcosa. Ad esempio, il nome del cliente, il nome dell'azienda e altro. E questo non funziona.
Tuttavia, esistono due soluzioni a questo problema in ClickHouse:
- Il primo consiste nell'uso dei dizionari. Gli External Dictionaries sono ciò che aiuta a risolvere il 99% dei problemi relativi allo schema star, agli aggiornamenti e così via.
- Il secondo è l'uso degli array. Anche gli array aiutano a eliminare le join e i problemi di normalizzazione.

- Non sono necessarie le join.
- Aggiornabili. Da marzo 2018 è emersa una possibilità non documentata (non la troverete nella documentazione) di aggiornare i dizionari parzialmente, ovvero quelle voci che sono cambiate. Praticamente è come una tabella.
- Sempre in memoria, quindi le join con il dizionario funzionano più velocemente rispetto a una tabella che si trova su disco e che probabilmente non è nemmeno in cache.

- Anche in questo caso non sono necessarie le join.
- È una rappresentazione compatta di 1 a molti.
- E a mio avviso, gli array sono fatti per i geek. Queste sono funzioni lambda e altro.
Non è solo per effetto scenico. È una funzionalità molto potente che consente di fare molte cose in modo semplice ed elegante.

Esempi tipici che aiutano a risolvere mediante array. Questi esempi sono semplici e abbastanza chiari:
- Ricerca per tag. Se hai degli hashtag e vuoi trovare delle voci in base a un hashtag.
- Ricerca per parametri key-value. Ci sono anche alcuni attributi con valore.
- Archiviazione di elenchi di chiavi che è necessario tradurre in qualcos'altro.
Tutte queste operazioni possono essere eseguite senza array. I tag possono essere collocati in una riga e selezionati con espressioni regolari o in una tabella separata, ma in tal caso sarà necessario fare join.

In ClickHouse non è necessario fare nulla, basta descrivere un array string per gli hashtag o creare una struttura annidata per sistemi tipo key-value.
Una struttura annidata può non essere il termine più appropriato. Si tratta di due array che hanno una parte comune nel nome e alcune caratteristiche correlate.
E cercare per tag è molto semplice. C'è una funzione has, che verifica se un elemento è presente nell'array. Abbiamo trovato tutte le registrazioni relative alla nostra conferenza.
La ricerca per subid è leggermente più complicata. Dobbiamo prima trovare l'indice della chiave, e poi prendere l'elemento con quell'indice e verificare che il valore sia quello di cui abbiamo bisogno. Tuttavia, è comunque molto semplice e compatto.
Un'espressione regolare che vorresti scrivere, se tutto fosse memorizzato in una sola riga, sarebbe, prima di tutto, goffa. E, in secondo luogo, funzionerebbe molto più lentamente di due array.

Un altro esempio. Hai un array in cui memorizzi gli ID. E puoi tradurli in nomi. La funzione arrayMap. Questa è una tipica funzione lambda. Passi al suo interno un'espressione lambda. E per ogni ID nel dizionario estrae il valore del nome.
Allo stesso modo si può fare anche la ricerca. Si passa una funzione predicato che verifica a cosa corrispondono gli elementi.

Queste cose semplificano molto lo schema e risolvono molti problemi.
Ma il prossimo problema con cui ci siamo imbattuti e di cui vorrei parlare, sono le query efficienti.
- In ClickHouse non c'è un pianificatore di query. Non esiste affatto.
- Tuttavia, anche le query complesse devono comunque essere pianificate. In quali casi?
- Se la query ha più join che avvolgi in sotto-selezioni. E l'ordine in cui vengono eseguiti ha importanza.
- E in secondo luogo, se la query è distribuita. Perché in una query distribuita solo la sottoquery più interna viene eseguita in modo distribuito, mentre tutto il resto viene inviato a un server specifico, a cui sei connesso e viene eseguito lì. Quindi, se hai query distribuite con molti join, devi scegliere l'ordine.
E anche nei casi più semplici, a volte è utile che il pianificatore lavori e riscrivere leggermente le query.

Ecco un esempio. A sinistra la query che mostra le prime 5 nazioni. E ci impiega 2,5 secondi, se non sbaglio. A destra la stessa query, ma leggermente riscritta. Invece di raggruppare per stringa, abbiamo iniziato a raggruppare per chiave (int). Ed è più veloce. Poi abbiamo unito il dizionario al risultato. Invece di 2,5 secondi, la query impiega 1,5 secondi. È un ottimo risultato.

Un esempio simile riguarda la riscrittura dei filtri. Qui c'è una query per la Russia. Ci impiega 5 secondi. Se la riscriviamo in modo da confrontare non più le stringhe, ma i numeri con un certo insieme di chiavi che si riferiscono alla Russia, sarà molto più veloce.

Ci sono molti trucchi. Questi possono velocizzare notevolmente le query che pensate già stiano funzionando velocemente o, al contrario, che stiano funzionando lentamente. Possono essere resi ancora più veloci.

- Massimo lavoro in modalità distribuita.
- Ordinamento per i tipi minimi, come ho fatto con gli indici.
- Se ci sono delle join, dizionari, è meglio farle per ultime, quando i dati sono già parzialmente raggruppati; in questo modo l'operazione di join o la chiamata al dizionario saranno meno frequenti e quindi più veloci.
- Sostituzione dei filtri.
Ci sono altre tecniche oltre a quelle che ho dimostrato. E tutte possono talvolta velocizzare notevolmente l'esecuzione delle query.

Passiamo al prossimo esempio. L'azienda X dagli Stati Uniti. Cosa fa?
C'era una richiesta:
- Collegamento offline delle transazioni pubblicitarie.
- Modellazione di diversi modelli di collegamento.

In cosa consiste lo scenario?
Un visitatore normale accede al sito, ad esempio, 20 volte al mese tramite diversi annunci o semplicemente torna di tanto in tanto senza alcun annuncio, perché ricorda il sito. Guarda alcuni prodotti, li mette nel carrello e poi li toglie dal carrello. E, alla fine, acquista qualcosa.
Domande ragionevoli: "A chi bisogna pagare per la pubblicità, se necessario?" e "Quale pubblicità lo ha influenzato, se lo ha fatto?" Cioè, perché ha acquistato e come fare in modo che anche le persone simili a lui comprino?
Per risolvere questo problema, è necessario collegare in modo appropriato gli eventi che si verificano sul sito web, cioè stabilire una connessione tra di essi. Poi trasmetterli per l'analisi al DWH. E sulla base di questa analisi, costruire modelli per capire a chi e quale pubblicità mostrare.

Una transazione pubblicitaria è un insieme di eventi utente correlati che inizia con la visualizzazione di un annuncio, prosegue con ulteriori azioni e può culminare in un acquisto, seguito eventualmente da acquisti successivi. Ad esempio, nel caso di un'app mobile o di un gioco mobile, solitamente l'installazione dell'app è gratuita, ma se vengono effettuate ulteriori azioni, potrebbero essere necessari dei pagamenti. Più un utente spende nell'app, maggiore è il suo valore. Ma prima è necessario collegare tutto.

Esistono diversi modelli di collegamento.
I più popolari sono:
- Last Interaction, dove l'interaction può essere un clic o una visualizzazione.
- First Interaction, ovvero la prima azione che ha portato l'utente al sito.
- Combinazione lineare – equa per tutti.
- Attenuazione.
- E altro ancora.

E come funzionava tutto questo inizialmente? C'era Runtime e Cassandra. Cassandra veniva utilizzata come transaction storage, ovvero conteneva tutte le transazioni correlate. Quando un evento si presentava in Runtime, ad esempio la visualizzazione di una pagina o altro, veniva effettuata una richiesta a Cassandra per verificare se l'utente esisteva. Successivamente venivano recuperate le transazioni ad esso collegate e veniva effettuato il collegamento.
E se per caso nel tuo ticket c'è un ID di transazione, allora è semplice. Ma spesso non è così. Pertanto, era necessario trovare l'ultima transazione o quella dell'ultimo clic, e così via.
E tutto ciò ha funzionato molto bene finché il legame era impostato sull'ultimo clic. Parliamo di 10 milioni di clic al giorno, 300 milioni al mese, se consideriamo un intervallo mensile. E poiché in Cassandra tutto deve essere in memoria per garantire un funzionamento rapido, poiché è necessario rispondere rapidamente a Runtime, erano necessari circa 10-15 server.
Ma quando hanno voluto collegare la transazione alla visualizzazione, la situazione è cambiata drasticamente. Perché? È evidente che ora ci sono 30 volte più eventi da memorizzare. Di conseguenza, sono necessari 30 volte più server. E questo porta a una cifra astronomica. Mantenere fino a 500 server per effettuare il collegamento, considerando che i server in Runtime sono significativamente meno, produce una cifra inaccettabile. E si è iniziato a riflettere su cosa fare.

E siamo arrivati a ClickHouse. Ma come si può fare con ClickHouse? A prima vista, sembra una serie di antipattern.
- Le transazioni stanno crescendo, e noi stiamo integrando sempre più eventi, ovvero sono mutate, e ClickHouse non gestisce bene gli oggetti mutabili.
- Quando riceviamo un visitatore, dobbiamo estrarre le sue transazioni in base alla chiave, tramite il suo visit id. Anche questo è una query puntuale, che non si fa in ClickHouse. Di solito in ClickHouse si effettuano grandi ...scan, mentre qui dobbiamo recuperare solo alcune righe. Anche questo è un antipattern.
- Inoltre, la transazione era in json, ma non volevano modificarla, quindi desideravano conservare il json in modo non strutturato e, se necessario, estrarre qualcosa da esso. Anche questo è un antipattern.
Cioè, un insieme di antipattern.

Tuttavia, siamo riusciti a creare un sistema che funziona molto bene.
Cosa è stato fatto? È stato introdotto ClickHouse, nel quale venivano inviati i log suddivisi in record. È emerso un servizio attributo che riceveva i log da ClickHouse. Successivamente, per ogni record, in base all'ID della visita, si ottenevano le transazioni che potevano essere ancora in fase di elaborazione, insieme agli snapshot, ossia transazioni già collegate, ovvero il risultato del lavoro precedente. Da lì, già impostavo la logica, selezionavo la transazione corretta, associavo nuovi eventi. Riscrivevo di nuovo nel log. Il log tornava a ClickHouse, quindi era un sistema continuamente ciclico. Inoltre, veniva inviato all'DWH per l'analisi.
In una tale forma, questo non funzionava molto bene. Per rendere più semplice ClickHouse, quando arrivava una richiesta per l'ID della visita, raggruppavamo queste richieste in blocchi di 1.000-2.000 ID di visita e estraevamo per 1.000-2.000 persone tutte le transazioni. E così tutto ha cominciato a funzionare.

Se si guarda all'interno di ClickHouse, ci sono solo 3 tabelle principali che gestiscono tutto ciò.
La prima tabella, nella quale vengono caricati i log, è in gran parte alimentata senza alcuna elaborazione.
La seconda tabella. Attraverso la vista materializzata, venivano estratti dai log eventi non attribuiti, ovvero quelli non correlati. E attraverso la vista materializzata venivano estratte le transazioni per costruire lo snapshot. Quindi, una vista materializzata speciale costruiva lo snapshot, ossia l'ultima stato accumulato della transazione.

Qui è scritto un testo in SQL. Vorrei commentare alcune cose importanti.
La prima cosa importante è la possibilità di estrarre colonne e campi da json in ClickHouse. Ci sono alcuni metodi in ClickHouse per lavorare con json. Sono molto, molto primitivi.
visitParamExtractInt consente di estrarre attributi da json, ossia il primo trovato scatta. In questo modo è possibile estrarre l'ID della transazione o l'ID della visita. Questo è uno.
Il secondo punto è che qui viene utilizzato un campo materializzato astuto. Cosa significa? Significa che non puoi inserirlo nella tabella, ovvero non viene inserito, viene calcolato e memorizzato al momento dell'inserimento. Durante l'inserimento, ClickHouse fa il lavoro per te. E viene estratto da json ciò di cui avrai bisogno in seguito.
In questo caso, la materialized view è per le righe non elaborate. Viene utilizzata la prima tabella con log praticamente grezzi. E cosa fa? Prima di tutto, cambia l'ordinamento, cioè ora l'ordinamento avviene per visit id, perché dobbiamo estrarre rapidamente la transazione di una specifica persona.
La seconda cosa importante è index_granularity. Se hai visto MergeTree, di solito per default si imposta index_granularity a 8.192. Cos'è? È un parametro di sparseness dell'indice. In ClickHouse, l'indice è sparso, non indicizza mai ogni singolo record. Lo fa ogni 8.192 record. Questo è utile quando è necessario calcolare molti dati, ma problematico quando ce ne sono pochi, perché provoca un overhead elevato. E se riduciamo l'index granularity, diminuiamo l'overhead. Non possiamo ridurlo a uno, perché potremmo non avere abbastanza memoria. L'indice è sempre conservato in memoria.

E lo snapshot utilizza anche alcune funzioni interessanti di ClickHouse.
Innanzitutto, si tratta di AggregatingMergeTree. E in AggregatingMergeTree viene memorizzato argMax, ovvero lo stato della transazione corrispondente all'ultimo timestamp. Transazioni nuove vengono continuamente generate per questo visitatore. E nello stato più recente di questa transazione abbiamo aggiunto un evento e abbiamo ottenuto un nuovo stato. Questo è tornato in ClickHouse. E attraverso argMax in questa vista materializzata possiamo sempre ottenere lo stato attuale.

- Il legame è 'disaccoppiato' da Runtime.
- Fino a 3 miliardi di transazioni vengono memorizzate e elaborate al mese. Questo è di gran lunga superiore rispetto a quanto avveniva in Cassandra, cioè in un tipico sistema di transazioni.
- Cluster di 2x5 server ClickHouse. 5 server e ogni server ha una replica. Questo è addirittura inferiore rispetto a quanto era in Cassandra per realizzare l'attribuzione basata sui click, mentre qui abbiamo l'attribuzione basata sulle impressioni. Cioè, invece di aumentare il numero di server di 30 volte, siamo riusciti a ridurlo.

E l'ultimo esempio è una compagnia finanziaria Y, che analizzava le correlazioni delle variazioni delle quotazioni azionarie.
La sfida era questa:
- Ci sono circa 5.000 azioni.
- Le quotazioni sono note ogni 100 millisecondi.
- I dati si sono accumulati in 10 anni. Evidentemente, per alcune aziende sono di più, per altre di meno.
- In totale ci sono circa 100 miliardi di righe.
E bisognava calcolare la correlazione dei cambiamenti.

Qui ci sono due azioni e le loro quotazioni. Se una sale e l'altra sale, c'è una correlazione positiva, ossia una cresce e l'altra cresce. Se una sale, come alla fine del grafico, e l'altra scende, c'è una correlazione negativa, ossia quando una cresce, l'altra scende.
Analizzando queste mutue variazioni, è possibile fare previsioni sul mercato finanziario.

Ma il compito è difficile. Cosa viene fatto per questo? Abbiamo 100 miliardi di registrazioni, in cui ci sono: tempo, azione e prezzo. Dobbiamo prima calcolare 100 miliardi di volte il runningDifference dell'algoritmo del prezzo. RunningDifference è una funzione in ClickHouse che calcola la differenza tra due righe in modo sequenziale.
E dopo questo, bisogna calcolare la correlazione, e la correlazione deve essere calcolata per ogni coppia. Per 5.000 azioni, le coppie sono 12,5 milioni. E questo è molto, ossia ci sono 12,5 volte di necessità di calcolare una funzione di correlazione.
E se qualcuno si fosse dimenticato, ͞x e ͞y sono la media ponderata del campione. Cioè, non è solo necessario calcolare radici e somme, ma anche eseguire altre somme all'interno di queste somme. Bisogna effettuare un sacco di calcoli 12,5 milioni di volte, e bisogna anche raggrupparli per ore. E le ore sono molte anche per noi. E dobbiamo farlo entro 60 secondi. È uno scherzo.

Dovevamo riuscire a fare qualcosa, perché tutto questo funzionava molto, molto lentamente, prima che arrivasse ClickHouse.

Hanno provato a calcolarlo su Hadoop, su Spark, su Greenplum. E tutto ciò era molto lento o costoso. Cioè, si poteva calcolare in un certo modo, ma poi era costoso.

E poi è arrivato ClickHouse e tutto è migliorato notevolmente.
Ricordo che abbiamo un problema di località dei dati, quindi non possiamo localizzare le correlazioni. Non possiamo dividere alcuni dati su un server, altri su un altro e calcolare, dobbiamo avere tutti i dati ovunque.
Cosa hanno fatto? I dati erano inizialmente localizzati. Su ciascun server sono memorizzati i dati relativi ai prezzi di un determinato insieme di azioni. E non si sovrappongono. Pertanto, è possibile calcolare logReturn in parallelo e indipendentemente, tutto avviene mentre è parallelo e distribuito.
In seguito abbiamo deciso di ridurre questi dati senza perdere espressività. Ridurre utilizzando array, cioè creare un array di azioni e un array di prezzi per ogni segmento temporale. In questo modo i dati occupano molto meno spazio. E sono anche un po' più facili da gestire. Si tratta quasi di operazioni parallele, cioè calcoliamo parzialmente in parallelo e poi scriviamo sul server.
Dopo questo, è possibile replicare. La lettera 'r' indica che questi dati sono stati replicati. Cioè abbiamo dati identici su tutti e tre i server - questi array.
Inoltre, con uno script speciale da questo insieme di 12,5 milioni di correlazioni che devono essere calcolate, possiamo creare pacchetti. Cioè, 2.500 compiti con 5.000 coppie di correlazioni ciascuno. E calcolare questa operazione su un determinato server ClickHouse. Tutti i dati sono disponibili, poiché i dati sono identici e può calcolarli in modo sequenziale.

Ancora una volta, ecco come appare. Innanzitutto, abbiamo tutti i dati in questa struttura: tempo, azioni, prezzo. Poi abbiamo calcolato il logReturn, ovvero dati della stessa struttura, solo che al posto del prezzo abbiamo il logReturn. Successivamente, li abbiamo rielaborati, quindi abbiamo ottenuto tempo e groupArray per le azioni e i prezzi. Abbiamo effettuato la replica. E dopo questo abbiamo generato una serie di task e li abbiamo dati a ClickHouse affinché li elaborasse. E funziona.

Nel proof of concept, il compito era una sotto-area, cioè abbiamo preso meno dati. E solo su tre server.
Questi primi due passaggi: il calcolo del Log_return e l'imballaggio in array hanno preso circa un'ora ciascuno.
Il calcolo della correlazione ha richiesto circa 50 ore. Ma 50 ore sono poche, perché in passato ci riuscivano solo dopo settimane. È stato un grande successo. E se si conta, 70 volte al secondo su questo cluster tutto veniva calcolato.
Ma la cosa più importante è che questo sistema è praticamente senza colli di bottiglia, cioè scala praticamente in modo lineare. E lo hanno verificato. L'hanno scalato con successo.

- Uno schema corretto è metà del successo. E uno schema corretto è l'uso di tutte le tecnologie necessarie di ClickHouse.
- Summing/AggregatingMergeTrees è una tecnologia che consente di aggregare o calcolare uno snapshot di stato come un caso particolare. Questo semplifica notevolmente molte operazioni.
- Le Materialized Views consentono di superare la limitazione di un solo indice. Forse non l'ho spiegato chiaramente, ma quando caricavamo i log, i log grezzi erano in una tabella con un solo indice, mentre i log degli attributi erano in un'altra tabella, cioè gli stessi dati, ma filtrati, sebbene l'indice fosse completamente diverso. Sembra trattarsi degli stessi dati, ma con ordinamenti diversi. Le Materialized Views permettono, se necessario, di bypassare questa limitazione di ClickHouse.
- Riduci la granularità dell'indice per le query puntuali.
- Distribuisci i dati in modo intelligente, cercando di localizzare al massimo i dati all'interno del server. E cerca di far sì che le query utilizzino la localizzazione dove possibile.

In sintesi, si può dire che ClickHouse ha ormai consolidato la sua posizione sia nel campo dei database commerciali che nelle soluzioni open source, in particolare per l'analisi. Si è perfettamente integrato in questo panorama e, anzi, sta lentamente iniziando a soppiantare altri sistemi; quando c'è ClickHouse, non avete bisogno di InfiniDB. Forse Vertica diventerà superflua, se implementeranno un buon supporto per SQL. Utilizzatelo!

—Grazie per la presentazione! È stato molto interessante! Ci sono stati confronti con Apache Phoenix?
-No, non ho sentito parlare di confronti. Noi di Yandex cerchiamo di monitorare tutti i confronti di ClickHouse con altri database. Se per caso qualcosa si dimostra più veloce di ClickHouse, allora Alexey Milovidov non riesce a dormire e inizia rapidamente a migliorarlo. Non sono a conoscenza di tale confronto.
(Алексей Миловидов) Apache Phoenix è un motore SQL basato su Hbase. Hbase è principalmente progettato per scenari di lavoro tipo key-value. Ogni riga può avere un numero arbitrario di colonne con nomi a piacere. Questo vale per sistemi come Hbase e Cassandra. Tuttavia, su di essi, le query analitiche pesanti non funzioneranno bene. Oppure potreste pensare che funzionino normalmente, se non avete avuto esperienza con ClickHouse.
Grazie
Buongiorno! Mi sono interessato a questo argomento da un po' di tempo, perché ho un sottosistema analitico. Ma quando guardo ClickHouse, ho l'impressione che ClickHouse sia molto adatto per l'analisi di eventi e dati mutabili. E se devo analizzare molti dati di business con enormi tabelle, ClickHouse, a quanto pare, non è molto adatto per me? Soprattutto se i dati cambiano. È corretto o ci sono esempi che potrebbero contraddirlo?
È corretto. E questo è vero per la maggior parte dei database analitici specializzati. Sono progettati per gestire una o più grandi tabelle che sono mutabili, e molte piccole tabelle che cambiano lentamente. Cioè, ClickHouse non è come Oracle, dove puoi inserire tutto e costruire query molto complesse. Per utilizzare ClickHouse in modo efficace, è necessario costruire lo schema in un modo che funzioni bene in ClickHouse. Cioè, evitare l'eccessiva normalizzazione, utilizzare dizionari e cercare di avere meno legami lunghi. Se lo schema viene costruito in questo modo, allora compiti aziendali simili su ClickHouse possono essere risolti in modo molto più efficiente rispetto a un tradizionale database relazionale.
Grazie per la presentazione! Ho una domanda riguardo all'ultimo caso finanziario. Avevano un'analisi. Dovevano confrontare come andavano su e giù. E ho capito che avete costruito il sistema proprio per questa analisi? Se domani, ad esempio, avessero bisogno di un altro report su questi dati, devono ricostruire nuovamente lo schema e caricare i dati? Cioè, fare qualche pre-elaborazione per ottenere la query?
Certo, si tratta di utilizzare ClickHouse per un compito specifico. Tradizionalmente, questo potrebbe essere risolto all'interno di Hadoop. Per Hadoop, è un compito ideale. Ma su Hadoop è molto lento. E il mio obiettivo è dimostrare che con ClickHouse si possono affrontare compiti che di solito sono risolti con mezzi completamente diversi, ma in modo molto più efficiente. È adattato a un compito specifico. È chiaro che se c'è un compito simile, allora può essere affrontato in modo simile.
Chiaro. Ha detto che sono state elaborate 50 ore. Questo a partire dall'inizio, quando avete caricato i dati o dopo aver ottenuto i risultati?
Sì, sì.
Bene, grazie mille.
Questo su un cluster di 3 server.
Salve! Grazie per la presentazione! È tutto molto interessante. Vorrei chiedere un po' meno sulle funzionalità e più sull'uso di ClickHouse in termini di stabilità. È successo che vi siano stati problemi, avete dovuto ripristinare? Come si comporta ClickHouse in queste situazioni? È mai capitato che si verificassero dei downtime anche per la replica? Noi, ad esempio, abbiamo riscontrato un problema con ClickHouse, dove comunque supera il suo limite e va in crash.
Certo, non esistono sistemi perfetti. Anche ClickHouse ha i suoi problemi. Ma avete mai sentito parlare di Yandex.Metrica che non funziona a lungo? Probabilmente no. Funziona in modo affidabile dal 2012-2013 su ClickHouse. Posso anche condividere la mia esperienza. Non abbiamo mai avuto guasti completi. Alcuni problemi parziali possono verificarsi, ma non sono mai stati critici al punto da influenzare seriamente il business. Non è mai successo. ClickHouse è suficiente affidabile e non cade casualmente. Non c'è bisogno di preoccuparsi. Non è una cosa grezza. È dimostrato da molte aziende.
Buongiorno! Hai detto che è necessario pensare attentamente allo schema dei dati fin dall'inizio. E se questo non è successo? I miei dati fluiscono e fluiscono. Passa mezzo anno e realizzo che non posso continuare così, devo ricaricare i dati e fare qualcosa con essi.
Dipende, ovviamente, dal tuo sistema. Ci sono diversi modi per farlo praticamente senza interruzioni. Ad esempio, puoi creare una Materialized View con una diversa struttura dati, se può essere mappata in modo univoco. Cioè, se consente di mappare attraverso ClickHouse, quindi estrarre alcune cose, cambiare la chiave primaria, modificare la partizione, si può creare una Materialized View. Lì puoi riscrivere i tuoi vecchi dati, i nuovi verranno scritti automaticamente. E poi basta passare all'utilizzo della Materialized View, poi cambiare la scrittura e eliminare la vecchia tabella. Questo è un metodo che non richiede interruzioni.
Grazie.
Fonte: habr.com
