ClickHouse + Graphite: hoe u het schijfruimteverbruik aanzienlijk kunt verminderen

ClickHouse + Graphite: hoe u het schijfruimteverbruik aanzienlijk kunt verminderen

Groeten, habr.

Als iemand het systeem exploiteert grafiet-web en er is een probleem met de opslagprestaties opgetreden fluisteren (IO, verbruikte schijfruimte), dan zou de kans dat ClickHouse als vervanger werd gecast, kleiner moeten zijn. Deze verklaring impliceert dat een implementatie van derden al wordt gebruikt als een daemon die bijvoorbeeld statistieken ontvangt koolstofschrijver of go-koolstof.

ClickHouse lost de beschreven problemen goed op. Nadat ze bijvoorbeeld 2TiB aan gegevens via fluisterverbinding hebben overgedragen, passen ze in 300GiB. Ik zal niet in detail op de vergelijking ingaan; er zijn genoeg artikelen over dit onderwerp. Bovendien was tot voor kort niet alles perfect met onze ClickHouse-opslag.

Problemen met verbruikte ruimte

Op het eerste gezicht zou alles goed moeten werken. Als vervolg op documentatie, maak een configuratie voor het opslagschema voor metrische gegevens (verder retention), maak vervolgens een tabel volgens de aanbeveling van de geselecteerde backend voor grafietweb: koolstof-klikhuis+grafiet-clickhouse of grafhuis, afhankelijk van welke stapel wordt gebruikt. En... de tijdbom gaat af.

Om te begrijpen welke, moet je weten hoe inserts werken en het verdere levenspad van gegevens in tabellen van motoren van de * familieBoom samenvoegen ClickHouse (grafieken afkomstig van presentaties Alexey Zatelepin):

  • Ingevoegd Π±Π»ΠΎΠΊ gegevens. In ons geval waren het de statistieken die arriveerden.
    ClickHouse + Graphite: hoe u het schijfruimteverbruik aanzienlijk kunt verminderen
  • Elk dergelijk blok wordt gesorteerd op basis van de sleutel voordat het naar schijf wordt geschreven. ORDER BYopgegeven bij het maken van de tabel.
  • Na het sorteren, кусок (part) gegevens worden naar schijf geschreven.
    ClickHouse + Graphite: hoe u het schijfruimteverbruik aanzienlijk kunt verminderen
  • De server controleert op de achtergrond, zodat er niet veel van dergelijke stukken zijn, en start de achtergrond слияния (merge, hierna samenvoeging).
    ClickHouse + Graphite: hoe u het schijfruimteverbruik aanzienlijk kunt verminderen
    ClickHouse + Graphite: hoe u het schijfruimteverbruik aanzienlijk kunt verminderen
  • De server stopt vanzelf met het uitvoeren van merges zodra er geen gegevens meer actief naar de server stromen ΠΏΠ°Ρ€Ρ‚ΠΈΡ†ΠΈΡŽ (partition), maar u kunt het proces handmatig starten met de opdracht OPTIMIZE.
  • Als er nog maar één stuk op de partitie over is, kunt u de samenvoeging niet uitvoeren met het gebruikelijke commando; u moet OPTIMIZE ... FINAL

Zo, de eerste statistieken komen binnen. En ze nemen wat ruimte in beslag. Gebeurtenissen daarna kunnen enigszins variΓ«ren, afhankelijk van vele factoren:

  • De partitiesleutel kan zeer klein (een dag) of zeer groot (meerdere maanden) zijn.
  • De retentieconfiguratie kan passen bij verschillende significante gegevensaggregatiedrempels binnen de actieve partitie (waar metrische gegevens worden vastgelegd), of misschien niet.
  • Als er veel gegevens zijn, zullen de vroegste delen, die vanwege het samenvoegen op de achtergrond al enorm kunnen zijn (als u een niet-optimale partitiesleutel kiest), zichzelf niet samenvoegen met nieuwe kleine delen.

En het eindigt altijd hetzelfde. De ruimte die wordt ingenomen door statistieken in ClickHouse neemt alleen toe als:

  • niet van toepassing OPTIMIZE ... FINAL handmatig of
  • voeg niet voortdurend gegevens in alle partities in, zodat vroeg of laat een samenvoeging op de achtergrond zal beginnen

De tweede methode lijkt het gemakkelijkst te implementeren en is daarom onjuist en werd als eerste geprobeerd.
Ik heb een vrij eenvoudig Python-script geschreven dat de afgelopen vier jaar voor elke dag dummy-statistieken heeft verzonden en elk uur cron heeft uitgevoerd.
Omdat de hele werking van ClickHouse DBMS gebaseerd is op het feit dat dit systeem vroeg of laat al het achtergrondwerk zal doen, maar het is niet bekend wanneer, kon ik niet wachten op het moment waarop de oude enorme stukken zich zouden verwaardigen om te gaan samensmelten met nieuwe kleintjes. Het werd duidelijk dat we op zoek moesten naar een manier om gedwongen optimalisaties te automatiseren.

ClickHouse + Graphite: hoe u het schijfruimteverbruik aanzienlijk kunt verminderen

Informatie in ClickHouse-systeemtabellen

Laten we eens kijken naar de tabelstructuur systeemonderdelen. Dit is uitgebreide informatie over elk onderdeel van alle tabellen op de ClickHouse-server. Bevat onder meer de volgende kolommen:

  • db-naam (database);
  • tafel naam (table);
  • partitienaam en ID (partition & partition_id);
  • toen het stuk werd gemaakt (modification_time);
  • minimum- en maximumdatum in een stuk (partitioneren gebeurt per dag) (min_date & max_date);

Er is ook een tafel system.graphite_retenties, met de volgende interessante velden:

  • db-naam (Tables.database);
  • tafel naam (Tables.table);
  • metrische leeftijd waarop de volgende aggregatie moet worden toegepast (age);

Dus:

  1. We hebben een tabel met chunks en een tabel met aggregatieregels.
  2. We combineren hun kruising en krijgen alle tabellen *GraphiteMergeTree.
  3. Wij zijn op zoek naar alle partities waarin:
    • meer dan één stuk
    • of het is tijd om de volgende aggregatieregel toe te passen, en modification_time ouder dan dit moment.

uitvoering

Dit verzoek

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

retourneert elk van de *GraphiteMergeTree-tabelpartities waarvan het samenvoegen schijfruimte zou moeten vrijmaken. Het enige dat u nog hoeft te doen, is ze allemaal doornemen met een verzoek OPTIMIZE ... FINAL. Bij de uiteindelijke implementatie wordt ook rekening gehouden met het feit dat het niet nodig is om partities aan te raken met actieve opname.

Dit is precies wat het project doet grafiet-ch-optimizer. Voormalige collega's van Yandex.Market probeerden het in productie, het resultaat van het werk is hieronder te zien.

ClickHouse + Graphite: hoe u het schijfruimteverbruik aanzienlijk kunt verminderen

Als u het programma op een server met ClickHouse draait, zal het gewoon in daemon-modus gaan werken. EΓ©n keer per uur wordt er een verzoek uitgevoerd, waarbij wordt gecontroleerd of er nieuwe partities ouder dan drie dagen zijn verschenen die geoptimaliseerd kunnen worden.

Onze onmiddellijke plannen zijn om op zijn minst deb-pakketten aan te bieden, en indien mogelijk ook rpm.

In plaats Output

De afgelopen 9+ maanden ben ik in mijn bedrijf geweest InnoGames Ik heb veel tijd besteed aan het sleutelen aan het kruispunt van ClickHouse en grafietweb. Het was een goede ervaring, die resulteerde in een snelle overstap van fluisteren naar ClickHouse als statistiekopslag. Ik hoop dat dit artikel het begin is van een serie over de verbeteringen die we hebben aangebracht aan verschillende delen van deze stapel, en wat er in de toekomst zal worden gedaan.

Er zijn meerdere liters bier en administratiedagen besteed aan het ontwikkelen van het verzoek v0duivel, waarvoor ik hem mijn dank wil uitspreken. En ook voor het beoordelen van dit artikel.

Projectpagina op github

Bron: www.habr.com

Voeg een reactie