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

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

Pozdrav, habr.

Ako netko iskorištava sustav grafitna mreža i naišao je na problem s izvedbom pohrane šapat (IO, potrošen prostor na disku), tada bi vjerojatnost da je ClickHouse postavljen kao zamjena trebala težiti jednoj. Ova izjava implicira da se implementacija treće strane već koristi kao demon koji prima metriku, na primjer pisac ugljika ili go-carbon.

ClickHouse dobro rješava opisane probleme. Na primjer, nakon prijenosa 2TiB podataka iz šapta, oni stanu u 300GiB. Neću se posebno zadržavati na usporedbi, ima dosta članaka na ovu temu. Osim toga, donedavno nije sve bilo savršeno s našim ClickHouse skladištem.

Problemi s potrošenim prostorom

Na prvi pogled sve bi trebalo dobro funkcionirati. Praćenje dokumentacija, izradite konfiguraciju za shemu pohrane metrike (dalje retention), zatim izradite tablicu prema preporuci odabrane pozadine za graphite-web: carbon-clickhouse+grafitna klizaljka ili grapnica, ovisno o tome koji se stog koristi. I... tempirana bomba eksplodira.

Da biste razumjeli koji, morate znati kako rade umetci i daljnji životni put podataka u tablicama motora obitelji *Spoji stablo ClickHouse (grafikoni preuzeti sa prezentacije Aleksej Zatelepin):

  • Umetnuto блок podaci. U našem slučaju, to je bila metrika koja je stigla.
    ClickHouse + Graphite: kako značajno smanjiti potrošnju prostora na disku
  • Svaki takav blok se sortira prema ključu prije nego što se zapiše na disk. ORDER BYnaveden prilikom izrade tablice.
  • Nakon sortiranja, кусок (part) podaci se zapisuju na disk.
    ClickHouse + Graphite: kako značajno smanjiti potrošnju prostora na disku
  • Poslužitelj prati u pozadini kako ne bi bilo puno takvih komada i pokreće pozadinu слияния (merge, u nastavku spojiti).
    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 samostalno izvoditi spajanja čim podaci prestanu aktivno teći u партицию (partition), ali proces možete pokrenuti ručno pomoću naredbe OPTIMIZE.
  • Ako je u particiji ostao samo jedan dio, tada nećete moći pokrenuti spajanje koristeći uobičajenu naredbu; morate koristiti OPTIMIZE ... FINAL

Dakle, stižu prve metrike. I zauzimaju malo prostora. Naknadni događaji mogu donekle varirati ovisno o mnogim čimbenicima:

  • Particioni ključ može biti vrlo mali (dan) ili vrlo velik (nekoliko mjeseci).
  • Konfiguracija zadržavanja može odgovarati nekoliko značajnih pragova agregacije podataka unutar aktivne particije (gdje se bilježe metrike) ili možda ne.
  • Ako postoji mnogo podataka, tada se najraniji dijelovi, koji zbog pozadinskog spajanja već mogu biti ogromni (ako odaberete neoptimalan ključ particioniranja), neće sami spojiti sa svježim malim dijelovima.

I uvijek završi isto. Prostor koji zauzimaju metrike u ClickHouseu povećava se samo ako:

  • ne primjenjivati OPTIMIZE ... FINAL ručno ili
  • nemojte kontinuirano unositi podatke u sve particije, tako da će prije ili kasnije započeti pozadinsko spajanje

Čini se da je drugu metodu najlakše implementirati i stoga je netočna i isprobana je prva.
Napisao sam prilično jednostavnu python skriptu koja je slala lažne metrike za svaki dan u posljednje 4 godine i pokretala cron svaki sat.
Budući da se cijeli rad ClickHouse DBMS-a temelji na činjenici da će ovaj sustav prije ili kasnije obaviti sve pozadinske poslove, ali ne zna se kada, nisam mogao dočekati trenutak kada će se stari ogromni komadi udostojiti da se počnu spajati s nove male. Postalo je jasno da moramo tražiti način automatizacije prisilnih optimizacija.

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

Podaci u tablicama sustava ClickHouse

Pogledajmo strukturu tablice sustav.dijelovi. Ovo su sveobuhvatne informacije o svakom dijelu svih stolova na poslužitelju ClickHouse. Sadrži, između ostalog, sljedeće stupce:

  • db ime (database);
  • naziv tablice (table);
  • naziv particije i ID (partition & partition_id);
  • kada je djelo stvoreno (modification_time);
  • minimalni i maksimalni datum u komadu (podjela se vrši po danima) (min_date & max_date);

Tu je i stol sustav.grafit_retencije, sa sljedećim zanimljivim poljima:

  • db ime (Tables.database);
  • naziv tablice (Tables.table);
  • metrička dob kada bi se trebala primijeniti sljedeća agregacija (age);

Dakle:

  1. Imamo tablicu komada i tablicu pravila združivanja.
  2. Kombiniramo njihovo sjecište i dobijemo sve tablice *GraphiteMergeTree.
  3. Tražimo sve particije u kojima:
    • više od jednog komada
    • ili je došlo vrijeme za primjenu sljedećeg pravila zbrajanja, i modification_time stariji od ovog trenutka.

Provedba

Ovaj zahtjev

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

vraća svaku od *GraphiteMergeTree particija tablice čije bi spajanje trebalo osloboditi prostor na disku. Jedino što preostaje je proći ih sve sa zahtjevom OPTIMIZE ... FINAL. Konačna implementacija također uzima u obzir činjenicu da nema potrebe dirati particije s aktivnim snimanjem.

To je upravo ono što projekt radi grafit-ch-optimizator. Bivši kolege iz Yandex.Marketa isprobali su ga u proizvodnji, rezultat rada možete vidjeti u nastavku.

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

Ako pokrenete program na poslužitelju s ClickHouseom, on će jednostavno početi raditi u daemon modu. Svakih sat vremena izvršavat će se zahtjev kojim se provjerava jesu li se pojavile nove particije starije od tri dana koje je moguće optimizirati.

Naši neposredni planovi su osigurati barem deb pakete, a ako je moguće i rpm.

Umjesto zaključka

Tijekom proteklih 9+ mjeseci bio sam u svojoj tvrtki innogames proveo puno vremena petljajući na raskrižju ClickHousea i graphite-weba. Bilo je to dobro iskustvo, koje je rezultiralo brzim prelaskom s whispera na ClickHouse kao pohranu metrike. Nadam se da je ovaj članak nešto kao početak niza o tome koja smo poboljšanja napravili na različitim dijelovima ovog skupa i što ćemo učiniti u budućnosti.

Nekoliko litara piva i admin dana potrošeno je na razvoj zahtjeva, zajedno s v0vrag, na čemu mu želim izraziti svoju zahvalnost. I također za recenziju ovog članka.

Stranica projekta na githubu

Izvor: www.habr.com

Dodajte komentar