ClickHouse + Graphite: Hoe om skyfspasie wat verbruik word aansienlik te verminder

ClickHouse + Graphite: Hoe om skyfspasie wat verbruik word aansienlik te verminder

Groete, habr.

As iemand die stelsel uitbuit grafiet-web en het 'n probleem met bergingwerkverrigting ondervind fluister (IO, skyfspasie verbruik), dan moet die kans dat ClickHouse as 'n plaasvervanger gegooi is, na een wees. Hierdie stelling impliseer dat 'n derdeparty-implementering reeds gebruik word as 'n daemon-ontvangsmaatstawwe, byvoorbeeld koolstofskrywer of go-koolstof.

ClickHouse los die beskryf probleme goed op. Byvoorbeeld, na die oordrag van 2TiB data vanaf fluister, pas hulle in 300GiB. Ek sal nie in detail by die vergelyking stilstaan ​​nie; daar is baie artikels oor hierdie onderwerp. Boonop was alles tot onlangs nie perfek met ons ClickHouse-berging nie.

Probleme met verbruikte spasie

Met die eerste oogopslag behoort alles goed te werk. Volgende dokumentasie, skep 'n konfigurasie vir die metrieke bergingskema (verder retention), skep dan 'n tabel volgens die aanbeveling van die geselekteerde agterkant vir graphite-web: koolstof-klikhuis+grafiet-klikhuis of graafhuis, afhangende van watter stapel gebruik word. En... die tydbom gaan af.

Om te verstaan ​​watter een, moet jy weet hoe insetsels werk en die verdere lewenspad van data in tabelle van enjins van die * familieMergeTree ClickHouse (kaarte geneem uit aanbiedings Alexey Zatelepin):

  • Ingevoeg Π±Π»ΠΎΠΊ data. In ons geval was dit die maatstawwe wat opgedaag het.
    ClickHouse + Graphite: Hoe om skyfspasie wat verbruik word aansienlik te verminder
  • Elke so 'n blok word volgens die sleutel gesorteer voordat dit na skyf geskryf word. ORDER BYgespesifiseer wanneer die tabel geskep word.
  • Na sortering, кусок (part) data word na skyf geskryf.
    ClickHouse + Graphite: Hoe om skyfspasie wat verbruik word aansienlik te verminder
  • Die bediener monitor in die agtergrond sodat daar nie baie sulke stukke is nie, en begin agtergrond слияния (merge, hierna saamsmelt).
    ClickHouse + Graphite: Hoe om skyfspasie wat verbruik word aansienlik te verminder
    ClickHouse + Graphite: Hoe om skyfspasie wat verbruik word aansienlik te verminder
  • Die bediener hou op om saamsmelt op sy eie te loop sodra data ophou aktief in die ΠΏΠ°Ρ€Ρ‚ΠΈΡ†ΠΈΡŽ (partition), maar jy kan die proses handmatig begin met die opdrag OPTIMIZE.
  • As daar net een stuk in die partisie oor is, sal jy nie die samevoeging met die gewone opdrag kan laat loop nie; jy moet gebruik OPTIMIZE ... FINAL

So, die eerste maatstawwe kom. En hulle neem 'n bietjie spasie op. Daaropvolgende gebeurtenisse kan ietwat verskil, afhangende van baie faktore:

  • Die partisiesleutel kan Γ³f baie klein ('n dag) Γ³f baie groot ('n paar maande) wees.
  • Die behoudopstelling kan verskeie beduidende data-aggregasiedrempels binne die aktiewe partisie pas (waar metrieke aangeteken word), of dalk nie.
  • As daar baie data is, sal die vroegste stukke, wat as gevolg van agtergrondsamevoeging reeds groot kan wees (as jy 'n nie-optimale partisiesleutel kies), nie hulself met vars klein stukke saamsmelt nie.

En dit eindig altyd dieselfde. Die spasie wat deur maatstawwe in ClickHouse in beslag geneem word, neem net toe as:

  • aansoek doen nie OPTIMIZE ... FINAL handmatig of
  • moenie data op 'n deurlopende basis in alle partisies invoeg nie, sodat vroeΓ«r of later 'n agtergrondsamesmelting sal begin

Die tweede metode blyk die maklikste te wees om te implementeer en daarom is dit verkeerd en is eers probeer.
Ek het 'n redelik eenvoudige luislangskrif geskryf wat die afgelope 4 jaar dummy-statistieke vir elke dag gestuur het en elke uur cron gehardloop het.
Aangesien die hele werking van ClickHouse DBMS gebaseer is op die feit dat hierdie stelsel vroeΓ«r of later al die agtergrondwerk sal doen, maar dit is nie bekend wanneer nie, kon ek nie wag vir die oomblik wanneer die ou groot stukke waardig is om te begin saamsmelt met nuwe kleintjies. Dit het duidelik geword dat ons 'n manier moet soek om gedwonge optimalisering te outomatiseer.

ClickHouse + Graphite: Hoe om skyfspasie wat verbruik word aansienlik te verminder

Inligting in ClickHouse-stelseltabelle

Kom ons kyk na die tabelstruktuur stelsel.onderdele. Dit is omvattende inligting oor elke stuk van alle tabelle op die ClickHouse-bediener. Bevat onder andere die volgende kolomme:

  • db naam (database);
  • tabel naam (table);
  • partisie naam en ID (partition & partition_id);
  • toe die stuk geskep is (modification_time);
  • minimum en maksimum datum in 'n stuk (verdeling word per dag gedoen) (min_date & max_date);

Daar is ook 'n tafel system.graphite_retentions, met die volgende interessante velde:

  • db naam (Tables.database);
  • tabel naam (Tables.table);
  • metrieke ouderdom wanneer die volgende samevoeging toegepas moet word (age);

Dus:

  1. Ons het 'n tabel van stukke en 'n tabel van samevoegingsreΓ«ls.
  2. Ons kombineer hul kruising en kry alle tabelle *GraphiteMergeTree.
  3. Ons is opsoek na alle partisies waarin:
    • meer as een stuk
    • of die tyd het aangebreek om die volgende samevoegingsreΓ«l toe te pas, en modification_time ouer as hierdie oomblik.

Implementering

Hierdie versoek

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

gee elkeen van die *GraphiteMergeTree-tabelpartisies terug waarvan die samevoeging skyfspasie moet vrymaak. Die enigste ding om te doen is om deur hulle almal te gaan met 'n versoek OPTIMIZE ... FINAL. Die finale implementering neem ook die feit in ag dat dit nie nodig is om partisies met aktiewe opname aan te raak nie.

Dit is presies wat die projek doen grafiet-ch-optimiseerder. Voormalige kollegas van Yandex.Market het dit in produksie probeer, die resultaat van die werk kan hieronder gesien word.

ClickHouse + Graphite: Hoe om skyfspasie wat verbruik word aansienlik te verminder

As jy die program op 'n bediener met ClickHouse laat loop, sal dit eenvoudig in daemon-modus begin werk. Een keer per uur sal 'n versoek uitgevoer word, om te kyk of nuwe partisies ouer as drie dae verskyn het wat geoptimaliseer kan word.

Ons onmiddellike planne is om ten minste deb-pakkette te verskaf, en indien moontlik ook rpm.

In plaas daarvan om 'n gevolgtrekking

Oor die afgelope 9+ maande was ek in my maatskappy innogames het baie tyd spandeer om te peuter by die kruising van ClickHouse en grafietweb. Dit was 'n goeie ervaring, wat gelei het tot 'n vinnige oorgang van fluistering na ClickHouse as 'n statistiekberging. Ek hoop hierdie artikel is iets van die begin van 'n reeks oor watter verbeterings ons aan verskeie dele van hierdie stapel aangebring het, en wat in die toekoms gedoen sal word.

Etlike liters bier en admin dae is bestee aan die ontwikkeling van die versoek, tesame met v0 duiwel, waarvoor ek my dank aan hom wil betuig. En ook vir die hersiening van hierdie artikel.

Projekbladsy op github

Bron: will.com

Voeg 'n opmerking