ClickHouse + Graphite: kuinka vähentää merkittävästi levytilan kulutusta

ClickHouse + Graphite: kuinka vähentää merkittävästi levytilan kulutusta

Tervehdys, habr.

Jos joku käyttää järjestelmää hyväkseen grafiittiverkko ja kohtasi tallennustilan suorituskykyongelman kuiskaus (IO, levytila ​​kulutettu), todennäköisyyden, että ClickHouse valettiin tilalle, pitäisi olla yksi. Tämä lausunto tarkoittaa, että kolmannen osapuolen toteutusta käytetään jo datamonina, joka vastaanottaa mittareita, esimerkiksi hiilikirjoittaja tai go-carbon.

ClickHouse ratkaisee kuvatut ongelmat hyvin. Esimerkiksi siirrettyään 2 TiB dataa whisperistä ne mahtuvat 300 GiB:iin. En viipyy vertailussa yksityiskohtaisesti, tästä aiheesta on paljon artikkeleita. Lisäksi vielä viime aikoihin asti kaikki ei ollut täydellistä ClickHouse-tallennustilassamme.

Ongelmia kulutetun tilan kanssa

Ensi silmäyksellä kaiken pitäisi toimia hyvin. Seurata dokumentointi, luo määritys mittaustietojen tallennusmallille (lisäksi retention), luo sitten taulukko valitun taustaohjelman suosituksen mukaan grafiittiverkkoa varten: hiili-clickhouse+grafiitti-clickhouse tai viljatalo, riippuen käytetystä pinosta. Ja... aikapommi räjähtää.

Ymmärtääksesi kumpi, sinun on tiedettävä, kuinka insertit toimivat ja tietojen myöhempi elämänpolku *-perheen moottoritaulukoissaMergeTree ClickHouse (kaaviot otettu kohteesta esitykset Aleksei Zatelepin):

  • Lisätty блок tiedot. Meidän tapauksessamme mittarit saapuivat.
    ClickHouse + Graphite: kuinka vähentää merkittävästi levytilan kulutusta
  • Jokainen tällainen lohko lajitellaan avaimen mukaan ennen levylle kirjoittamista. ORDER BYmääritetty taulukkoa luotaessa.
  • Lajittelun jälkeen кусок (part) tiedot kirjoitetaan levylle.
    ClickHouse + Graphite: kuinka vähentää merkittävästi levytilan kulutusta
  • Palvelin tarkkailee taustalla, jotta tällaisia ​​kappaleita ei ole paljon, ja käynnistää taustan слияния (merge, jäljempänä yhdistäminen).
    ClickHouse + Graphite: kuinka vähentää merkittävästi levytilan kulutusta
    ClickHouse + Graphite: kuinka vähentää merkittävästi levytilan kulutusta
  • Palvelin lopettaa yhdistämisten suorittamisen itsestään heti, kun data lakkaa virtaamasta aktiivisesti palvelimeen партицию (partition), mutta voit aloittaa prosessin manuaalisesti komennolla OPTIMIZE.
  • Jos osiossa on jäljellä vain yksi kappale, et voi suorittaa yhdistämistä tavallisella komennolla; sinun on käytettävä OPTIMIZE ... FINAL

Joten ensimmäiset mittarit saapuvat. Ja ne vievät jonkin verran tilaa. Myöhemmät tapahtumat voivat vaihdella jonkin verran useista tekijöistä riippuen:

  • Osiointiavain voi olla joko hyvin pieni (päivä) tai erittäin suuri (useita kuukausia).
  • Säilytyskokoonpano voi sopia useisiin merkittäviin datan aggregointikynnyksiin aktiivisen osion sisällä (johon mittarit tallennetaan), tai ehkä ei.
  • Jos dataa on paljon, niin varhaisimmat palat, jotka taustan yhdistämisen vuoksi voivat olla jo valtavia (jos valitset ei-optimaalisen osiointiavaimen), eivät sulaudu uusiin pieniin paloihin.

Ja se päättyy aina samalla tavalla. Mittareiden käyttämä tila ClickHousessa kasvaa vain, jos:

  • Älä lisää OPTIMIZE ... FINAL manuaalisesti tai
  • Älä lisää tietoja kaikkiin osioihin jatkuvasti, jotta ennemmin tai myöhemmin taustayhdistys alkaa

Toinen menetelmä näyttää olevan helpoin toteuttaa, ja siksi se on virheellinen ja sitä kokeiltiin ensin.
Kirjoitin melko yksinkertaisen python-skriptin, joka lähetti fiktiivisiä mittareita joka päivälle viimeisen 4 vuoden ajan ja suoritti cronin tunnin välein.
Koska ClickHouse DBMS:n koko toiminta perustuu siihen, että tämä järjestelmä tekee ennemmin tai myöhemmin kaikki taustatyöt, mutta ei tiedetä milloin, en malttanut odottaa hetkeä, jolloin vanhat valtavat palaset alkavat sulautua uusia pieniä. Kävi selväksi, että meidän oli etsittävä tapa automatisoida pakotetut optimoinnit.

ClickHouse + Graphite: kuinka vähentää merkittävästi levytilan kulutusta

Tiedot ClickHouse-järjestelmätaulukoissa

Katsotaanpa taulukon rakennetta system.parts. Tämä on kattavaa tietoa kaikista ClickHouse-palvelimen taulukoista. Sisältää muun muassa seuraavat sarakkeet:

  • db nimi (database);
  • taulukon nimi (table);
  • osion nimi ja tunnus (partition & partition_id);
  • kun teos luotiin (modification_time);
  • minimi- ja maksimipäivämäärä kappaleessa (osiointi tapahtuu päiväkohtaisesti) (min_date & max_date);

Siellä on myös pöytä system.graphite_retentions, seuraavilla mielenkiintoisilla kentillä:

  • db nimi (Tables.database);
  • taulukon nimi (Tables.table);
  • metrinen ikä, jolloin seuraavaa aggregaatiota tulisi käyttää (age);

Joten:

  1. Meillä on kappaleiden taulukko ja aggregointisääntöjen taulukko.
  2. Yhdistämme niiden risteyksen ja saamme kaikki taulukot *GraphiteMergeTree.
  3. Etsimme kaikkia osioita, joissa:
    • enemmän kuin yksi kappale
    • tai on tullut aika soveltaa seuraavaa yhdistämissääntöä ja modification_time vanhempi kuin tämä hetki.

Реализация

Tämä pyyntö

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

palauttaa jokaisen *GraphiteMergeTree-taulukkoosion, jonka yhdistämisen pitäisi vapauttaa levytilaa. Ainoa asia, joka on jäljellä, on käydä ne kaikki läpi pyynnöstä OPTIMIZE ... FINAL. Lopullisessa toteutuksessa huomioidaan myös se, että osioihin ei tarvitse koskettaa aktiivisella tallennuksella.

Tämä on juuri sitä, mitä projekti tekee grafiitti-ch-optimoija. Yandex.Marketin entiset kollegat kokeilivat sitä tuotannossa, työn tulos näkyy alla.

ClickHouse + Graphite: kuinka vähentää merkittävästi levytilan kulutusta

Jos suoritat ohjelman palvelimella ClickHousen kanssa, se alkaa yksinkertaisesti toimia demonitilassa. Kerran tunnissa suoritetaan pyyntö, joka tarkistaa, onko ilmaantunut uusia, yli kolme päivää vanhempia osioita, jotka voidaan optimoida.

Lähisuunnitelmissamme on toimittaa ainakin deb-paketit ja mahdollisuuksien mukaan myös rpm.

Sen sijaan johtopäätös

Viimeiset 9+ kuukautta olen ollut yrityksessäni innopelejä vietti paljon aikaa puuhaillen ClickHousen ja grafiittiverkon risteyksessä. Se oli hyvä kokemus, joka johti nopeaan siirtymiseen whisperistä ClickHouseen mittarin tallennustilaksi. Toivon, että tämä artikkeli on alkua sarjalle, jossa kerrotaan, mitä parannuksia olemme tehneet tämän pinon eri osiin ja mitä aiomme tehdä tulevaisuudessa.

Pyynnön kehittämiseen kului useita litroja olutta ja adminpäiviä mm v0devil, josta haluan ilmaista kiitokseni hänelle. Ja myös tämän artikkelin tarkistamisesta.

Projektisivu githubissa

Lähde: will.com

Lisää kommentti