Sveicināti, habr.
Ja kāds izmanto sistēmu
ClickHouse labi atrisina aprakstītās problēmas. Piemēram, pēc 2 TiB datu pārsūtīšanas no whisper, tie iekļaujas 300 GiB. Es nekavēšos pie salīdzinājuma sīkāk, par šo tēmu ir daudz rakstu. Turklāt vēl nesen ne viss bija ideāli ar mūsu ClickHouse krātuvi.
Problēmas ar aizņemto vietu
No pirmā acu uzmetiena visam vajadzētu darboties labi. Sekojošs retention
), pēc tam izveidojiet tabulu saskaņā ar atlasītās grafīta tīmekļa aizmugursistēmas ieteikumu:
Lai saprastu, kurš no tiem, jums jāzina, kā darbojas ieliktņi un tālākais datu dzīves ceļš * saimes dzinēju tabulāsMergeTree ClickHouse (diagrammas ņemtas no
- Ievietots
блок
datus. Mūsu gadījumā tā bija metrika, kas ieradās.
- Katrs šāds bloks pirms ierakstīšanas diskā tiek sakārtots atbilstoši atslēgai.
ORDER BY
norādīts, veidojot tabulu. - Pēc šķirošanas,
кусок
(part
) dati tiek ierakstīti diskā.
- Serveris uzrauga fonā, lai nebūtu daudz šādu gabalu, un palaiž fonu
слияния
(merge
, turpmāk apvienot).
- Serveris pārstāj darboties sapludināšanai, tiklīdz dati pārstāj aktīvi ieplūst serverī
партицию
(partition
), taču procesu var sākt manuāli ar komanduOPTIMIZE
. - Ja nodalījumā ir palicis tikai viens gabals, jūs nevarēsit palaist sapludināšanu, izmantojot parasto komandu; jums ir jāizmanto
OPTIMIZE ... FINAL
Tātad nāk pirmie rādītāji. Un tie aizņem kādu vietu. Turpmākie notikumi var nedaudz atšķirties atkarībā no daudziem faktoriem:
- Sadalīšanas atslēga var būt ļoti maza (viena diena) vai ļoti liela (vairāki mēneši).
- Saglabāšanas konfigurācija var atbilst vairākiem nozīmīgiem datu apkopošanas sliekšņiem aktīvajā nodalījumā (kur tiek reģistrēta metrika) vai arī ne.
- Ja datu ir daudz, tad agrākie gabali, kas fona sapludināšanas dēļ jau var būt milzīgi (ja izvēlaties neoptimālu sadalīšanas atslēgu), nesaplūdīs paši ar svaigiem maziem gabaliņiem.
Un tas vienmēr beidzas vienādi. Vieta, ko aizņem metrika pakalpojumā ClickHouse, palielinās tikai tad, ja:
- nepiemēro
OPTIMIZE ... FINAL
manuāli vai - nepārtraukti neievietojiet datus visos nodalījumos, lai agrāk vai vēlāk sāksies fona sapludināšana
Šķiet, ka otrā metode ir visvieglāk īstenojama, un tāpēc tā ir nepareiza un tika izmēģināta vispirms.
Es uzrakstīju diezgan vienkāršu python skriptu, kas pēdējos 4 gadus katru dienu nosūtīja fiktīvus rādītājus un palaida cron katru stundu.
Tā kā visa ClickHouse DBVS darbība ir balstīta uz to, ka šī sistēma agri vai vēlu paveiks visus fona darbus, bet nav zināms kad, tad nevarēju sagaidīt brīdi, kad vecie milzīgie gabali sāks apvienoties ar jaunas mazās. Kļuva skaidrs, ka jāmeklē veids, kā automatizēt piespiedu optimizāciju.
Informācija ClickHouse sistēmas tabulās
Apskatīsim tabulas struktūru
- db nosaukums (
database
); - tabulas nosaukums (
table
); - nodalījuma nosaukums un ID (
partition
&partition_id
); - kad gabals tika izveidots (
modification_time
); - minimālais un maksimālais datums gabalā (sadalīšana notiek pa dienām) (
min_date
&max_date
);
Ir arī galds
- db nosaukums (
Tables.database
); - tabulas nosaukums (
Tables.table
); - metriskais vecums, kad jāpiemēro nākamais apkopojums (
age
);
Tātad:
- Mums ir gabalu tabula un apkopošanas noteikumu tabula.
- Mēs apvienojam to krustojumu un iegūstam visas tabulas *GraphiteMergeTree.
- Mēs meklējam visas starpsienas, kurās:
- vairāk nekā viens gabals
- vai ir pienācis laiks piemērot nākamo apkopošanas noteikumu, un
modification_time
vecāks par šo brīdi.
Ieviešana
Šis pieprasījums
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
atgriež katru *GraphiteMergeTree tabulas nodalījumu, kuru sapludināšanai vajadzētu atbrīvot vietu diskā. Vienīgais, kas jādara, ir iziet tos visus ar lūgumu OPTIMIZE ... FINAL
. Galīgajā ieviešanā tiek ņemts vērā arī tas, ka nav nepieciešams pieskarties starpsienām ar aktīvu ierakstīšanu.
Tas ir tieši tas, ko projekts dara
Ja programmu palaižat serverī ar ClickHouse, tā vienkārši sāks darboties dēmona režīmā. Reizi stundā tiks izpildīts pieprasījums, pārbaudot, vai nav parādījušies jauni nodalījumi, kas vecāki par trim dienām, kurus var optimizēt.
Mūsu tuvākie plāni ir nodrošināt vismaz deb paketes un, ja iespējams, arī rpm.
Tā vietā, lai noslēgtu
Pēdējos 9+ mēnešus esmu bijis savā uzņēmumā
Pieprasījuma izstrādē tika pavadīti vairāki litri alus un admin dienas, kopā ar
Avots: www.habr.com