
Përshëndetje, habr.
Nëse dikush shfrytëzon sistemin dhe ka hasur në probleme me performancën e depozitës (IO, hapësira e përdorur në disk), atëherë probabiliteti që të jetë hedhur një sy në ClickHouse si zëvendësim duhet të jetë afër njësi. Ky pohim nënkupton se si demon metrikash përdoret tashmë një implementim i palës së tretë, për shembull или .
ClickHouse mirë zgjidh problemet e përmendura. Për shembull, pas transferimit të 2TiB të të dhënave nga whisper, ato u përshtatën në 300GiB. Nuk do të ndalem tek krahasimi në detaje, ka mjaft artikuj mbi këtë temë. Gjithashtu, deri kohët e fundit, me depozitën tonë ClickHouse nuk ishte gjithçka perfekte.
Problemet me hapësirën e përdorur
Në shikim të parë, gjithçka duhet të funksionojë mirë. Duke ndjekur , krijojmë një konfigurim për skemën e ruajtjes së metrike (më pas retention), pastaj krijojmë një tabelë sipas rekomandimeve të backend-it të zgjedhur për graphite-web: + или , varësisht nga staku që përdoret. Dhe... aktivizohet një bombë me vonesë.
Për të kuptuar se cila, duhet të dimë si funksionojnë inserimet dhe rruga e mëtejshme e jetës së të dhënave në tabelat e motorëve të familjes *MergeTree ClickHouse (diagramet janë marrë nga Aleksandr Zatelepina):
- Injetohet
një blloktë dhënash. Në rastin tonë, këto janë metrikat që kanë mb arrive.

- Çdo bllok i tillë para se të shkruhet në disk renditet sipas çelësit
ORDER BY, i specifikuar kur krijohet tabela. - Pasi të renditet,
një copë(part) të dhënash shkruhet në disk.

- Serveri monitoron në sfond që të mos ketë shumë copëza të tilla, dhe aktivizon proceset e
shkrirjes(merge, më vonë quhen mërgë.)


- Serveri ndalon të aktivizojë mërgë automatikisht sa herë që të dhënat ndalojnë së ardhuri aktivisht në
particion(partition), por mund të aktivizoni procesin manualisht me komandënOPTIMIZE. - Nëse në particion ka mbetur vetëm një copë, atëherë nuk do të jetë e mundur të aktivizohet një mërgë me komandën e zakonshme, nevojitet të përdoret
OPTIMIZE ... FINAL
Pra, metrikat e para mbërrijnë. Dhe ato shfrytëzojnë ndonjë hapësirë. Eventet e ardhshme mund të variojnë pak në varësi të shumë faktorëve:
- Çelësi i partitizimit mund të jetë shumë i vogël (një ditë), si dhe shumë i madh (për disa muaj).
- Konfigurimi i retention mund të përmbajë disa pragje të rëndësishme të agregimit të të dhënave brenda një partie aktive (ku shkruhen metrikat), ose ndoshta jo.
- Nëse të dhënat janë shumë të shumta, copat më të vjetra, të cilat për shkak të mergimeve pasive mund të jenë tashmë shumë të mëdha (kur zgjidhet një çelës jo optimal për ndarjen), nuk do të bashkohen vetë me copat e reja të vogla.
Dhe gjithmonë përfundon gjithçka në të njëjtën mënyrë. Hapsira e zënë nga metrikat në ClickHouse vetëm rritet, nëse:
- nuk aplikohet
OPTIMIZE ... FINALduke ndihmuar manualisht ose - nuk futen të dhëna në të gjitha partitë në një bazë të qëndrueshme, në mënyrë që vonë ose më vonë të fillohet një mergim pasiv.
Mënyra e dytë duket si më e thjeshta për t'u zbatuar dhe, pra, është e gabuar dhe u provua e para.
Shkrova një skenar mjaft të thjeshtë në python, i cili dërgonte metrika fiktive për çdo ditë për katër vitet e fundit dhe ekzekutohej çdo orë nga cron.
Duke qenë se gjithë puna e sistemit ClickHouse DBMS është e ndërtuar mbi faktin se ky sistem do të bëjë gjithë punën e pasme përfundimisht, por nuk dihet kur, nuk e kam arritur dot të pres momentin kur copat e vjetra të mëdha do të kishin filluar të bashkoheshin me copat e reja të vogla. U bë e qartë se duhet të kërkoja mënyra për të automatizuar optimizimet përkatëse.

Informacioni në tabelat sistemore të ClickHouse
Le të shohim strukturën e tabelës . Ky është informacioni gjithëpërfshirës për çdo copë të të gjitha tabelave në serverin ClickHouse. Përmban, përfshirë, kolonat e mëposhtme:
- emri i DB (
database); - emri i tabelës (
table); - emri dhe ID e partisë (
partition&partition_id); - kur u krijua copëza (
modification_time); - data minimale dhe maksimale në copë (ndarja bëhet sipas ditëve) (
min_date&max_date);
Gjithashtu ka një tabelë , me fushat e mëposhtme të interesit:
- emri i DB (
Tables.database); - emri i tabelës (
Tables.table); - mosha e metrikës, kur duhet të aplikohet agregimi i ardhshëm (
age);
Pra:
- Kemi një tabelë copash dhe një tabelë rregullash agregimi.
- Bashkojmë ndërprerjen e tyre dhe marrim të gjitha tabelat *GraphiteMergeTree.
- Kërkojmë të gjitha partitë, ku:
- më shumë se një copë
- ose ka ardhur momenti për të aplikuar rregullin e ardhshëm të agregimit, dhe
modification_timeështë më e vjetër se ky moment.
Implementimi
Ky kërkesë
SELEKTO
concat(p.database, '.', p.table) AS table,
p.partition_id AS partition_id,
p.partition AS partition,
-- Rregulli më "i vjetër", që mund të aplikohet për
-- particionin, por jo në të ardhmen, shiko (*)
max(g.age) AS age,
-- Numri i pjesëve në particion
countDistinct(p.name) AS parts,
-- Metri më i vjetër në particion pranohet 00:00:00 e ditës së ardhshme
toDateTime(max(p.max_date + 1)) AS max_time,
-- Kur particiones duhet të optimizohet
max_time + age AS rollup_time,
-- Kur pjesa më e vjetër në particion është përditësuar
min(p.modification_time) AS modified_at
FROM system.parts AS p
INNER JOIN
(
-- Të gjitha rregullat për të gjitha tabelat *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
-- Vetëm pjesët aktive
p.active
-- (*) Dhe vetëm rreshtat, ku rregullat e agregatimit tashmë duhet të aplikohen
AND ((toDateTime(p.max_date + 1) + g.age) < now())
GROUP BY
table,
partition
HAVING
-- Vetëm particionet që janë më të rinj se momenti i optimizimit
(modified_at 1)
ORDER BY
table ASC,
partition ASC,
age ASCkthen çdo nga partitë e tabelave *GraphiteMergeTree, të cilat duhet të bashkohen për të liruar hapësirën në disk. E vetmja gjë që mbetet është të kalosh nëpër to të gjitha me një kërkesë OPTIMIZE ... FINAL. Në implementimin përfundimtar është marrë parasysh gjithashtu fakti se nuk ka nevojë të prekësh partitë me shkrim aktiv.
Kjo është ajo që bën projekti . Koleget e mia të vjetra nga Yandex.Market e provuan atë në prodhim, rezultatin e punës mund ta shihni më poshtë.

Nëse e nisni programin në një server me ClickHouse, ai do të fillojë të punojë thjesht në modin demon. Njëherë në orë do të ekzekutohet një kërkesë që kontrollon nëse ka partitë të reja më të vjetra se tre ditë që mund të optimizohen.
Në planet e afërta është të ofrohet, të paktën, paketat deb, dhe, sa më shumë të jetë e mundur, gjithashtu rpm.
Në përfundim
Në 9 muajt e kaluar kam kaluar shumë kohë brenda kompanisë sime duke u marrë me ClickHouse dhe graphite-web. Ky ishte një përvojë e mirë, rezultati i së cilës e bëri kalimin e shpejtë nga whisper në ClickHouse si një depo për metrikat e mundshëm. Shpresoj që ky artikull të jetë një lloj fillimi i një cikli mbi përmirësimet që kemi bërë në pjesë të ndryshme të këtij stivi, dhe se çfarë do të bëhet në të ardhmen.
Për zhvillimin e kërkesës u shpenzuan disa litra birrë dhe ditë administratori së bashku me , për të cilin do të doja të shprehja mirënjohjen time. Po ashtu për rishikimin e këtij artikulli.
Burimi: habr.com




