Saluti, habr.
Se qualcuno sfrutta il sistema
ClickHouse risolve bene i problemi descritti. Ad esempio, dopo aver trasferito 2 TiB di dati da Whisper, rientrano in 300 GiB. Non mi soffermerò nel dettaglio sul confronto; ci sono moltissimi articoli su questo argomento. Inoltre, fino a poco tempo fa, non tutto era perfetto con il nostro storage ClickHouse.
Problemi con lo spazio consumato
A prima vista, tutto dovrebbe funzionare bene. Seguente retention
), quindi crea una tabella secondo le raccomandazioni del backend selezionato per graphite-web:
Per capire quale è necessario sapere come funzionano gli inserti e l'ulteriore percorso di vita dei dati nelle tabelle dei motori della famiglia *Uniscialbero ClickHouse (grafici tratti da
- Inserito
блок
dati. Nel nostro caso, sono state le metriche ad arrivare.
- Ciascuno di questi blocchi viene ordinato in base alla chiave prima di essere scritto su disco.
ORDER BY
specificato durante la creazione della tabella. - Dopo l'ordinamento,
кусок
(part
) i dati vengono scritti su disco.
- Il server esegue il monitoraggio in background in modo che non siano presenti molti pezzi di questo tipo e avvia lo sfondo
слияния
(merge
, di seguito fusi).
- Il server interrompe l'esecuzione delle unioni da solo non appena i dati interrompono il flusso attivo nel file
партицию
(partition
), ma è possibile avviare manualmente il processo con il comandoOPTIMIZE
. - Se nella partizione è rimasto solo un pezzo, non sarà possibile eseguire l'unione utilizzando il comando abituale; è necessario utilizzare
OPTIMIZE ... FINAL
Quindi arrivano i primi parametri. E occupano un po' di spazio. Gli eventi successivi possono variare leggermente a seconda di molti fattori:
- La chiave di partizionamento può essere molto piccola (un giorno) o molto grande (diversi mesi).
- La configurazione di conservazione può soddisfare diverse soglie significative di aggregazione dei dati all'interno della partizione attiva (dove vengono registrate le metriche) o forse no.
- Se sono presenti molti dati, i primi blocchi, che a causa dell'unione in background potrebbero già essere enormi (se si sceglie una chiave di partizionamento non ottimale), non si uniranno con nuovi piccoli blocchi.
E finisce sempre allo stesso modo. Lo spazio occupato dalle metriche in ClickHouse aumenta solo se:
- non applicare
OPTIMIZE ... FINAL
manualmente o - non inserire dati in tutte le partizioni in modo continuativo, in modo che prima o poi venga avviata un'unione in background
Il secondo metodo sembra essere il più semplice da implementare e, pertanto, non è corretto ed è stato provato per primo.
Ho scritto uno script Python abbastanza semplice che ha inviato metriche fittizie per ogni giorno negli ultimi 4 anni ed ha eseguito cron ogni ora.
Poiché l'intero funzionamento di ClickHouse DBMS si basa sul fatto che questo sistema prima o poi farà tutto il lavoro in background, ma non si sa quando, non potevo aspettare il momento in cui i vecchi enormi pezzi si degneranno di fondersi con nuovi piccoli. È diventato chiaro che dovevamo cercare un modo per automatizzare le ottimizzazioni forzate.
Informazioni nelle tabelle di sistema ClickHouse
Diamo un'occhiata alla struttura della tabella
- nome database (
database
); - nome della tabella (
table
); - nome e ID della partizione (
partition
&partition_id
); - quando il pezzo è stato creato (
modification_time
); - data minima e massima in un pezzo (il partizionamento viene effettuato per giorno) (
min_date
&max_date
);
C'è anche un tavolo
- nome database (
Tables.database
); - nome della tabella (
Tables.table
); - età metrica in cui deve essere applicata la successiva aggregazione (
age
);
Quindi:
- Abbiamo una tabella di blocchi e una tabella di regole di aggregazione.
- Combiniamo la loro intersezione e otteniamo tutte le tabelle *GraphiteMergeTree.
- Cerchiamo tutte le partizioni in cui:
- più di un pezzo
- oppure è giunto il momento di applicare la prossima regola di aggregazione, e
modification_time
più vecchio di questo momento.
implementazione
Questa richiesta
SELECT
concat(p.database, '.', p.table) AS table,
p.partition_id AS partition_id,
p.partition AS partition,
-- Самое "старое" правило, которое может быть применено для
-- партиции, но не в будущем, см (*)
max(g.age) AS age,
-- Количество кусков в партиции
countDistinct(p.name) AS parts,
-- За самую старшую метрику в партиции принимается 00:00:00 следующего дня
toDateTime(max(p.max_date + 1)) AS max_time,
-- Когда партиция должна быть оптимизированна
max_time + age AS rollup_time,
-- Когда самый старый кусок в партиции был обновлён
min(p.modification_time) AS modified_at
FROM system.parts AS p
INNER JOIN
(
-- Все правила для всех таблиц *GraphiteMergeTree
SELECT
Tables.database AS database,
Tables.table AS table,
age
FROM system.graphite_retentions
ARRAY JOIN Tables
GROUP BY
database,
table,
age
) AS g ON
(p.table = g.table)
AND (p.database = g.database)
WHERE
-- Только активные куски
p.active
-- (*) И только строки, где правила аггрегации уже должны быть применены
AND ((toDateTime(p.max_date + 1) + g.age) < now())
GROUP BY
table,
partition
HAVING
-- Только партиции, которые младше момента оптимизации
(modified_at < rollup_time)
-- Или с несколькими кусками
OR (parts > 1)
ORDER BY
table ASC,
partition ASC,
age ASC
restituisce ciascuna delle partizioni della tabella *GraphiteMergeTree la cui unione dovrebbe liberare spazio su disco. L'unica cosa che resta da fare è esaminarli tutti con una richiesta OPTIMIZE ... FINAL
. L'implementazione finale tiene conto anche del fatto che non è necessario toccare le partizioni con registrazione attiva.
Questo è esattamente ciò che fa il progetto
Se esegui il programma su un server con ClickHouse, inizierà semplicemente a funzionare in modalità demone. Ogni ora verrà eseguita una richiesta, controllando se sono comparse nuove partizioni più vecchie di tre giorni che possono essere ottimizzate.
I nostri piani immediati sono di fornire almeno i pacchetti deb e, se possibile, anche gli rpm.
Invece di una conclusione
Negli ultimi 9+ mesi sono stato all'interno della mia azienda
Sono stati spesi diversi litri di birra e giorni di amministrazione per sviluppare la richiesta, insieme a
Fonte: habr.com