ClickHouse + Graphite: hogyan lehet jelentősen csökkenteni a lemezterület-felhasználást

ClickHouse + Graphite: hogyan lehet jelentősen csökkenteni a lemezterület-felhasználást

Üdvözlet, habr.

Ha valaki kihasználja a rendszert grafit-háló és tárolási teljesítménybeli problémába ütközött suttogás (IO, lemezterület elhasználódott), akkor annak az esélye, hogy a ClickHouse-t csereként adták le, egynek kell lennie. Ez az állítás arra utal, hogy egy harmadik féltől származó implementációt már használnak mérőszámokat fogadó démonként, például széníró vagy go-karbon.

A ClickHouse jól megoldja a leírt problémákat. Például 2 TiB adat átvitele után a whisperből 300 GiB-be férnek bele. Nem foglalkozom részletesen az összehasonlítással, rengeteg cikk van ebben a témában. Ráadásul egészen a közelmúltig nem volt minden tökéletes a ClickHouse tárolónkkal.

Problémák az elhasznált hellyel

Első pillantásra mindennek jól kell működnie. Következő dokumentáció, hozzon létre egy konfigurációt a metrika tárolási sémához (továbbiakban retention), majd hozzon létre egy táblázatot a grafit-web kiválasztott háttérprogramjának ajánlása szerint: szén-clickhouse+grafit-clickhouse vagy lerakóház, attól függően, hogy melyik köteget használjuk. És... felrobban az időzített bomba.

Annak megértéséhez, hogy melyik, ismernie kell a betétek működését és az adatok további életútját a * család motorjainak táblázataibanMergeTree ClickHouse (diagramok származnak előadások Alexey Zatelepin):

  • Beszúrva блок adat. Esetünkben a mérőszámok érkeztek.
    ClickHouse + Graphite: hogyan lehet jelentősen csökkenteni a lemezterület-felhasználást
  • Minden ilyen blokkot a kulcs szerint rendeznek, mielőtt lemezre írnák. ORDER BYtáblázat létrehozásakor megadva.
  • A válogatás után, кусок (part) az adatok lemezre kerülnek.
    ClickHouse + Graphite: hogyan lehet jelentősen csökkenteni a lemezterület-felhasználást
  • A szerver a háttérben figyel, hogy ne legyen sok ilyen darab, és elindítja a hátteret слияния (merge, a továbbiakban összevonás).
    ClickHouse + Graphite: hogyan lehet jelentősen csökkenteni a lemezterület-felhasználást
    ClickHouse + Graphite: hogyan lehet jelentősen csökkenteni a lemezterület-felhasználást
  • A kiszolgáló magától leállítja az egyesítések futtatását, amint leáll az adatok aktív áramlása a партицию (partition), de a folyamatot manuálisan is elindíthatja a paranccsal OPTIMIZE.
  • Ha csak egy darab maradt a partícióban, akkor nem tudja futtatni az egyesítést a szokásos paranccsal; OPTIMIZE ... FINAL

Tehát megérkeznek az első mutatók. És elfoglalnak egy kis helyet. A későbbi események némileg változhatnak számos tényezőtől függően:

  • A particionáló kulcs lehet nagyon kicsi (egy nap) vagy nagyon nagy (több hónap).
  • A megőrzési konfiguráció több jelentős adatösszesítési küszöböt is illeszthet az aktív partíción belül (ahol a mérőszámok rögzítve vannak), vagy nem.
  • Ha sok az adat, akkor a legkorábbi darabok, amelyek a háttér-összevonás miatt már hatalmasak lehetnek (ha nem optimális particionáló kulcsot választunk), nem egyesülnek friss kis darabokkal.

És mindig ugyanaz a vége. A mérőszámok által elfoglalt hely a ClickHouse-ban csak akkor növekszik, ha:

  • ne alkalmazza OPTIMIZE ... FINAL manuálisan ill
  • ne helyezzen be folyamatosan adatokat minden partícióba, így előbb-utóbb megindul a háttér-összevonás

A második módszer tűnik a legkönnyebben megvalósíthatónak, ezért helytelen, és először próbálták ki.
Írtam egy meglehetősen egyszerű python-szkriptet, amely az elmúlt 4 évben minden napra dummy metrikákat küldött, és óránként lefuttatta a cront.
Mivel a ClickHouse DBMS teljes működése azon alapszik, hogy ez a rendszer előbb-utóbb elvégzi az összes háttérmunkát, de nem tudni, hogy mikor, alig vártam a pillanatot, amikor a régi hatalmas darabok méltók egybeolvadni. új kicsiket. Világossá vált, hogy módot kell keresnünk a kényszeroptimalizálások automatizálására.

ClickHouse + Graphite: hogyan lehet jelentősen csökkenteni a lemezterület-felhasználást

Információk a ClickHouse rendszertáblázatokban

Vessünk egy pillantást a táblázat szerkezetére rendszer.alkatrészek. Ez átfogó információ a ClickHouse szerver összes táblájáról. Többek között a következő oszlopokat tartalmazza:

  • db név (database);
  • táblázat neve (table);
  • partíció neve és azonosítója (partition & partition_id);
  • amikor a darab készült (modification_time);
  • minimális és maximális dátum egy darabban (a particionálás naponként történik) (min_date & max_date);

Asztal is van system.graphite_retentions, a következő érdekes mezőkkel:

  • db név (Tables.database);
  • táblázat neve (Tables.table);
  • metrikus életkor, amikor a következő összesítést kell alkalmazni (age);

Tehát:

  1. Van egy darab táblázatunk és egy táblázat az összesítési szabályokról.
  2. Összevonjuk a metszéspontjukat, és megkapjuk az összes táblát *GraphiteMergeTree.
  3. Minden olyan partíciót keresünk, amelyben:
    • több mint egy darab
    • vagy eljött az ideje a következő összesítési szabály alkalmazásának, és modification_time régebbi ennél a pillanatnál.

Реализация

Ez a kérés

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

visszaadja a *GraphiteMergeTree táblapartíciók mindegyikét, amelyek összevonása lemezterületet szabadít fel. Már csak egy kéréssel kell végigmenni mindegyiken OPTIMIZE ... FINAL. A végső megvalósítás azt is figyelembe veszi, hogy az aktív rögzítéssel nem kell partíciókat érinteni.

A projekt pontosan ezt teszi grafit-ch-optimalizáló. A Yandex.Market korábbi kollégái kipróbálták a gyártásban, a munka eredménye alább látható.

ClickHouse + Graphite: hogyan lehet jelentősen csökkenteni a lemezterület-felhasználást

Ha a programot ClickHouse-szal futtatja egy szerveren, akkor egyszerűen démon módban kezd működni. Óránként egyszer végrehajtásra kerül egy kérés, amely ellenőrzi, hogy megjelentek-e új, három napnál régebbi, optimalizálható partíciók.

Közelebbi terveink között szerepel legalább deb csomagok biztosítása, és ha lehet, rpm is.

Ahelyett, hogy egy következtetés

Az elmúlt 9+ hónapban a cégemben dolgoztam innogames sok időt töltött a ClickHouse és a grafit-web találkozásánál. Jó tapasztalat volt, aminek eredményeként gyorsan áttértünk a whisperről a ClickHouse-ra, mint metrikatárolóra. Remélem, ez a cikk egy olyan sorozat kezdete, amely arról szól, hogy milyen fejlesztéseket végeztünk ennek a veremnek a különböző részein, és mit fogunk tenni a jövőben.

Több liter sör és admin napok teltek el a kérés kidolgozásával együtt v0ördög, amiért szeretném kifejezni hálámat neki. És a cikk áttekintéséért is.

Projekt oldal a githubon

Forrás: will.com

Hozzászólás