ClickHouse + Graphite: kuidas diskiruumi kasutust oluliselt vähendada

ClickHouse + Graphite: kuidas diskiruumi kasutust oluliselt vähendada

Tere tulemast, habr.

Kui keegi kasutab süsteemi graphite-web ja on kohanud salvestusprobleemide toime efektiivsust whisper (IO, kasutatud kettaruumi), siis tõenäosus, et vaadatakse ClickHouse'i alternatiivina, peaks olema peaaegu 100%. See eeldab, et mõõtemetoodika demon on juba kolmanda osapoole teostus, näiteks carbonwriter või go-carbon.

ClickHouse lahendab kirjeldatud probleemid hästi. Näiteks, pärast 2TiB andmete ülekanne whisper'ist mahtusid need 300GiB sisse. Ma ei hakka detailide võrdlemisega vaeva nägema, sellel teemal on piisavalt artikleid. Lisaks, kuni hiljuti polnud meie ClickHouse'i salvestamine täiesti ideaalne.

Probleemid salvestusruumiga

Esmapilgul peaks kõik tööle hakkama. Järgides dokumentatsioonis, loome metoodika salvestamise skeemi konfiguratsiooni (edasi retention), luuakse siis tabel vastavalt valitud veebiteenuse soovitusele: carbon-clickhouse+graphite-clickhouse või graphouse, sõltuvalt sellest, millist tehnolooge kasutusele võetakse. Ja... käivitub aeglane plahvatus.

Selleks, et mõista, milline see on, tuleb teada, kuidas töötavad sisestused ja edasine andmete eluiga tabelites, mis kuuluvad *semeenrikondade*MergeTree ClickHouse (diagrammid on saadud esitluses Aleksei Zatelepini):

  • Sisestatakse plokk andmeid. Meie puhul on need juhtunud metriigid.
    ClickHouse + Graphite: kuidas diskiruumi kasutust oluliselt vähendada
  • Iga selline plokk sorteeritakse enne kettale kirjutamist vastavalt võtmele, ORDER BY, mis on määratud tabeli loomisel.
  • Pärast sorteerimist tükk (part) andmeid kirjutatakse kettale.
    ClickHouse + Graphite: kuidas diskiruumi kasutust oluliselt vähendada
  • Server jälgib taustal, et selliseid tükke ei oleks liiga palju, ning käivitab taustal ühinemisi (merge, edasised mergenud).
    ClickHouse + Graphite: kuidas diskiruumi kasutust oluliselt vähendada
    ClickHouse + Graphite: kuidas diskiruumi kasutust oluliselt vähendada
  • Server lõpetab ühinemise automaatse käivitamise, kui andmed enam ei voola aktiivselt partitsiooni (partition), kuid protsessi saab käsitsi käivitada käsuga OPTIMIZE.
  • Kui partitsioonis on jäänud ainult üks tükk, siis ei saa tavalise käsuga ühinemist käivitada, vaid tuleb kasutada OPTIMIZE ... FINAL

Nii et esimesed metriigid on käes. Ja nad võtavad teatud ruumi. Edasised sündmused võivad varieeruda palju, sõltuvalt paljusid tegureid:

  • Partitsiooni võtmed võivad olla kas väga väikesed (päev) või väga suured (mitu kuud).
  • Retention konfiguratsioon võib mahutada mitu olulist andmete aggregatsiooni läve aktiivses partitsioonis (kuhu kirjutatakse mõõdikud), aga see ei pruugi nii olla.
  • Kui andmeid on väga palju, siis varasemad osad, mis taustal toimuvate ühendamiste tõttu võivad olla juba suured (kui valitakse mittesoovitav partitsioneerimise võti), ei ühtistu enam värskete väikeste osadega.

Ja kõik lõppeb alati ühtemoodi. ClickHouse'is võetud mõõdikute ruum ainult suureneb, kui:

  • ei rakendata OPTIMIZE ... FINAL käsitsi või
  • ei sisestata andmeid kõikidesse partitsioonidesse pidevalt, et varem või hiljem käivitada taustal toimuv ühendamine.

Teine meetod tundub kõige lihtsam teostada ja seetõttu on see vale ning on esmalt testitud.
Olen kirjutanud piisavalt lihtsa skripti Pythonis, mis saatis vale mõõdikud iga päeva kohta viimase nelja aasta jooksul ja käivitati iga tunne croni abil.
Kuna kogu ClickHouse DBMS-i töö põhineb sellel, et see süsteem teeb varem või hiljem kogu taustatöö, kuid ei ole teada, millal, ei olnud mul võimalik oodata hetke, mil vanad suured tükkid lähevad kokku uute väikeste tükkidega. Selgeks sai, et tuleb leida viis sunnitud optimeerimise automatiseerimiseks.

ClickHouse + Graphite: kuidas diskiruumi kasutust oluliselt vähendada

Teave ClickHouse süsteemitabelites

Vaadakem tabeli struktuuri system.parts. See on ammendav teave iga tüki kohta kõigis ClickHouse serveri tabelites. See sisaldab muu hulgas järgmisi veerge:

  • andmebaasi nimi (database);
  • tabeli nimi (tabel);
  • partitsiooni nimi ja ID (partition & partition_id);
  • millal tükk loodi (modification_time);
  • minimaalne ja maksimaalne kuupäev tükkis (partitsioneerimine toimub päevade kaupa) (min_date & max_date);

Samuti on olemas tabel system.graphite_retentions, järgmiste huvitavate väljadega:

  • andmebaasi nimi (Tables.database);
  • tabeli nimi (Tables.table);
  • metri vanus, millal peaks järgmist aggregatsiooni rakendama (age);

Nii et:

  1. Meil on tükki ja aggregatsiooni reeglite tabel.
  2. Kombineerime nende lõike ja saame kõik tabelid *GraphiteMergeTree.
  3. Otsime kõik partitsioonid, kus:
    • rohkem kui üks tükk
    • või on aeg rakendada järgmist aggregatsioonireeglit, ning modification_time on vanem kui see hetk.

Rakendus

See päring

SELECT
    concat(p.database, '.', p.table) AS table,
    p.partition_id AS partition_id,
    p.partition AS partition,
    -- Kõige "vanem" reegel, mida saab применить для
    -- partitsiooni, kuid mitte tulevikus, vt (*)
    max(g.age) AS age,
    -- Osade arv partitsioonis
    countDistinct(p.name) AS parts,
    -- Kõige vanemaks metrikaks partitsioonis loetakse 00:00:00 järgmisel päeval
    toDateTime(max(p.max_date + 1)) AS max_time,
    -- Millal partitsioon tuleks optimeerida
    max_time + age AS rollup_time,
    -- Millal kõige vanem tükk partitsioonis viimane kord uuendati
    min(p.modification_time) AS modified_at
FROM system.parts AS p
INNER JOIN
(
    -- Kõik reeglid kõikidele tabelitele *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
    -- Ainult aktiivsed tükid
    p.active
    -- (*) Ja ainult need read, kus agregatsiooni reegleid peaks juba rakendama
    AND ((toDateTime(p.max_date + 1) + g.age) < now())
GROUP BY
    table,
    partition
HAVING
    -- Ainult partitsioonid, mis on nooremad optimeerimise hetkest
    (modified_at  1)
ORDER BY
    table ASC,
    partition ASC,
    age ASC

tagastab iga tabeli partitsiooni *GraphiteMergeTree, mille merge peaks vabastama kettaruumi. Järgnevalt tuleb ainult läbi käia kõik koos päringuga OPTIMIZE ... FINAL. Lõhnavas teostuses on arvesse võetud ka, et aktiivses kirjutamises olevate partitsioonide kallale minna ei ole vaja.

Just seda teeb projekt graphite-ch-optimizer. Endised kolleegid Yandex.Market'ist on seda tootmises proovinud, töötulemusi võib näha allpool.

ClickHouse + Graphite: kuidas diskiruumi kasutust oluliselt vähendada

Kui käivitada programm серверi ClickHouse'is, siis hakkab see lihtsalt tööle deemonirežiimis. Iga tunni tagant käivitatakse päring, et kontrollida, kas on ilmunud uusi üle kolme päeva vanuseid partitsioone, mida saaks optimeerida.

Lähitulevikus plaanime pakkuda vähemalt deb pakette ja võimalusel ka rpm.

Kokkuvõtte asemel

Viimase üheksast kuust olen oma ettevõttes InnoGames olen veetnud palju aega, uurides ClickHouse'i ja graphite-web'i vahepealses olukorras. See oli hea kogemus, mille tulemuseks oli kiire üleminek whisper'ilt ClickHouse'ile mõõdikute salvestamiseks. Loodan, et see artikkel on midagi nagu algus tsüklile, mis käsitleb meie tehtud täiustusi erinevates selle stack'i osades ja mida tulevikus plaanitakse.

Küsimuse väljatöötamiseks kulus mitu liitrit õlut ja administratiivpäevi koos v0devil, kellele tahan väljendada oma tänu. Samuti tema kommentaaride eest selle artikli üle.

Projekti leht githubis

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster