
Hej, habr.
Om nÄgon utnyttjar systemet och stöter pÄ prestandaproblem med lagringen (IO, lagrat diskutrymme), sÄ bör chansen att man övervÀger ClickHouse som en ersÀttning strÀva mot en. Detta pÄstÄende innebÀr att en tredjepartsimplementation redan anvÀnds som mottagande metrikdaemon, till exempel eller .
ClickHouse löser de beskrivna problemen vÀl. Till exempel, efter att ha flyttat 2TiB data frÄn whisper, fick de plats i 300GiB. Jag kommer inte att gÄ in mer pÄ jÀmförelsen, det finns gott om artiklar om detta. Dessutom har vÄrt ClickHouse-lager inte varit perfekt fram till nyligen.
Problem med upptaget utrymme
Vid första anblick borde allt fungera bra. Följande , skapar vi en konfiguration för lagringsschemat (nedan retention), sedan skapar vi en tabell enligt rekommendationen frÄn den valda backend för graphite-web: + eller , beroende pÄ vilken stack som anvÀnds. Och... en tidsinstÀlld bomb sÀtts igÄng.
För att förstÄ vilken, mÄste man veta hur insÀttningarna fungerar och den fortsatta livscykeln för data i tabellerna frÄn *MergeTree ClickHouse (diagrammen Àr hÀmtade frÄn Aleksej Zatelepin):
- En
blockdata. I vÄrt fall Àr det metrikar som har ankommit.

- Varje sÄdan block sorteras enligt nyckeln
ORDER BY, specificerad vid skapandet av tabellen. - Efter sortering,
en del(part) data skrivs till disk.

- Servern övervakar i bakgrunden sÄ att sÄdana delar inte blir för mÄnga, och kör bakgrunds-
sammanfogningarna(merge, dÀrefter merges).


- Servern slutar automatiskt köra merges sÄ snart inga data lÀngre aktivt kommer in i
partition(partitionen, men kan manuellt startas med kommandotOPTIMIZEOPTIMIZE ... FINAL. - SÄ kommer de första metrikarna in. Och de tar upp ett visst utrymme. De efterföljande hÀndelserna kan variera nÄgot beroende pÄ mÄnga faktorer:
Partitioneringsnyckeln kan vara antingen mycket liten (dag) eller mycket stor (flera mÄnader).
Retention-konfigurationen kan innefatta flera betydande trösklar för aggregering av data inom den aktiva partitionen (dit metrikarna skrivs), eller sÄ kan den kanske inte.
- Partitionnyckeln kan vara bÄde mycket liten (en dag) och mycket stor (flera mÄnader).
- Retentionkonfigurationen kan rymma flera betydande datainsamlingsgrÀnser inom den aktiva partitionen (dit mÀtvÀrdena skrivs), eller sÄ kan den inte göra det.
- Om det finns mycket data, kommer de tidigaste bitarna, som pÄ grund av bakgrundssammanslagningar redan kan vara stora (vid val av en suboptimal partitioneringsnyckel), inte att slÄs samman med de nya smÄ bitarna.
Och allt avslutas alltid pÄ samma sÀtt. Utrymmet som upptas av metrik i ClickHouse vÀxer bara om:
- man inte tillÀmpar
Partitioneringsnyckeln kan vara antingen mycket liten (dag) eller mycket stor (flera mÄnader).manuellt eller - inte sÀtter in data i alla partitioner kontinuerligt, för att förr eller senare kunna starta en bakgrundssammanslagning.
Den andra metoden verkar vara den enklaste att implementera och dÀrför Àr den felaktig och prövades först.
Jag skrev ett ganska enkelt skript i Python som skickade falska metrik för varje dag under de senaste 4 Ären och kördes varje timme av cron.
Eftersom hela arbetet i ClickHouse DBMS Àr baserat pÄ att detta system förr eller senare kommer att göra allt det bakgrundsarbetet, men maskinens tidpunkt Àr okÀnd, lyckades jag inte vÀnta pÄ att de gamla stora bitarna skulle ge sig till att börja sammanslÄs med de nya smÄ. Det blev klart att jag behövde hitta ett sÀtt att automatisera tvingande optimeringar.

Informationen i systemtabellerna för ClickHouse
LÄt oss titta pÄ strukturen av tabellen . Det ger uttömmande information om varje bit av alla tabeller pÄ ClickHouse-servern. Den innehÄller bland annat följande kolumner:
- databasnamn (
database); - tabellnamn (
tabell); - partitionens namn och ID (
partitionen, men kan manuellt startas med kommandot&partition_id); - nÀr biten skapades (
modification_time); - minimalt och maximalt datum i biten (partitioneringen sker dag för dag) (
min_date&max_date);
Det finns ocksÄ en tabell , med följande intressanta fÀlt:
- databasnamn (
Tables.database); - tabellnamn (
Tables.table); - metrikens Älder, nÀr nÀsta aggregering ska tillÀmpas (
age);
SĂ„:
- Vi har en tabell med bitar och en tabell med aggregeringsregler.
- Vi förenar deras snitt och fÄr alla tabeller *GraphiteMergeTree.
- Vi letar efter alla partitioner dÀr:
- mer Àn en bit
- eller det Àr dags att tillÀmpa nÀsta aggregeringsregel, och
modification_timeÀldre Àn den punkten.
Implementering
Denna frÄga
VĂLJ
concat(p.database, '.', p.table) AS table,
p.partition_id AS partition_id,
p.partition AS partition,
-- Den "Àldre" regeln som kan tillÀmpas pÄ
-- partitionen, men inte i framtiden, se (*)
max(g.age) AS age,
-- Antal delar i partitionen
countDistinct(p.name) AS parts,
-- Den Àldsta mÀtningen i partitionen antas vara 00:00:00 nÀsta dag
toDateTime(max(p.max_date + 1)) AS max_time,
-- NÀr partitionen bör optimeras
max_time + age AS rollup_time,
-- NÀr den Àldsta delen i partitionen senast uppdaterades
min(p.modification_time) AS modified_at
FRĂ
N system.parts AS p
INNER JOIN
(
-- Alla regler för alla tabeller *GraphiteMergeTree
VĂLJ
Tables.database AS database,
Tables.table AS table,
age
FRĂ
N system.graphite_retentions
ARRAY JOIN Tables
GRUPPERA EFTER
database,
table,
age
) AS g PĂ
(p.table = g.table)
OCH (p.database = g.database)
DĂR
-- Endast aktiva delar
p.active
-- (*) Och endast rader dÀr aggregeringsregler redan bör tillÀmpas
OCH ((toDateTime(p.max_date + 1) + g.age) < now())
GRUPPERA EFTER
table,
partition
HAVING
-- Endast partitioner som Àr yngre Àn optimeringstidpunkten
(modified_at 1)
ORDNA EFTER
table ASC,
partition ASC,
age ASCreturnerar var och en av partitionerna i tabellerna *GraphiteMergeTree, vars sammanslagning bör leda till frigörande av diskutrymme. Nu ÄterstÄr bara att göra det lilla: gÄ igenom dem alla med en frÄga Partitioneringsnyckeln kan vara antingen mycket liten (dag) eller mycket stor (flera mÄnader).. I den slutliga implementeringen har man Àven beaktat att partitioner med aktiv skrivning inte behöver beröras.
Det Àr precis det hÀr som projektet gör . Tidigare kollegor frÄn Yandex.Market har testat den i produktion, resultatet kan ses nedan.

Om programmet körs pÄ en server med ClickHouse kommer det enkelt att börja fungera i daemonlÀge. En gÄng i timmen kommer en frÄga att köras för att kontrollera om nya partitioner Àldre Àn tre dagar har dykt upp som kan optimeras.
I de nĂ€rmaste planerna â att tillhandahĂ„lla Ă„tminstone deb-paket, och om möjligt â Ă€ven rpm.
Avslutande
Under de senaste 9 mĂ„naderna har jag inom mitt företag tillbringat mycket tid med att arbeta i skĂ€rningspunkten mellan ClickHouse och graphite-web. Det har varit en bra erfarenhet, resultatet av detta möjliggjorde en snabb övergĂ„ng frĂ„n whisper till ClickHouse som lagring av mĂ€tvĂ€rden. Jag hoppas att denna artikel â Ă€r nĂ„got slags början pĂ„ en serie om vilka förbĂ€ttringar vi har gjort i olika delar av denna stack och vad som kommer att göras i framtiden.
Utvecklingen av förfrÄgan tog flera liter öl och ett antal admin-dagar tillsammans med , för vilket jag vill uttrycka min tacksamhet. Och Àven för att han recenserade denna artikel.
KĂ€lla: habr.com




