ClickHouse + Graphite: kako značajno smanjiti potrošnju prostora na disku

ClickHouse + Graphite: kako značajno smanjiti potrošnju prostora na disku

Pozdravljam vas, habr.

Ako je netko eksploatirao sustav graphite-web i naišao na probleme s performansama pohrane whisper (IO, zauzeto diskovno mjesto), tada bi šansa da pogleda ClickHouse kao zamjenu trebala težiti jedinici. Ova tvrdnja podrazumijeva da je kao mjerač metrika već korištena treća strana, na primjer carbonwriter ili go-carbon.

ClickHouse dobro rješava opisane probleme. Na primjer, nakon migracije 2TiB podataka iz whispera, oni su stali u 300GiB. Neću se zadržavati na usporedbi, ima dovoljno članaka na tu temu. Osim toga, do nedavno nije sve bilo idealno s našim ClickHouse skladištem.

Problemi s zauzetim mjestom

Na prvi pogled, sve bi trebalo raditi dobro. Slijedeći dokumentaciju, kreiramo konfiguraciju za shemu pohrane metrika (dalje retention), zatim kreiramo tablicu prema preporuci odabranog backend-a za graphite-web: carbon-clickhouse+graphite-clickhouse ili graphouse, ovisno o tome koji se skup koristi. I... aktivira se vrijeme odmaka.

Da bismo razumjeli koja, trebamo znati kako funkcioniraju umetanja i daljnji životni put podataka u tablicama motora *MergeTree ClickHouse (dijagrami preuzeti iz prezentacije Alekseja Zatelepin):

  • Umetanje bloka podataka. U našem slučaju to su stigle metrike.
    ClickHouse + Graphite: kako značajno smanjiti potrošnju prostora na disku
  • Svaki takav blok se sortira prema ključu ORDER BY, navedenom prilikom kreiranja tablice.
  • Nakon sortiranja, komad (part) podataka se zapisuje na disk.
    ClickHouse + Graphite: kako značajno smanjiti potrošnju prostora na disku
  • Poslužitelj u pozadini prati da takvih komada ne bude previše i pokreće pozadinske spajanja (merge, zatim se obavljaju mergenja.
    ClickHouse + Graphite: kako značajno smanjiti potrošnju prostora na disku
    ClickHouse + Graphite: kako značajno smanjiti potrošnju prostora na disku
  • Poslužitelj prestaje automatski pokretati mergenje čim podaci prestanu aktivno dolaziti u particiju (partition), ali proces se može pokrenuti ručno naredbom OPTIMIZE.
  • Ako u particiji ostane samo jedan komad, ručno pokretanje mergenja neće biti moguće, potrebno je koristiti OPTIMIZE ... FINAL

Dakle, dolaze prve metrike. I one zauzimaju određeni prostor. Sljedeći događaji mogu se malo razlikovati ovisno o mnogim faktorima:

  • Ključ particioniranja može biti vrlo mali (dan) ili vrlo velik (nekoliko mjeseci).
  • Konfiguracija retenzije može sadržavati nekoliko značajnih pragova agregacije podataka unutar aktivne particije (gdje se pišu metrike), ili ne mora.
  • Ako ima jako mnogo podataka, najraniji dijelovi, koji mogu biti ogromni zbog pozadinskih spajanja (pri izboru neoptimalnog ključa particioniranja), neće se spojiti sa novim malim dijelovima.

I sve uvijek završava na isti način. Prostor koji zauzimaju metrike u ClickHouse samo raste ako:

  • ne primjenjujete OPTIMIZE ... FINAL ručno ili
  • ne umetnete podatke u sve particije na stalnoj osnovi, kako biste ranije ili kasnije pokrenuli pozadinsko spajanje.

Drugi način čini se najjednostavnijim za implementaciju i, stoga, on je pogrešan i isproban prije svega.
Napisao sam dovoljno jednostavan skript na Pythonu koji je slao lažne metrike za svaki dan u protekle 4 godine i pokretao se svaki sat putem krona.
Budući da je sav rad ClickHouse DBMS-a izgrađen na tome da će ovaj sustav ranije ili kasnije obaviti sav pozadinski rad, ali nije poznato kada, nisam uspio dočekati trenutak kada će stari ogromni dijelovi početi spajati s novim malim. Postalo je jasno da trebam potražiti način za automatizaciju prisilnih optimizacija.

ClickHouse + Graphite: kako značajno smanjiti potrošnju prostora na disku

Informacije u sistemskim tablicama ClickHouse

Pogledajmo strukturu tablice system.parts. Ovo je iscrpna informacija o svakom dijelu svih tablica na serveru ClickHouse. Sadrži, između ostalog, sljedeće stupce:

  • ime Baze podataka (database);
  • ime tablice (table);
  • ime i ID particije (partition & partition_id);
  • kada je dio stvoren (modification_time);
  • minimalni i maksimalni datum u dijelu (particioniranje ide po danima) (min_date & max_date);

Također postoji tablica system.graphite_retentions, sa sljedećim zanimljivim poljima:

  • ime Baze podataka (Tables.database);
  • ime tablice (Tables.table);
  • starost metrike kada bi sljedeća agregacija trebala biti primijenjena (age);

Dakle:

  1. Imamo tablicu dijelova i tablicu pravila agregacije.
  2. Kombiniramo njihov presjek i dobivamo sve tablice *GraphiteMergeTree.
  3. Tražimo sve particije u kojima:
    • ima više od jednog dijela
    • ili je došlo vrijeme za primjenu sljedećeg pravila agregacije, i modification_time stariji su od tog trenutka.

Implementacija

Ovaj upit

ODABERITE
    concat(p.database, '.', p.table) AS table,
    p.partition_id AS partition_id,
    p.partition AS partition,
    -- Najstarije pravilo koje se može primijeniti za
    -- particiju, ali ne i u budućnosti, sm (*)
    max(g.age) AS age,
    -- Broj dijelova u particiji
    countDistinct(p.name) AS parts,
    -- Najstarija metrika u particiji se smatra 00:00:00 sljedećeg dana
    toDateTime(max(p.max_date + 1)) AS max_time,
    -- Kada bi particija trebala biti optimizirana
    max_time + age AS rollup_time,
    -- Kada je najstariji dio u particiji ažuriran
    min(p.modification_time) AS modified_at
IZ sustava.parts AS p
UNUTAR JE
(
    -- Sva pravila za sve tablice *GraphiteMergeTree
    ODABERITE
        Tables.database AS database,
        Tables.table AS table,
        age
    IZ sustava.graphite_retentions
    ARRAY JOIN Tables
    GRUPIRAJ PREMA
        database,
        table,
        age
) AS g ON
    (p.table = g.table)
    I (p.database = g.database)
GDE
    -- Samo aktivni dijelovi
    p.active
    -- (*) I samo redovi gdje pravila agregacije već trebaju biti primijenjena
    I ((toDateTime(p.max_date + 1) + g.age) < now())
GRUPIRAJ PREMA
    table,
    partition
IMAJUĆI NA UMU
    -- Samo particije koje su mlađe od trenutka optimizacije
    (modified_at  1)
POREDAJ
    table ASC,
    partition ASC,
    age ASC

vraća svaku od particija tablica *GraphiteMergeTree, čiji bi spoj trebao dovesti do oslobađanja diskovnog prostora. Ostalo je samo proći kroz njih s upitom OPTIMIZE ... FINAL. U konačnoj realizaciji također je uzet u obzir taj moment da se particije s aktivnim zapisom ne trebaju dodirivati.

Upravo to čini projekt graphite-ch-optimizer. Bivši kolege iz Yandex.Market su ga testirali u produkciji, rezultat rada možete vidjeti dolje.

ClickHouse + Graphite: kako značajno smanjiti potrošnju prostora na disku

Ako pokrenete program na serveru s ClickHouse, jednostavno će početi raditi u režimu demona. Svakih sat vremena će se izvršavati upit, provjeravajući jesu li se pojavile nove particije starije od tri dana koje je moguće optimizirati.

U bliskim planovima — pružiti, barem, deb pakete, a ako je moguće — i rpm.

Umjesto zaključka

U proteklih 9 i više mjeseci unutar svoje kompanije InnoGames provela sam mnogo vremena, radeći na spoju ClickHouse i graphite-web. To je bilo dobro iskustvo, a rezultat svih radova omogućava brzi prelazak s whisper na ClickHouse kao skladište metrika. Nadam se da je ovaj članak inicijalna točka ciklusa o tome koje su promjene unesene u različite dijelove ovog stoga i što će biti učinjeno u budućnosti.

Na izradu upita potrošeno je nekoliko litara piva i admin-dana zajedno s v0devil, za što mu želim izraziti svoju zahvalnost. Također i za recenziranje ovog članka.

Stranica projekta na githubu

Izvor: habr.com

Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere 🔥 Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere | ProHoster