ClickHouse + Grafite: come ridurre sensibilmente il consumo di spazio su disco

ClickHouse + Grafite: come ridurre sensibilmente il consumo di spazio su disco

Saluti, habr.

Se qualcuno sfrutta il sistema rete di grafite e ho riscontrato un problema di prestazioni di archiviazione sussurro (IO, spazio su disco consumato), la possibilità che ClickHouse sia stato lanciato come sostituto dovrebbe tendere a uno. Questa affermazione implica, ad esempio, che un'implementazione di terze parti sia già utilizzata come demone che riceve le metriche carbonwriter o go-carbon.

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 documentazione, creare una configurazione per lo schema di archiviazione delle metriche (ulteriormente retention), quindi crea una tabella secondo le raccomandazioni del backend selezionato per graphite-web: carbon-clickhouse+clickhouse in grafite o grafouse, a seconda dello stack utilizzato. E... la bomba a orologeria esplode.

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 presentazioni Aleksej Zatelepin):

  • Inserito блок dati. Nel nostro caso, sono state le metriche ad arrivare.
    ClickHouse + Grafite: come ridurre sensibilmente il consumo di spazio su disco
  • Ciascuno di questi blocchi viene ordinato in base alla chiave prima di essere scritto su disco. ORDER BYspecificato durante la creazione della tabella.
  • Dopo l'ordinamento, кусок (part) i dati vengono scritti su disco.
    ClickHouse + Grafite: come ridurre sensibilmente il consumo di spazio 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).
    ClickHouse + Grafite: come ridurre sensibilmente il consumo di spazio su disco
    ClickHouse + Grafite: come ridurre sensibilmente il consumo di spazio su disco
  • 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 comando OPTIMIZE.
  • 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.

ClickHouse + Grafite: come ridurre sensibilmente il consumo di spazio su disco

Informazioni nelle tabelle di sistema ClickHouse

Diamo un'occhiata alla struttura della tabella parti.del.sistema. Si tratta di informazioni complete su ciascuna parte di tutte le tabelle sul server ClickHouse. Contiene, tra l'altro, le seguenti colonne:

  • 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 system.grafite_retentions, con i seguenti campi interessanti:

  • nome database (Tables.database);
  • nome della tabella (Tables.table);
  • età metrica in cui deve essere applicata la successiva aggregazione (age);

Quindi:

  1. Abbiamo una tabella di blocchi e una tabella di regole di aggregazione.
  2. Combiniamo la loro intersezione e otteniamo tutte le tabelle *GraphiteMergeTree.
  3. 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 ottimizzatore di grafite-ch. Ex colleghi di Yandex.Market lo hanno provato in produzione, il risultato del lavoro può essere visto di seguito.

ClickHouse + Grafite: come ridurre sensibilmente il consumo di spazio su disco

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 InnoGames ho passato molto tempo ad armeggiare all'intersezione tra ClickHouse e grafite-web. È stata una buona esperienza, che ha portato a una rapida transizione da Whisper a ClickHouse come archivio di metriche. Spero che questo articolo sia l'inizio di una serie sui miglioramenti che abbiamo apportato alle varie parti di questo stack e su cosa verrà fatto in futuro.

Sono stati spesi diversi litri di birra e giorni di amministrazione per sviluppare la richiesta, insieme a v0devil, per il quale desidero esprimergli la mia gratitudine. E anche per aver recensito questo articolo.

Pagina del progetto su github

Fonte: habr.com

Aggiungi un commento