Salamu, habr.
Ikiwa mtu anatumia mfumo vibaya
ClickHouse hutatua shida zilizoelezewa vizuri. Kwa mfano, baada ya kuhamisha 2TiB ya data kutoka kwa kunong'ona, zinafaa kwenye 300GiB. Sitakaa juu ya kulinganisha kwa undani; kuna nakala nyingi juu ya mada hii. Kwa kuongeza, hadi hivi karibuni, sio kila kitu kilikuwa kamili na hifadhi yetu ya ClickHouse.
Matatizo na nafasi inayotumiwa
Kwa mtazamo wa kwanza, kila kitu kinapaswa kufanya kazi vizuri. Kufuatia retention
), kisha unda jedwali kulingana na pendekezo la sehemu ya nyuma iliyochaguliwa ya wavuti ya grafiti:
Ili kuelewa ni ipi, unahitaji kujua jinsi kuingiza hufanya kazi na njia zaidi ya maisha ya data kwenye jedwali la injini za familia *MergeTree ClickHouse (chati zilizochukuliwa kutoka
- imeingizwa
Π±Π»ΠΎΠΊ
data. Kwa upande wetu, ilikuwa vipimo vilivyofika.
- Kila kizuizi kama hicho hupangwa kulingana na ufunguo kabla ya kuandikwa kwa diski.
ORDER BY
maalum wakati wa kuunda meza. - Baada ya kupanga,
ΠΊΡΡΠΎΠΊ
(part
) data imeandikwa kwa diski.
- Seva inafuatilia kwa nyuma ili hakuna vipande vingi kama hivyo, na kuzindua mandharinyuma
ΡΠ»ΠΈΡΠ½ΠΈΡ
(merge
, unganisha baadaye).
- Seva itaacha kufanya kazi muunganisho yenyewe mara tu data inapoacha kutiririka kikamilifu kwenye faili ya
ΠΏΠ°ΡΡΠΈΡΠΈΡ
(partition
), lakini unaweza kuanza mchakato kwa mikono na amriOPTIMIZE
. - Ikiwa kuna kipande kimoja tu kilichobaki kwenye kizigeu, basi hautaweza kuendesha unganisho kwa kutumia amri ya kawaida; lazima utumie
OPTIMIZE ... FINAL
Kwa hivyo, vipimo vya kwanza vinafika. Na wanachukua nafasi fulani. Matukio yanayofuata yanaweza kutofautiana kwa kiasi fulani kulingana na mambo mengi:
- Kitufe cha kugawa kinaweza kuwa kidogo sana (siku) au kikubwa sana (miezi kadhaa).
- Mipangilio ya kubaki inaweza kutoshea vizingiti kadhaa muhimu vya ujumlishaji wa data ndani ya kizigeu kinachotumika (ambapo vipimo vimerekodiwa), au labda sivyo.
- Ikiwa kuna data nyingi, basi vipande vya mapema zaidi, ambavyo kwa sababu ya uunganisho wa mandharinyuma vinaweza kuwa vikubwa (ikiwa utachagua ufunguo usio wa kugawanya usio bora), hautajiunganisha na vipande vidogo vidogo.
Na daima huisha sawa. Nafasi inayokaliwa na vipimo katika ClickHouse huongezeka tu ikiwa:
- usitumie
OPTIMIZE ... FINAL
kwa mikono au - usiingize data katika sehemu zote kwa msingi unaoendelea, ili mapema au baadaye uunganisho wa usuli utaanza
Njia ya pili inaonekana kuwa rahisi zaidi kutekeleza na, kwa hiyo, si sahihi na ilijaribiwa kwanza.
Niliandika hati rahisi ya python ambayo ilituma metrics za dummy kwa kila siku kwa miaka 4 iliyopita na kukimbia cron kila saa.
Kwa kuwa operesheni nzima ya ClickHouse DBMS inategemea ukweli kwamba mfumo huu utafanya kazi yote ya nyuma mapema au baadaye, lakini haijulikani ni lini, sikuweza kungojea wakati vipande vikubwa vya zamani vitaanza kuunganishwa na. mpya ndogo. Ilionekana wazi kuwa tulihitaji kutafuta njia ya kubinafsisha uboreshaji wa kulazimishwa.
Taarifa katika majedwali ya mfumo wa ClickHouse
Wacha tuangalie muundo wa meza
- db jina (
database
); - jina la meza (
table
); - jina la sehemu na kitambulisho (
partition
&partition_id
); - wakati kipande kilipoundwa (
modification_time
); - tarehe ya chini na ya juu katika kipande (kugawa hufanywa kwa siku) (
min_date
&max_date
);
Pia kuna meza
- db jina (
Tables.database
); - jina la meza (
Tables.table
); - umri wa kipimo ambapo muunganisho unaofuata unapaswa kutumika (
age
);
Hivyo:
- Tunayo jedwali la vipande na jedwali la sheria za kujumlisha.
- Tunaunganisha makutano yao na kupata meza zote *GraphiteMergeTree.
- Tunatafuta sehemu zote ambazo:
- zaidi ya kipande kimoja
- au wakati umefika wa kutumia kanuni inayofuata ya ujumlisho, na
modification_time
mzee kuliko wakati huu.
Utekelezaji
Ombi hili
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
hurejesha kila sehemu ya jedwali la *GraphiteMergeTree ambalo uunganishaji wake unapaswa kutoa nafasi ya diski. Kitu pekee kilichobaki kufanya ni kuwapitia wote kwa ombi OPTIMIZE ... FINAL
. Utekelezaji wa mwisho pia unazingatia ukweli kwamba hakuna haja ya kugusa partitions na kurekodi kazi.
Hivi ndivyo mradi unavyofanya
Ikiwa utaendesha programu kwenye seva na ClickHouse, itaanza kufanya kazi katika hali ya daemon. Mara moja kwa saa ombi litatekelezwa, kuangalia kama sehemu mpya za zamani zaidi ya siku tatu zimeonekana ambazo zinaweza kuboreshwa.
Mipango yetu ya haraka ni kutoa angalau vifurushi vya deni, na ikiwezekana pia rpm.
Badala ya hitimisho
Zaidi ya miezi 9+ iliyopita nimekuwa ndani ya kampuni yangu
Lita kadhaa za siku za bia na msimamizi zilitumika kuunda ombi, pamoja na
Chanzo: mapenzi.com