ProHoster > blog > amministrazione > Archiviazione delle metriche: come siamo passati da Graphite+Whisper a Graphite+ClickHouse
Archiviazione delle metriche: come siamo passati da Graphite+Whisper a Graphite+ClickHouse
Ciao a tutti! Nel suo ultimo articolo Ho scritto sull'organizzazione di un sistema di monitoraggio modulare per l'architettura dei microservizi. Niente resta fermo, il nostro progetto è in continua crescita, così come il numero di metriche memorizzate. Come abbiamo organizzato la transizione da Graphite+Whisper a Graphite+ClickHouse in condizioni di carico elevato, leggi le aspettative e i risultati della migrazione sotto il taglio.
Prima di raccontarti come abbiamo organizzato il passaggio dall'archiviazione delle metriche in Graphite+Whisper a Graphite+ClickHouse, vorrei fornire informazioni sui motivi di tale decisione e sugli svantaggi di Whisper con cui abbiamo convissuto per molto tempo.
Problemi di grafite+Whisper
1. Carico elevato sul sottosistema del disco
Al momento della transizione ci arrivavano circa 1.5 milioni di parametri al minuto. Con un flusso di questo tipo, l'utilizzo del disco sui server è stato pari a circa il 30%. In generale, questo era abbastanza accettabile: tutto funzionava stabilmente, veniva scritto velocemente, letto velocemente... Fino a quando uno dei team di sviluppo non ha lanciato una nuova funzionalità e ha iniziato a inviarci 10 milioni di parametri al minuto. È stato allora che il sottosistema del disco si è rafforzato e abbiamo riscontrato un utilizzo del 100%. Il problema è stato risolto rapidamente, ma è rimasto un residuo.
2. Mancanza di replica e coerenza
Molto probabilmente, come tutti coloro che utilizzano/usano Graphite+Whisper, abbiamo riversato lo stesso flusso di parametri su più server Graphite contemporaneamente per creare tolleranza agli errori. E non ci sono stati problemi particolari con questo, fino al momento in cui uno dei server si è bloccato per qualche motivo. A volte siamo riusciti a recuperare un server caduto abbastanza velocemente e carbon-c-relay è riuscito a caricarvi i parametri dalla sua cache, ma a volte no. E poi c'è stato un buco nei parametri, che abbiamo riempito con rsync. La procedura è stata piuttosto lunga. L’unica cosa che redime era che ciò accadeva molto raramente. Inoltre, periodicamente abbiamo preso una serie casuale di parametri e li abbiamo confrontati con altri dello stesso tipo sui nodi vicini del cluster. In circa il 5% dei casi diversi valori erano diversi, cosa di cui non eravamo molto contenti.
3. Ampio ingombro
Poiché scriviamo in Graphite non solo l'infrastruttura, ma anche le metriche aziendali (e ora anche le metriche di Kubernetes), molto spesso otteniamo una situazione in cui la metrica contiene solo pochi valori e il file .wsp viene creato tenendo conto di tutta la conservazione periodo e occupa una quantità di spazio preassegnata, che per noi era di circa 2 MB. Il problema è ulteriormente aggravato dal fatto che nel tempo compaiono molti file simili e quando si creano report su di essi, la lettura dei punti vuoti richiede molto tempo e risorse.
Vorrei subito notare che i problemi sopra descritti possono essere affrontati con vari metodi e con diversi gradi di efficacia, ma più dati si iniziano a ricevere, più essi peggiorano.
Avendo tutto quanto sopra (tenendo conto di quanto precedente articoli), nonché un aumento costante del numero di parametri ricevuti, il desiderio di trasferire tutti i parametri a un intervallo di memorizzazione di 30 secondi. (fino a 10 secondi se necessario), abbiamo deciso di provare Graphite+ClickHouse come promettente alternativa a Whisper.
Grafite+ClickHouse. Aspettative
Dopo aver visitato diversi incontri dei ragazzi di Yandex, aver letto un paio di articoli su Habré, dopo aver esaminato la documentazione e trovato componenti validi per legare ClickHouse sotto Grafite, abbiamo deciso di agire!
Desidero ricevere quanto segue:
ridurre l'utilizzo del sottosistema disco dal 30% al 5%;
ridurre la quantità di spazio occupato da 1TB a 100GB;
essere in grado di ricevere 100 milioni di parametri al minuto nel server;
replica dei dati e tolleranza agli errori pronte all'uso;
non restare seduto su questo progetto per un anno ed effettuare la transizione entro un lasso di tempo ragionevole;
passare senza tempi di inattività.
Abbastanza ambizioso, vero?
Grafite+ClickHouse. Componenti
Per ricevere i dati tramite il protocollo Graphite e successivamente registrarli in ClickHouse, ho selezionato carbon-clickhouse (Golang).
Come database per l'archiviazione delle serie temporali è stata scelta l'ultima versione di ClickHouse, la versione stabile 1.1.54253. Si sono verificati problemi durante il lavoro: una montagna di errori si riversava nei registri e non era del tutto chiaro cosa farne. In discussione con Romano Lomonosov (autore di carbon-clickhouse, graphite-clickhouse e molti, molti altri) è stato scelto quello più vecchio versione 1.1.54236. Gli errori sono scomparsi: tutto ha iniziato a funzionare alla grande.
“grafite” è un database che abbiamo creato per monitorare le tabelle.
“graphite.metrics” - tabella con motore ReplicatedReplacingMergeTree (replicato Sostituzione di MergeTree). Questa tabella memorizza i nomi delle metriche e i relativi percorsi.
“graphite.data” - tabella con motore ReplicatedGraphiteMergeTree (replicato GraphiteMergeTree). Questa tabella memorizza i valori metrici.
CREATE TABLE graphite.data ( Path String, Value Float64, Time UInt32, Date Date, Timestamp UInt32 ) ENGINE = ReplicatedGraphiteMergeTree('/clickhouse/tables/replicator/graphite.data', 'r1', Date, (Path, Time), 8192, 'graphite_rollup')
"graphite.date_metrics" è una tabella compilata in modo condizionale con il motore ReplicatedReplacingMergeTree. Questa tabella registra i nomi di tutte le metriche rilevate durante il giorno. Le ragioni della sua creazione sono descritte nella sezione "I problemi" alla fine di questo articolo.
CREATE MATERIALIZED VIEW graphite.date_metrics ( Path String, Level UInt32, Date Date) ENGINE = ReplicatedReplacingMergeTree('/clickhouse/tables/replicator/graphite.date_metrics', 'r1', Date, (Level, Path, Date), 8192) AS SELECT toUInt32(length(splitByChar('.', Path))) AS Level, Date, Path FROM graphite.data
"graphite.data_stat" - una tabella riempita per condizione, con il motore ReplicatedAggregatingMergeTree (replicato AggregazioneMergeTree). Questa tabella registra il numero di metriche in entrata, suddivise in 4 livelli di nidificazione.
CREATE MATERIALIZED VIEW graphite.data_stat ( Date Date, Prefix String, Timestamp UInt32, Count AggregateFunction(count)) ENGINE = ReplicatedAggregatingMergeTree('/clickhouse/tables/replicator/graphite.data_stat', 'r1', Date, (Timestamp, Prefix), 8192) AS SELECT toStartOfMonth(now()) AS Date, replaceRegexpOne(Path, '^([^.]+.[^.]+.[^.]+).*$', '1') AS Prefix, toUInt32(toStartOfMinute(toDateTime(Timestamp))) AS Timestamp, countState() AS Count FROM graphite.data GROUP BY Timestamp, Prefix
Grafite+ClickHouse. Diagramma di interazione dei componenti
Grafite+ClickHouse. Migrazione dei dati
Come ricordiamo dalle aspettative di questo progetto, il passaggio a ClickHouse dovrebbe avvenire senza tempi di inattività, di conseguenza abbiamo dovuto in qualche modo trasferire l'intero nostro sistema di monitoraggio sul nuovo spazio di archiviazione nel modo più trasparente possibile per i nostri utenti.
Ecco come lo abbiamo fatto.
È stata aggiunta una regola a carbon-c-relay per inviare un flusso aggiuntivo di metriche alla carbon-clickhouse di uno dei server che partecipano alla replica delle tabelle ClickHouse.
Abbiamo scritto un piccolo script in Python che, utilizzando la libreria Whisper-dump, legge tutti i file .wsp dal nostro archivio e invia questi dati alla carbon-clickhouse sopra descritta in 24 thread. Il numero di valori metrici accettati in carbon-clickhouse ha raggiunto i 125 milioni/min e ClickHouse non ha nemmeno sudato.
Abbiamo creato un DataSource separato in Grafana per eseguire il debug delle funzioni utilizzate nei dashboard esistenti. Abbiamo identificato un elenco di funzioni che abbiamo utilizzato, ma non sono state implementate in carbonapi. Abbiamo aggiunto queste funzioni e inviato PR agli autori di carbonapi (un ringraziamento speciale a loro).
Per cambiare il carico di lettura nelle impostazioni del bilanciatore, abbiamo cambiato gli endpoint da graphite-api (interfaccia API per Graphite+Whisper) a carbonapi.
Grafite+ClickHouse. risultati
ridotto utilizzo del sottosistema disco dal 30% all'1%;
ridotto lo spazio occupato da 1 TB a 300 GB;
abbiamo la capacità di ricevere sul server 125 milioni di metriche al minuto (picchi al momento della migrazione);
trasferito tutte le metriche a un intervallo di archiviazione di trenta secondi;
replicazione dei dati ricevuti e tolleranza agli errori;
commutato senza tempi di inattività;
Ci sono volute circa 7 settimane per completare tutto.
Grafite+ClickHouse. I problemi
Nel nostro caso c'erano alcune insidie. Questo è ciò che abbiamo riscontrato dopo la transizione.
ClickHouse non sempre rilegge le configurazioni al volo; a volte è necessario riavviarlo. Ad esempio, nel caso della descrizione del cluster zookeeper nella configurazione di ClickHouse, non è stato utilizzato fino al riavvio del server clickhouse.
Le richieste ClickHouse di grandi dimensioni non sono state soddisfatte, quindi in graphite-clickhouse la nostra stringa di connessione ClickHouse è simile alla seguente:
ClickHouse molto spesso rilascia nuove versioni di release stabili; queste possono contenere sorprese: fai attenzione.
I contenitori creati dinamicamente in Kubernetes inviano un gran numero di parametri con una durata breve e casuale. Non ci sono molti punti per tali parametri e non ci sono problemi di spazio. Ma quando crea query, ClickHouse preleva un numero enorme di queste stesse metriche dalla tabella "metriche". Nel 90% dei casi non sono disponibili dati oltre la finestra temporale (24 ore). Ma il tempo viene impiegato per cercare questi dati nella tabella "dati" e alla fine si verifica un timeout. Per risolvere questo problema, abbiamo iniziato a mantenere una visione separata con le informazioni sulle metriche riscontrate durante la giornata. Pertanto, quando creiamo report (grafici) per contenitori creati dinamicamente, interroghiamo solo le metriche che sono state rilevate all'interno di una determinata finestra e non per l'intero tempo, il che ha accelerato significativamente la costruzione di report su di essi. Per la soluzione sopra descritta, ho raccolto clickhouse in grafite (forcella), che include l'implementazione dell'utilizzo della tabella date_metrics.
Grafite+ClickHouse. Tag
Con la versione 1.1.0 Graphite è diventata ufficiale tag di supporto. E stiamo pensando attivamente a cosa e come fare per supportare questa iniziativa nello stack grafite+clickhouse.
Grafite+ClickHouse. Rilevatore di anomalie
Sulla base dell'infrastruttura sopra descritta, abbiamo implementato un prototipo di rilevatore di anomalie e funziona! Ma di più su di lui nel prossimo articolo.