ClickHouse + Graphite: Sådan reduceres forbrugt diskplads betydeligt

ClickHouse + Graphite: Sådan reduceres forbrugt diskplads betydeligt

Hilsen habr.

Hvis nogen betjener systemet grafit web og løb ind i et problem med lagerydeevne hviske (IO, forbrugt diskplads), så skulle chancen for, at ClickHouse blev betragtet som en erstatning, være tæt på én. Denne erklæring antyder, at en tredjepartsimplementering allerede er brugt som den modtagende dæmon, for eksempel kulstof forfatter eller gå kulstof.

ClickHouse løser de beskrevne problemer godt. For eksempel, efter at have hældt 2TiB data fra whisper, passer de ind i 300GiB. Jeg vil ikke dvæle ved sammenligningen i detaljer, der er nok artikler om dette emne. Derudover var alt indtil for nylig ikke perfekt med vores ClickHouse opbevaring.

Problemer med forbrugt plads

Ved første øjekast skulle alt fungere godt. Følge dokumentation, opret en konfiguration for metrics storage-skemaet (herefter retention), opret derefter en tabel i henhold til anbefalingen fra den valgte grafitweb-backend: kulstof-klikhus+grafit-klikhus eller graphouse, afhængig af hvilken stak der bruges. Og... en tidsindstillet bombe er aktiveret.

For at forstå hvilken, skal du vide, hvordan skær fungerer og den videre livsbane for data i tabeller over familiemotorer *MergeTree ClickHouse (diagrammer taget fra præsentationer Alexey Zatelepin):

  • indsat блок data. I vores tilfælde er disse målinger.
    ClickHouse + Graphite: Sådan reduceres forbrugt diskplads betydeligt
  • Hver sådan blok sorteres efter nøglen, før den skrives til disken. ORDER BYDen angivne, da tabellen blev oprettet.
  • Efter sortering, кусок (part) data skrives til disk.
    ClickHouse + Graphite: Sådan reduceres forbrugt diskplads betydeligt
  • Serveren overvåger i baggrunden, så der ikke er mange sådanne stykker, og starter baggrunden слияния (merge, flet derefter).
    ClickHouse + Graphite: Sådan reduceres forbrugt diskplads betydeligt
    ClickHouse + Graphite: Sådan reduceres forbrugt diskplads betydeligt
  • Serveren holder op med at lancere fusionerer af sig selv, så snart dataene stopper aktivt med at strømme ind партицию (partition), men du kan starte processen manuelt med kommandoen OPTIMIZE.
  • Hvis der kun er et stykke tilbage i partitionen, så vil du ikke være i stand til at starte sammenfletningen med den sædvanlige kommando, du skal bruge OPTIMIZE ... FINAL

Så de første målinger ankommer. Og de fylder lidt. Efterfølgende begivenheder kan variere noget afhængigt af mange faktorer:

  • Partitionsnøglen kan enten være meget lille (en dag) eller meget stor (adskillige måneder).
  • Opbevaringskonfigurationen kan passe til flere væsentlige dataaggregeringstærskler inde i den aktive partition (hvor metrikken er skrevet), eller måske ikke.
  • Hvis der er mange data, så vil de tidligste bidder, som allerede kan være enorme på grund af baggrundsfletning (når man vælger en ikke-optimal partitioneringsnøgle), ikke flette sig selv sammen med friske små bidder.

Og det ender altid det samme. Det sted, der er optaget af metrics i ClickHouse, vokser kun, hvis:

  • gælder ikke OPTIMIZE ... FINAL manuelt eller
  • indsæt ikke data i alle partitioner løbende for at starte en baggrundsfletning før eller siden

Den anden metode ser ud til at være den nemmeste at implementere, og derfor er den forkert og blev testet i første omgang.
Jeg skrev et ret simpelt python-script, der sender dummy-metrics for hver dag i de sidste 4 år og kører hver time med cron.
Da alt arbejdet i ClickHouse DBMS er baseret på det faktum, at dette system før eller siden vil gøre alt baggrundsarbejdet, men det vides ikke hvornår, nåede jeg ikke at vente på det øjeblik, hvor de gamle enorme stykker værdiger sig til at begynde at smelte sammen med nye små. Det blev klart, at vi skulle finde en måde at automatisere tvungne optimeringer på.

ClickHouse + Graphite: Sådan reduceres forbrugt diskplads betydeligt

Oplysninger i ClickHouse-systemtabeller

Lad os tage et kig på strukturen af ​​tabellen system.dele. Dette er omfattende information om hvert stykke af alle borde på ClickHouse-serveren. Indeholder blandt andet følgende kolonner:

  • database navn (database);
  • tabel navn (table);
  • partitionsnavn og ID (partition & partition_id);
  • da stykket blev skabt (modification_time);
  • minimum og maksimum dato i klumpen (opdeling er efter dag) (min_date & max_date);

Der er også et bord system.graphite_retentions, med følgende interessante felter:

  • database navn (Tables.database);
  • tabel navn (Tables.table);
  • alderen for metrikken, når den næste aggregering skal anvendes (age);

So:

  1. Vi har en tabel med bidder og en tabel med aggregeringsregler.
  2. Vi forener deres skæringspunkt, og vi modtager alle *GraphiteMergeTree-tabeller.
  3. Vi leder efter alle partitioner, hvor:
    • mere end et stykke
    • eller tiden er inde til at anvende den næste sammenlægningsregel, og modification_time ældre end dette øjeblik.

implementering

Denne anmodning

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

returnerer hver af *GraphiteMergeTree tabelpartitionerne, der skal flettes for at frigøre diskplads. Det er kun tilfældet for små ting: gennemgå dem alle med en anmodning OPTIMIZE ... FINAL. Den endelige implementering tog også højde for, at der ikke er behov for at røre partitioner med en aktiv registrering.

Det er, hvad projektet gør. grafit-ch-optimizer. Tidligere kolleger fra Yandex.Market testede det i produktionen, resultatet af arbejdet kan ses nedenfor.

ClickHouse + Graphite: Sådan reduceres forbrugt diskplads betydeligt

Hvis du kører programmet på en server med ClickHouse, vil det simpelthen begynde at arbejde i dæmontilstand. En gang i timen vil der blive udført en forespørgsel, som kontrollerer, om der er nye partitioner, der er ældre end tre dage, som kan optimeres.

I den nærmeste fremtid - for at give mindst deb-pakker, og hvis muligt - også rpm.

I stedet for en konklusion

I de sidste 9+ måneder har jeg været inde i mit firma innogames brugte meget tid på at lave mad i krydset mellem ClickHouse og grafit-web. Det var en god oplevelse, som resulterede i en hurtig overgang fra hvisken til ClickHouse som et lager af metrics. Jeg håber, at denne artikel er noget som starten på en cyklus om, hvilke forbedringer vi har lavet til forskellige dele af denne stak, og hvad der vil blive gjort i fremtiden.

Der blev brugt adskillige liter øl og admin-dage på udviklingen af ​​forespørgslen, sammen med v0devilsom jeg vil udtrykke min taknemmelighed over for ham. Og også for at gennemgå denne artikel.

Projektside på github

Kilde: www.habr.com

Tilføj en kommentar