Lep pozdrav, habr.
Če kdo izkorišča sistem
ClickHouse dobro rešuje opisane težave. Na primer, po prenosu 2 TiB podatkov iz šepeta se prilegajo 300 GiB. Ne bom se podrobneje ukvarjal s primerjavo, člankov na to temo je veliko. Poleg tega do nedavnega z našo shrambo ClickHouse ni bilo vse popolno.
Težave s porabljenim prostorom
Na prvi pogled bi moralo vse delovati dobro. Sledim retention
), nato ustvarite tabelo v skladu s priporočilom izbranega ozadja za graphite-web:
Da bi razumeli, kateri, morate vedeti, kako delujejo vstavki in nadaljnja življenjska pot podatkov v tabelah motorjev družine *MergeTree ClickHouse (grafi povzeti iz
- Vstavljeno
блок
podatke. V našem primeru so prispele metrike.
- Vsak tak blok je razvrščen glede na ključ, preden se zapiše na disk.
ORDER BY
določeno pri ustvarjanju tabele. - Po razvrščanju,
кусок
(part
) se podatki zapišejo na disk.
- Strežnik spremlja v ozadju, da ni veliko takšnih kosov in zažene ozadje
слияния
(merge
, v nadaljevanju združiti).
- Strežnik sam preneha izvajati združevanja takoj, ko se podatki prenehajo aktivno pretakati v
партицию
(partition
), vendar lahko postopek zaženete ročno z ukazomOPTIMIZE
. - Če je v particiji ostal samo en kos, spajanja ne boste mogli zagnati z običajnim ukazom; morate uporabiti
OPTIMIZE ... FINAL
Tako so prispele prve metrike. In zavzamejo nekaj prostora. Kasnejši dogodki se lahko nekoliko razlikujejo glede na številne dejavnike:
- Particijski ključ je lahko zelo majhen (en dan) ali zelo velik (več mesecev).
- Konfiguracija zadrževanja lahko ustreza več pomembnim pragom združevanja podatkov znotraj aktivne particije (kjer so zabeležene metrike) ali pa tudi ne.
- Če je podatkov veliko, se najzgodnejši kosi, ki so zaradi združevanja v ozadju morda že ogromni (če izberete neoptimalen particijski ključ), ne bodo sami združili s svežimi majhnimi kosi.
In vedno se konča enako. Prostor, ki ga zasedajo meritve v ClickHouse, se poveča le, če:
- ne veljajo
OPTIMIZE ... FINAL
ročno oz - ne vstavljajte podatkov sproti v vse particije, da se bo prej ali slej začelo spajanje v ozadju
Zdi se, da je druga metoda najlažja za izvedbo in zato ni pravilna in je bila preizkušena prva.
Napisal sem dokaj preprost skript python, ki je pošiljal navidezne meritve za vsak dan v zadnjih 4 letih in izvajal cron vsako uro.
Ker celotno delovanje ClickHouse DBMS temelji na dejstvu, da bo ta sistem prej ali slej opravil vse delo v ozadju, vendar ni znano kdaj, nisem mogel dočakati trenutka, ko se stari ogromni kosi usmilijo, da se začnejo spajati z nove male. Postalo je jasno, da moramo iskati način za avtomatizacijo vsiljenih optimizacij.
Informacije v sistemskih tabelah ClickHouse
Oglejmo si strukturo tabele
- db ime (
database
); - ime tabele (
table
); - ime in ID particije (
partition
&partition_id
); - ko je komad nastal (
modification_time
); - minimalni in maksimalni datum v kosu (razdelitev poteka po dnevih) (
min_date
&max_date
);
Obstaja tudi miza
- db ime (
Tables.database
); - ime tabele (
Tables.table
); - metrična starost, ko je treba uporabiti naslednje združevanje (
age
);
Torej:
- Imamo tabelo kosov in tabelo pravil združevanja.
- Njihovo presečišče združimo in dobimo vse tabele *GraphiteMergeTree.
- Iščemo vse particije, v katerih:
- več kot en kos
- ali je prišel čas za uporabo naslednjega pravila združevanja in
modification_time
starejši od tega trenutka.
Реализация
Ta zahteva
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
vrne vsako od particij tabele *GraphiteMergeTree, katerih združitev bi morala sprostiti prostor na disku. Edina stvar, ki jo morate storiti, je, da jih pregledate z zahtevo OPTIMIZE ... FINAL
. Končna izvedba upošteva tudi dejstvo, da se ni treba dotikati particij z aktivnim snemanjem.
Točno to počne projekt
Če program zaženete na strežniku s ClickHouse, bo preprosto začel delovati v demonskem načinu. Enkrat na uro se izvede zahteva, ki preverja, ali so se pojavile nove particije, starejše od treh dni, ki jih je mogoče optimizirati.
Naši neposredni načrti so, da zagotovimo vsaj deb pakete in, če je mogoče, tudi rpm.
Namesto zaključka
V zadnjih 9+ mesecih sem bil v svojem podjetju
Za razvoj zahteve je bilo porabljenih več litrov piva in administratorskih dni, skupaj z
Vir: www.habr.com