ClickHouse + Graphite: kaip žymiai sumažinti disko vietos suvartojimą

ClickHouse + Graphite: kaip žymiai sumažinti disko vietos suvartojimą

Sveikinimai, habr.

Jei kas nors išnaudoja sistemą grafito tinklelis ir iškilo saugyklos našumo problema šnabždesys (IO, sunaudota vietos diske), tada tikimybė, kad ClickHouse buvo pakeista, turėtų būti viena. Šis teiginys reiškia, kad trečiosios šalies diegimas jau naudojamas kaip demonas, gaunantis metriką, pvz. anglies rašytojas arba go-carbon.

„ClickHouse“ gerai išsprendžia aprašytas problemas. Pavyzdžiui, perkėlus 2TiB duomenų iš whisper, jie telpa į 300GiB. Aš nesigilinsiu į palyginimą, yra daug straipsnių šia tema. Be to, iki šiol ne viskas buvo tobula naudojant mūsų ClickHouse saugyklą.

Problemos dėl sunaudotos vietos

Iš pirmo žvilgsnio viskas turėtų veikti gerai. Sekant dokumentacija, sukurkite metrikos saugojimo schemos konfigūraciją (toliau retention), tada sukurkite lentelę pagal pasirinktos grafito žiniatinklio užpakalinės programos rekomendaciją: anglies-clickhouse+grafitas-clickhouse arba graibštas, priklausomai nuo to, kuri krūva naudojama. Ir... susprogo uždelsto veikimo bomba.

Norėdami suprasti, kuris iš jų, turite žinoti, kaip veikia įdėklai ir tolesnis duomenų gyvenimo kelias * šeimos variklių lentelėseMergeTree ClickHouse (diagramos paimtos iš pristatymai Aleksejus Zatelepinas):

  • Įdėta блок duomenis. Mūsų atveju tai buvo metrika.
    ClickHouse + Graphite: kaip žymiai sumažinti disko vietos suvartojimą
  • Kiekvienas toks blokas prieš įrašant į diską surūšiuojamas pagal raktą. ORDER BYnurodyta kuriant lentelę.
  • Po rūšiavimo, кусок (part) duomenys įrašomi į diską.
    ClickHouse + Graphite: kaip žymiai sumažinti disko vietos suvartojimą
  • Serveris stebi fone, kad tokių dalių nebūtų daug, ir paleidžia foną слияния (merge, toliau sujungti).
    ClickHouse + Graphite: kaip žymiai sumažinti disko vietos suvartojimą
    ClickHouse + Graphite: kaip žymiai sumažinti disko vietos suvartojimą
  • Serveris nustoja vykdyti sujungimus, kai tik duomenys nustoja aktyviai tekėti į партицию (partition), tačiau procesą galite pradėti rankiniu būdu naudodami komandą OPTIMIZE.
  • Jei skaidinyje liko tik viena dalis, negalėsite paleisti sujungimo naudodami įprastą komandą, kurią turite naudoti OPTIMIZE ... FINAL

Taigi, ateina pirmieji rodikliai. Ir jie užima šiek tiek vietos. Vėlesni įvykiai gali šiek tiek skirtis priklausomai nuo daugelio veiksnių:

  • Skirstymo raktas gali būti labai mažas (diena) arba labai didelis (keli mėnesiai).
  • Išlaikymo konfigūracija gali atitikti keletą svarbių duomenų kaupimo slenksčių aktyviame skaidinyje (kur įrašoma metrika), o gal ir ne.
  • Jei duomenų yra daug, tada ankstyviausi gabalai, kurie dėl fono sujungimo jau gali būti didžiuliai (jei pasirinksite neoptimalų skaidymo raktą), nesusilies su naujais mažais gabalėliais.

Ir visada baigiasi tuo pačiu. „ClickHouse“ metrikos užimama vieta padidėja tik tada, jei:

  • netaikyti OPTIMIZE ... FINAL rankiniu būdu arba
  • neįterpkite duomenų į visus skaidinius nuolat, kad anksčiau ar vėliau prasidėtų foninis sujungimas

Antrasis metodas atrodo lengviausiai įgyvendinamas, todėl jis yra neteisingas ir buvo išbandytas pirmiausia.
Parašiau gana paprastą python scenarijų, kuris pastaruosius 4 metus kiekvieną dieną siųsdavo fiktyvią metriką ir paleidau cron kas valandą.
Kadangi visa ClickHouse DBVS veikla paremta tuo, kad ši sistema anksčiau ar vėliau atliks visus foninius darbus, bet nežinia kada, negalėjau sulaukti momento, kai senos didžiulės dalys ims susilieti su naujų mažų. Tapo aišku, kad turime ieškoti būdo, kaip automatizuoti priverstinius optimizavimus.

ClickHouse + Graphite: kaip žymiai sumažinti disko vietos suvartojimą

Informacija ClickHouse sistemos lentelėse

Pažvelkime į lentelės struktūrą sistema.dalys. Tai yra išsami informacija apie kiekvieną visų ClickHouse serverio lentelių dalį. Jame, be kita ko, yra šie stulpeliai:

  • db pavadinimas (database);
  • lentelės pavadinimas (table);
  • skaidinio pavadinimas ir ID (partition & partition_id);
  • kai kūrinys buvo sukurtas (modification_time);
  • minimali ir maksimali data gabale (skirstymas atliekamas pagal dieną) (min_date & max_date);

Taip pat yra stalas system.graphite_retentions, su šiais įdomiais laukais:

  • db pavadinimas (Tables.database);
  • lentelės pavadinimas (Tables.table);
  • metrinis amžius, kai turėtų būti taikomas kitas apibendrinimas (age);

Taigi:

  1. Turime dalių lentelę ir agregavimo taisyklių lentelę.
  2. Sujungiame jų sankirtą ir gauname visas lenteles *GraphiteMergeTree.
  3. Ieškome visų pertvarų, kuriose:
    • daugiau nei vienas gabalas
    • arba atėjo laikas taikyti kitą sumavimo taisyklę ir modification_time senesnis už šią akimirką.

Vykdymas

Šis prašymas

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

grąžina kiekvieną *GraphiteMergeTree lentelės skaidinį, kurių sujungimas turėtų atlaisvinti vietos diske. Belieka juos visus peržiūrėti su prašymu OPTIMIZE ... FINAL. Galutiniame įgyvendinime taip pat atsižvelgiama į tai, kad nereikia liesti skaidinių su aktyviu įrašymu.

Būtent tai ir daro projektas grafito-ch optimizatorius. Buvę kolegos iš Yandex.Market išbandė tai gamyboje, darbo rezultatą galite pamatyti žemiau.

ClickHouse + Graphite: kaip žymiai sumažinti disko vietos suvartojimą

Jei programą paleisite serveryje su ClickHouse, ji tiesiog pradės veikti demono režimu. Kartą per valandą bus vykdoma užklausa, tikrinama, ar neatsirado naujų skaidinių, senesnių nei trys dienos, kuriuos galima optimizuoti.

Mūsų artimiausi planai yra pateikti bent deb paketus ir, jei įmanoma, ir rpm.

Vietoj išvados

Per pastaruosius 9 ir daugiau mėnesių dirbau savo įmonėje „InnoGames“ praleido daug laiko dirbdamas ClickHouse ir grafito tinklo sankirtoje. Tai buvo gera patirtis, dėl kurios greitai perėjome nuo šnabždesio prie ClickHouse kaip metrikos saugyklos. Tikiuosi, kad šis straipsnis yra serijos apie tai, kokius patobulinimus atlikome įvairiose šio krūvos dalyse ir kas bus daroma ateityje, pradžia.

Keletas litrų alaus ir admin dienų buvo išleista kuriant prašymą, kartu su v0velnias, už ką noriu jam padėkoti. Ir taip pat už šio straipsnio peržiūrą.

Projekto puslapis github

Šaltinis: www.habr.com

Pirkite patikimą prieglobą svetainėms su DDoS apsauga, VPS VDS serveriais 🔥 Įsigykite patikimą svetainių talpinimą su DDoS apsauga, VPS VDS serveriais | ProHoster