Salam, habr.
Əgər kimsə sistemi istismar edirsə
ClickHouse təsvir olunan problemləri yaxşı həll edir. Məsələn, pıçıltıdan 2TiB məlumat ötürdükdən sonra onlar 300GiB-ə uyğun gəlir. Müqayisə üzərində ətraflı dayanmayacağam, bu mövzuda çoxlu məqalələr var. Bundan əlavə, son vaxtlara qədər ClickHouse yaddaşımızda hər şey mükəmməl deyildi.
İstehlak olunan yerlə bağlı problemlər
İlk baxışdan hər şey yaxşı işləməlidir. İzləyir retention
), sonra graphite-web üçün seçilmiş backendin tövsiyəsinə əsasən cədvəl yaradın:
Hansı birini başa düşmək üçün əlavələrin necə işlədiyini və * ailəsinin mühərrik cədvəllərindəki məlumatların sonrakı həyat yolunu bilmək lazımdır.MergeTree ClickHouse (diaqramlar
- Daxil edilib
блок
data. Bizim vəziyyətimizdə, gələn ölçülər idi.
- Hər bir belə blok diskə yazılmazdan əvvəl açara görə sıralanır.
ORDER BY
cədvəl yaratarkən müəyyən edilir. - Çeşidləndikdən sonra,
кусок
(part
) verilənlər diskə yazılır.
- Server arxa planda izləyir ki, belə parçalar çox olmasın və fonu işə salır
слияния
(merge
, bundan sonra birləşdiriləcək).
- Məlumatların aktiv şəkildə daxil olmasını dayandıran kimi server öz-özünə birləşmələri dayandırır
партицию
(partition
), ancaq əmrlə prosesi əl ilə başlaya bilərsinizOPTIMIZE
. - Bölmədə yalnız bir parça qalıbsa, adi əmrdən istifadə edərək birləşməni işlədə bilməyəcəksiniz, istifadə etməlisiniz
OPTIMIZE ... FINAL
Beləliklə, ilk ölçülər gəlir. Və bir az yer tuturlar. Sonrakı hadisələr bir çox amillərdən asılı olaraq bir qədər dəyişə bilər:
- Bölmə açarı çox kiçik (bir gün) və ya çox böyük (bir neçə ay) ola bilər.
- Saxlama konfiqurasiyası aktiv bölmə daxilində (ölçmələrin qeydə alındığı yerlərdə) bir neçə əhəmiyyətli məlumat toplama həddi ilə uyğunlaşa bilər, ya da olmaya bilər.
- Əgər çoxlu məlumat varsa, o zaman arxa fonda birləşmə səbəbindən artıq böyük ola bilən ən erkən hissələr (optimal olmayan bölmə açarı seçsəniz) təzə kiçik parçalarla birləşdirilməyəcəkdir.
Və həmişə eyni bitir. ClickHouse-da ölçülərin tutduğu yer yalnız aşağıdakı hallarda artır:
- müraciət etməyin
OPTIMIZE ... FINAL
əl ilə və ya - bütün arakəsmələrə davamlı olaraq məlumat daxil etməyin, belə ki, gec-tez fon birləşməsi başlayacaq
İkinci üsul tətbiq etmək üçün ən asan görünür və buna görə də səhvdir və əvvəlcə sınaqdan keçirilmişdir.
Mən son 4 il ərzində hər gün üçün dummy metrikalar göndərən və hər saat cron işlədən kifayət qədər sadə bir piton skripti yazdım.
ClickHouse DBMS-nin bütün fəaliyyəti bu sistemin gec-tez bütün fon işlərini görəcəyinə əsaslandığından, lakin nə vaxt bilinmir, mən köhnə nəhəng parçaların birləşməyə başlamaq istədiyi anı gözləyə bilmədim. yeni kiçiklər. Məcburi optimallaşdırmaları avtomatlaşdırmağın yolunu axtarmalı olduğumuz aydın oldu.
ClickHouse sistem cədvəllərində məlumat
Cədvəlin quruluşuna nəzər salaq
- db adı (
database
); - masa adı (
table
); - ad və bölmə ID (
partition
&partition_id
); - parça yarananda (
modification_time
); - bir parçada minimum və maksimum tarix (bölmə günlə aparılır) (
min_date
&max_date
);
Masa da var
- db adı (
Tables.database
); - masa adı (
Tables.table
); - növbəti toplamanın tətbiq edilməli olduğu metrik yaş (
age
);
Belə ki:
- Parçalar cədvəlimiz və toplama qaydaları cədvəlimiz var.
- Biz onların kəsişməsini birləşdiririk və bütün cədvəlləri əldə edirik *GraphiteMergeTree.
- Bütün bölmələri axtarırıq:
- birdən çox parça
- və ya növbəti toplama qaydasını tətbiq etməyin vaxtı gəldi və
modification_time
bu andan daha yaşlı.
Tətbiq
Bu xahiş
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
Birləşməsi disk yerini boşaltmalı olan *GraphiteMergeTree cədvəl bölmələrinin hər birini qaytarır. Yeganə bir xahişlə onların hamısından keçmək qalır OPTIMIZE ... FINAL
. Son icra, həmçinin aktiv qeyd ilə arakəsmələrə toxunmağa ehtiyac olmadığını nəzərə alır.
Layihənin etdiyi də məhz budur
Proqramı ClickHouse ilə serverdə işlədirsinizsə, o, sadəcə olaraq demon rejimində işləməyə başlayacaq. Saatda bir dəfə optimallaşdırıla bilən üç gündən çox köhnə yeni arakəsmələrin olub-olmadığını yoxlayan sorğu yerinə yetiriləcək.
Bizim yaxın planlarımız ən azı deb paketləri və mümkünsə rpm təmin etməkdir.
Bunun əvəzinə bir nəticəyə
Son 9+ ay ərzində mən şirkətimdə olmuşam
Bir neçə litr pivə və admin günləri ilə birlikdə sorğunun hazırlanmasına sərf olundu
Mənbə: www.habr.com