ClickHouse + Graphite: kako bistveno zmanjšati porabo prostora na disku

ClickHouse + Graphite: kako bistveno zmanjšati porabo prostora na disku

Lep pozdrav, habr.

Če kdo izkorišča sistem grafitna mreža in je naletel na težavo z zmogljivostjo shranjevanja šepetati (IO, porabljen prostor na disku), potem bi morala biti možnost, da je bil ClickHouse izbran kot zamenjava, enaka eni. Ta izjava nakazuje, da se na primer implementacija tretje osebe že uporablja kot demon, ki prejema meritve carbonwriter ali go-ogljik.

ClickHouse dobro rešuje opisane težave. Na primer, po prenosu 2 TiB podatkov iz šepeta se prilegajo 300 GiB. Ne bom se podrobneje ukvarjal s primerjavo, člankov na to temo je veliko. Poleg tega do nedavnega z našo shrambo ClickHouse ni bilo vse popolno.

Težave s porabljenim prostorom

Na prvi pogled bi moralo vse delovati dobro. Sledim dokumentacijo, ustvarite konfiguracijo za shemo shranjevanja meritev (nadalje retention), nato ustvarite tabelo v skladu s priporočilom izbranega ozadja za graphite-web: ogljik+grafitna klikovnica ali graphouse, odvisno od uporabljenega sklada. In ... tempirana bomba eksplodira.

Da bi razumeli, kateri, morate vedeti, kako delujejo vstavki in nadaljnja življenjska pot podatkov v tabelah motorjev družine *MergeTree ClickHouse (grafi povzeti iz predstavitve Aleksej Zatelepin):

  • Vstavljeno блок podatke. V našem primeru so prispele metrike.
    ClickHouse + Graphite: kako bistveno zmanjšati porabo prostora na disku
  • Vsak tak blok je razvrščen glede na ključ, preden se zapiše na disk. ORDER BYdoločeno pri ustvarjanju tabele.
  • Po razvrščanju, кусок (part) se podatki zapišejo na disk.
    ClickHouse + Graphite: kako bistveno zmanjšati porabo prostora na disku
  • Strežnik spremlja v ozadju, da ni veliko takšnih kosov in zažene ozadje слияния (merge, v nadaljevanju združiti).
    ClickHouse + Graphite: kako bistveno zmanjšati porabo prostora na disku
    ClickHouse + Graphite: kako bistveno zmanjšati porabo prostora na disku
  • Strežnik sam preneha izvajati združevanja takoj, ko se podatki prenehajo aktivno pretakati v партицию (partition), vendar lahko postopek zaženete ročno z ukazom OPTIMIZE.
  • Če je v particiji ostal samo en kos, spajanja ne boste mogli zagnati z običajnim ukazom; morate uporabiti OPTIMIZE ... FINAL

Tako so prispele prve metrike. In zavzamejo nekaj prostora. Kasnejši dogodki se lahko nekoliko razlikujejo glede na številne dejavnike:

  • Particijski ključ je lahko zelo majhen (en dan) ali zelo velik (več mesecev).
  • Konfiguracija zadrževanja lahko ustreza več pomembnim pragom združevanja podatkov znotraj aktivne particije (kjer so zabeležene metrike) ali pa tudi ne.
  • Če je podatkov veliko, se najzgodnejši kosi, ki so zaradi združevanja v ozadju morda že ogromni (če izberete neoptimalen particijski ključ), ne bodo sami združili s svežimi majhnimi kosi.

In vedno se konča enako. Prostor, ki ga zasedajo meritve v ClickHouse, se poveča le, če:

  • ne veljajo OPTIMIZE ... FINAL ročno oz
  • ne vstavljajte podatkov sproti v vse particije, da se bo prej ali slej začelo spajanje v ozadju

Zdi se, da je druga metoda najlažja za izvedbo in zato ni pravilna in je bila preizkušena prva.
Napisal sem dokaj preprost skript python, ki je pošiljal navidezne meritve za vsak dan v zadnjih 4 letih in izvajal cron vsako uro.
Ker celotno delovanje ClickHouse DBMS temelji na dejstvu, da bo ta sistem prej ali slej opravil vse delo v ozadju, vendar ni znano kdaj, nisem mogel dočakati trenutka, ko se stari ogromni kosi usmilijo, da se začnejo spajati z nove male. Postalo je jasno, da moramo iskati način za avtomatizacijo vsiljenih optimizacij.

ClickHouse + Graphite: kako bistveno zmanjšati porabo prostora na disku

Informacije v sistemskih tabelah ClickHouse

Oglejmo si strukturo tabele sistem.deli. To so izčrpne informacije o vsakem delu vseh tabel na strežniku ClickHouse. Med drugim vsebuje naslednje stolpce:

  • db ime (database);
  • ime tabele (table);
  • ime in ID particije (partition & partition_id);
  • ko je komad nastal (modification_time);
  • minimalni in maksimalni datum v kosu (razdelitev poteka po dnevih) (min_date & max_date);

Obstaja tudi miza sistem.zadrževanje_grafita, z naslednjimi zanimivimi polji:

  • db ime (Tables.database);
  • ime tabele (Tables.table);
  • metrična starost, ko je treba uporabiti naslednje združevanje (age);

Torej:

  1. Imamo tabelo kosov in tabelo pravil združevanja.
  2. Njihovo presečišče združimo in dobimo vse tabele *GraphiteMergeTree.
  3. Iščemo vse particije, v katerih:
    • več kot en kos
    • ali je prišel čas za uporabo naslednjega pravila združevanja in modification_time starejši od tega trenutka.

Реализация

Ta zahteva

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

vrne vsako od particij tabele *GraphiteMergeTree, katerih združitev bi morala sprostiti prostor na disku. Edina stvar, ki jo morate storiti, je, da jih pregledate z zahtevo OPTIMIZE ... FINAL. Končna izvedba upošteva tudi dejstvo, da se ni treba dotikati particij z aktivnim snemanjem.

Točno to počne projekt grafit-ch-optimizator. Nekdanji kolegi iz Yandex.Market so ga preizkusili v proizvodnji, rezultat dela si lahko ogledate spodaj.

ClickHouse + Graphite: kako bistveno zmanjšati porabo prostora na disku

Če program zaženete na strežniku s ClickHouse, bo preprosto začel delovati v demonskem načinu. Enkrat na uro se izvede zahteva, ki preverja, ali so se pojavile nove particije, starejše od treh dni, ki jih je mogoče optimizirati.

Naši neposredni načrti so, da zagotovimo vsaj deb pakete in, če je mogoče, tudi rpm.

Namesto zaključka

V zadnjih 9+ mesecih sem bil v svojem podjetju neigre preživel veliko časa na presečišču ClickHouse in graphite-web. Bila je dobra izkušnja, ki je privedla do hitrega prehoda s šepetanja na ClickHouse kot shrambo metrik. Upam, da je ta članek nekakšen začetek niza o tem, katere izboljšave smo naredili na različnih delih tega sklada in kaj bomo naredili v prihodnosti.

Za razvoj zahteve je bilo porabljenih več litrov piva in administratorskih dni, skupaj z v0devil, za kar se mu želim zahvaliti. In tudi za pregled tega članka.

Stran projekta na githubu

Vir: www.habr.com

Dodaj komentar