
Saluti, abr.
Se qualchissia sfrutta u sistema è hà scontru un prublema di prestazione di almacenamento (IO, spaziu di discu cunsumatu), allora a chance chì ClickHouse hè stata chjappata cum'è rimpiazzamentu duverà tende à unu. Questa dichjarazione implica chì una implementazione di terzu hè digià aduprata cum'è un daemon chì riceve metriche, per esempiu o .
ClickHouse risolve bè i prublemi descritti. Per esempiu, dopu avè trasferitu 2TiB di dati da u sussurru, si mette in 300GiB. Ùn aghju micca a paraguni in detail, ci sò assai articuli nantu à questu tema. Inoltre, finu à pocu tempu, micca tuttu era perfettu cù u nostru almacenamiento ClickHouse.
Prublemi cù u spaziu cunsumatu
À u primu sguardu, tuttu deve travaglià bè. Dopu , crea una cunfigurazione per u schema di almacenamiento di metrica (in più retention), dopu creà una tavola secondu a ricunniscenza di u backend sceltu per graphite-web: + o , secondu chì stack hè utilizatu. È... a bomba à orologeria spara.
Per capisce quale, avete bisognu di sapè cumu funziona l'inserzioni è u percorsu di a vita ulteriore di e dati in tavule di i mutori di a famiglia *MergeTree ClickHouse (grafici presi da Alexey Zatelepin):
- Inseritu
блокdati. In u nostru casu, era i metrichi chì sò ghjunti.

- Ogni tali bloccu hè ordinatu secondu a chjave prima di esse scrittu à u discu.
ORDER BYspecificatu quandu crea a tavola. - Dopu a classificazione,
кусок(part) i dati sò scritti à u discu.

- U servitore monitors in u sfondate in modu chì ùn ci hè micca assai tali pezzi, è lancia sfondate
слияния(merge, in seguito fusione).


- U servitore smette di eseguisce fusioni per sè stessu appena i dati si fermanu di flussu attivamente in u
партицию(partition), ma pudete inizià u prucessu manualmente cù u cumandimuOPTIMIZE. - S'ellu ci hè solu un pezzu in a partizione, allora ùn puderete micca eseguisce a fusione cù u cumandamentu di solitu chì duvete aduprà
OPTIMIZE ... FINAL
Dunque, i primi metrichi arrivanu. È piglianu un pocu di spaziu. L'avvenimenti successivi pò varià un pocu sicondu parechji fatturi:
- A chjave di partizione pò esse o assai chjuca (un ghjornu) o assai grande (parechji mesi).
- A cunfigurazione di ritenzione pò adattà à parechji soglie di aggregazione di dati significativi in a partizione attiva (induve e metriche sò registrate), o forse micca.
- Se ci sò assai dati, allora i primi pezzi, chì per via di a fusione di fondo pò esse digià enormi (se sceglite una chjave di partizione micca ottimale), ùn si fusionaranu micca cù pezzi freschi.
È finisce sempre u listessu. U spaziu occupatu da e metriche in ClickHouse aumenta solu se:
- ùn applicà micca
OPTIMIZE ... FINALmanualmente o - Ùn inserite micca e dati in tutte e partizioni in modu continuu, perchè prima o dopu una fusione di fondo inizierà
U sicondu metudu pare esse u più faciule da implementà è, per quessa, hè incorrectu è hè statu pruvatu prima.
Aghju scrittu un script python abbastanza simplice chì hà mandatu metriche dummy per ogni ghjornu per l'ultimi anni 4 è curria cron ogni ora.
Siccomu tuttu u funziunamentu di ClickHouse DBMS hè basatu annantu à u fattu chì stu sistema prima o poi farà tuttu u travagliu di fondo, ma ùn hè micca cunnisciutu quandu, ùn aghju micca pussutu aspittà per u mumentu quandu i vechji pezzi enormi degnanu di cumincià à fusione cù novi chjuchi. Hè diventatu chjaru chì avemu bisognu di circà un modu per automatizà ottimisazioni forzate.

L'infurmazioni in i tavule di u sistema ClickHouse
Fighjemu un ochju à a struttura di a tavola . Questa hè una infurmazione cumpleta nantu à ogni pezzu di tutte e tavule nantu à u servitore ClickHouse. Cuntene, frà altre cose, i seguenti culonni:
- nome db (
database); - nome di a tavola (
table); - nome di partizione è ID (
partition&partition_id); - quandu u pezzu hè statu creatu (
modification_time); - data minima è massima in un pezzu (a partizione hè fatta per ghjornu) (
min_date&max_date);
Ci hè ancu una tavola , cù i seguenti campi interessanti:
- nome db (
Tables.database); - nome di a tavola (
Tables.table); - età metrica quandu a prossima aggregazione deve esse applicata (
age);
So:
- Avemu una tavula di pezzi è una tavola di reguli di aggregazione.
- Cumbinemu a so intersezzione è uttene tutte e tavule *GraphiteMergeTree.
- Cerchemu tutte e partizioni in quale:
- più di un pezzu
- o hè ghjuntu u tempu d'applicà a prossima regula di aggregazione, è
modification_timepiù vechju di stu mumentu.
Реализация
Sta dumanda
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 ASCritorna ognuna di e partizioni di tabella *GraphiteMergeTree chì a fusione deve liberà spaziu di discu. L'unicu chì resta da fà hè di passà per elli tutti cù una dumanda OPTIMIZE ... FINAL. L'implementazione finale piglia ancu in contu u fattu chì ùn ci hè bisognu di toccu partizioni cù a registrazione attiva.
Questu hè esattamente ciò chì u prughjettu faci . L'antichi culleghi di Yandex.Market pruvò in a produzzione, u risultatu di u travagliu pò esse vistu quì sottu.

Se eseguite u prugramma in un servitore cù ClickHouse, simpricimenti principià à travaglià in modu daemon. Una volta à l'ora, una dumanda serà eseguita, cuntrollà s'ellu sò apparsu novi partizioni più vechje di trè ghjorni chì ponu esse ottimizzati.
I nostri piani immediati sò di furnisce almenu pacchetti di deb, è se pussibule ancu rpm.
Inveci di 'na cunchiusioni
In l'ultimi 9+ mesi sò statu in a mo cumpagnia spentu assai tempu tinkering à l'intersezzione di ClickHouse è graphite-web. Hè stata una bona sperienza, chì hà risultatu in una transizione rapida da u sussurru à ClickHouse cum'è un almacenamentu di metrica. Spergu chì questu articulu hè qualcosa di l'iniziu di una seria nantu à ciò chì migliure chì avemu fattu in diverse parti di sta pila, è ciò chì serà fattu in u futuru.
Diversi litri di birra è ghjorni amministrativi sò stati passati à sviluppà a dumanda, inseme cù , per quale vogliu sprimà a mo gratitudine à ellu. È ancu per rivisione stu articulu.
Source: www.habr.com




