Tervehdys, habr.
Jos joku käyttää järjestelmää hyväkseen
ClickHouse ratkaisee kuvatut ongelmat hyvin. Esimerkiksi siirrettyään 2 TiB dataa whisperistä ne mahtuvat 300 GiB:iin. En viipyy vertailussa yksityiskohtaisesti, tästä aiheesta on paljon artikkeleita. Lisäksi vielä viime aikoihin asti kaikki ei ollut täydellistä ClickHouse-tallennustilassamme.
Ongelmia kulutetun tilan kanssa
Ensi silmäyksellä kaiken pitäisi toimia hyvin. Seurata retention
), luo sitten taulukko valitun taustaohjelman suosituksen mukaan grafiittiverkkoa varten:
Ymmärtääksesi kumpi, sinun on tiedettävä, kuinka insertit toimivat ja tietojen myöhempi elämänpolku *-perheen moottoritaulukoissaMergeTree ClickHouse (kaaviot otettu kohteesta
- Lisätty
блок
tiedot. Meidän tapauksessamme mittarit saapuivat.
- Jokainen tällainen lohko lajitellaan avaimen mukaan ennen levylle kirjoittamista.
ORDER BY
määritetty taulukkoa luotaessa. - Lajittelun jälkeen
кусок
(part
) tiedot kirjoitetaan levylle.
- Palvelin tarkkailee taustalla, jotta tällaisia kappaleita ei ole paljon, ja käynnistää taustan
слияния
(merge
, jäljempänä yhdistäminen).
- Palvelin lopettaa yhdistämisten suorittamisen itsestään heti, kun data lakkaa virtaamasta aktiivisesti palvelimeen
партицию
(partition
), mutta voit aloittaa prosessin manuaalisesti komennollaOPTIMIZE
. - Jos osiossa on jäljellä vain yksi kappale, et voi suorittaa yhdistämistä tavallisella komennolla; sinun on käytettävä
OPTIMIZE ... FINAL
Joten ensimmäiset mittarit saapuvat. Ja ne vievät jonkin verran tilaa. Myöhemmät tapahtumat voivat vaihdella jonkin verran useista tekijöistä riippuen:
- Osiointiavain voi olla joko hyvin pieni (päivä) tai erittäin suuri (useita kuukausia).
- Säilytyskokoonpano voi sopia useisiin merkittäviin datan aggregointikynnyksiin aktiivisen osion sisällä (johon mittarit tallennetaan), tai ehkä ei.
- Jos dataa on paljon, niin varhaisimmat palat, jotka taustan yhdistämisen vuoksi voivat olla jo valtavia (jos valitset ei-optimaalisen osiointiavaimen), eivät sulaudu uusiin pieniin paloihin.
Ja se päättyy aina samalla tavalla. Mittareiden käyttämä tila ClickHousessa kasvaa vain, jos:
- Älä lisää
OPTIMIZE ... FINAL
manuaalisesti tai - Älä lisää tietoja kaikkiin osioihin jatkuvasti, jotta ennemmin tai myöhemmin taustayhdistys alkaa
Toinen menetelmä näyttää olevan helpoin toteuttaa, ja siksi se on virheellinen ja sitä kokeiltiin ensin.
Kirjoitin melko yksinkertaisen python-skriptin, joka lähetti fiktiivisiä mittareita joka päivälle viimeisen 4 vuoden ajan ja suoritti cronin tunnin välein.
Koska ClickHouse DBMS:n koko toiminta perustuu siihen, että tämä järjestelmä tekee ennemmin tai myöhemmin kaikki taustatyöt, mutta ei tiedetä milloin, en malttanut odottaa hetkeä, jolloin vanhat valtavat palaset alkavat sulautua uusia pieniä. Kävi selväksi, että meidän oli etsittävä tapa automatisoida pakotetut optimoinnit.
Tiedot ClickHouse-järjestelmätaulukoissa
Katsotaanpa taulukon rakennetta
- db nimi (
database
); - taulukon nimi (
table
); - osion nimi ja tunnus (
partition
&partition_id
); - kun teos luotiin (
modification_time
); - minimi- ja maksimipäivämäärä kappaleessa (osiointi tapahtuu päiväkohtaisesti) (
min_date
&max_date
);
Siellä on myös pöytä
- db nimi (
Tables.database
); - taulukon nimi (
Tables.table
); - metrinen ikä, jolloin seuraavaa aggregaatiota tulisi käyttää (
age
);
Joten:
- Meillä on kappaleiden taulukko ja aggregointisääntöjen taulukko.
- Yhdistämme niiden risteyksen ja saamme kaikki taulukot *GraphiteMergeTree.
- Etsimme kaikkia osioita, joissa:
- enemmän kuin yksi kappale
- tai on tullut aika soveltaa seuraavaa yhdistämissääntöä ja
modification_time
vanhempi kuin tämä hetki.
Реализация
Tämä pyyntö
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
palauttaa jokaisen *GraphiteMergeTree-taulukkoosion, jonka yhdistämisen pitäisi vapauttaa levytilaa. Ainoa asia, joka on jäljellä, on käydä ne kaikki läpi pyynnöstä OPTIMIZE ... FINAL
. Lopullisessa toteutuksessa huomioidaan myös se, että osioihin ei tarvitse koskettaa aktiivisella tallennuksella.
Tämä on juuri sitä, mitä projekti tekee
Jos suoritat ohjelman palvelimella ClickHousen kanssa, se alkaa yksinkertaisesti toimia demonitilassa. Kerran tunnissa suoritetaan pyyntö, joka tarkistaa, onko ilmaantunut uusia, yli kolme päivää vanhempia osioita, jotka voidaan optimoida.
Lähisuunnitelmissamme on toimittaa ainakin deb-paketit ja mahdollisuuksien mukaan myös rpm.
Sen sijaan johtopäätös
Viimeiset 9+ kuukautta olen ollut yrityksessäni
Pyynnön kehittämiseen kului useita litroja olutta ja adminpäiviä mm
Lähde: will.com