Agurrak, habr.
Norbaitek sistema ustiatzen badu
ClickHouse-k ondo konpontzen ditu deskribatutako arazoak. Adibidez, whisper-etik 2TiB datu transferitu ondoren, 300GiB-ra sartzen dira. Ez naiz konparazioan zehatz-mehatz luzatuko; gai honi buruzko artikulu ugari daude. Gainera, duela gutxi arte, dena ez zen perfektua gure ClickHouse biltegiarekin.
Kontsumitutako espazioarekin arazoak
Lehen begiratuan, dena ondo funtzionatu beharko luke. Jarraian retention
), ondoren sortu taula bat grafito-web-erako hautatutako backendaren gomendioaren arabera:
Zein ulertzeko, txertatzeek nola funtzionatzen duten eta datuen bizi-ibilbidea * familiako motor tauletan nola funtzionatzen duten jakin behar duzu.MergeTree ClickHouse (diagramatik ateratakoak
- Txertatuta
Π±Π»ΠΎΠΊ
datuak. Gure kasuan, neurketak izan ziren iritsi zirenak.
- Bloke bakoitza gakoaren arabera ordenatzen da diskoan idatzi aurretik.
ORDER BY
taula sortzean zehaztuta. - Sailkatu ondoren,
ΠΊΡΡΠΎΠΊ
(part
) datuak diskoan idazten dira.
- Zerbitzariak atzeko planoan kontrolatzen du, horrelako pieza asko ez egon daitezen, eta atzeko planoa abiarazten du
ΡΠ»ΠΈΡΠ½ΠΈΡ
(merge
, aurrerantzean batu).
- Zerbitzariak bere kabuz konbinazioak exekutatzeari uzten dio datuak aktiboki isurtzeari uzten dioten bezain laster
ΠΏΠ°ΡΡΠΈΡΠΈΡ
(partition
), baina prozesua eskuz has dezakezu komandoarekinOPTIMIZE
. - Partizioan pieza bakarra geratzen bada, ezin izango duzu batuketa exekutatu ohiko komandoa erabiliz; erabili behar duzu
OPTIMIZE ... FINAL
Beraz, lehenengo neurketak iristen dira. Eta leku pixka bat hartzen dute. Ondorengo gertaerak zertxobait alda daitezke faktore askoren arabera:
- Partizio-gakoa oso txikia (egun bat) edo oso handia (hainbat hilabete) izan daiteke.
- Atxikipen konfigurazioa partizio aktiboaren barruan (neurriak erregistratzen diren tokian) hainbat datu-agregazio atalase esanguratsu egokitzea izan daiteke edo agian ez.
- Datu asko baldin badaude, lehen zatiak, atzeko planoan batzea dela eta dagoeneko handiak izan daitezke (partizio-gako ez-optimoa aukeratzen baduzu), ez dira zati txiki berriekin batuko.
Eta beti berdin bukatzen da. ClickHouse-n metrikek hartzen duten espazioa soilik handitzen da:
- ez aplikatu
OPTIMIZE ... FINAL
eskuz edo - ez txertatu datuak partizio guztietan etengabe, lehenago edo beranduago atzeko planoko batuketa bat hasiko da
Bigarren metodoa ezartzeko errazena dela dirudi eta, beraz, okerra da eta lehen probatu zen.
Python script nahiko sinple bat idatzi nuen, azken 4 urteetan egunero-egunero metrika bidaltzen zituena eta orduro cron exekutatzen zuen.
ClickHouse DBMSren funtzionamendu osoa sistema honek lehenago edo beranduago atzeko lan guztiak egingo dituelako oinarrian dagoenez, baina ez dakigu noiz, ezin izan nuen itxaron pieza erraldoi zaharrak bateratzen hasteko momentua. txiki berriak. Argi geratu zen behartutako optimizazioak automatizatzeko modua bilatu behar genuela.
ClickHouse sistema-tauletako informazioa
Ikus dezagun taularen egiturari
- db izena (
database
); - taularen izena (
table
); - partizioaren izena eta ID (
partition
&partition_id
); - pieza sortu zenean (
modification_time
); - gutxieneko eta gehienezko data pieza batean (banaketa egunez egiten da) (
min_date
&max_date
);
Mahai bat ere badago
- db izena (
Tables.database
); - taularen izena (
Tables.table
); - hurrengo agregazioa aplikatu behar den adin metrikoa (
age
);
Beraz:
- Zati-taula eta agregazio-arauen taula ditugu.
- Haien elkargunea konbinatzen dugu eta taula guztiak *GraphiteMergeTree lortzen ditugu.
- Partizio guztiak bilatzen ari gara, zeinetan:
- pieza bat baino gehiago
- edo hurrengo batuketa-araua aplikatzeko garaia heldu da, eta
modification_time
une hau baino zaharragoa.
Inplementazioa
Eskaera hau
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
*GraphiteMergeTree taula-partizioetako bakoitza itzultzen du, zeinen bateratzeak diskoko lekua askatu beharko lukeen. Egin beharreko gauza bakarra denak eskaera batekin pasatzea da OPTIMIZE ... FINAL
. Azken inplementazioak ere kontuan hartzen du ez dagoela partizioak ukitu beharrik grabaketa aktiboarekin.
Hori da, hain zuzen, proiektuak egiten duena
Programa ClickHouse-rekin zerbitzari batean exekutatzen baduzu, deabru moduan lanean hasiko da. Ordubetean eskaera bat exekutatuko da, optimizatu daitezkeen hiru egun baino zaharragoak diren partizio berriak agertu diren egiaztatuz.
Gure berehalako planak gutxienez deb paketeak eskaintzea da, eta ahal bada rpm ere.
Horren ordez Ondorio baten
Azken 9 hilabeteetan nire enpresan egon naiz
Hainbat litro garagardo eta administrazio-egun eman ziren eskaera garatzen, batera
Iturria: www.habr.com