ClickHouse + Graphite: diskdə istifadə olunan yeri əhəmiyyətli dərəcədə azaltmaq.

ClickHouse + Graphite: diskdə istifadə olunan yeri əhəmiyyətli dərəcədə azaltmaq.

Salam, habr.

Kimsə sistemi istismar edirsə graphite-web və saxlama performansı problemi ilə qarşılaşırsa whisper (IO, istifadə olunan disk sahəsi), ClickHouse-un alternativ olaraq nəzərdən keçirilmə ehtimalı birə yaxın olmalıdır. Bu ifadə, indi metriklərin qəbul edilməsi üçün üçüncü tərəf bir həllin istifadəsində olduğunu göstərir, məsələn carbonwritergo-carbon.

ClickHouse təsvir olunan problemləri yaxşı həll edir. Məsələn, whisper-dan 2TiB məlumat köçürdükdən sonra, bunlar 300GiB-ə sığdı. Məsələnin müqayisəsi ilə uzun müddət dayanmayacağam, bu mövzuda kifayət qədər məqalə var. Həmçinin, son zamanlarda bizim ClickHouse saxlama sistemi ilə hər şey ideal deyildi.

İstifadə olunan yer problemləri

Birinci baxışda, hər şey yaxşı işləməlidir. İzləyərək sənəd, metriklərin saxlanma sxemi üçün konfiqurasiya yaradırıq (daha sonra retention), sonra seçilmiş arxa tərəf üzrə graphite-web üçün tövsiyələrə uyğun olaraq cədvəl yaradırıq: carbon-clickhouse+graphite-clickhousegraphouse, hansı yığımdan asılı olaraq. Və... gecikmiş bomba işə düşür.

Hansının olduğunu anlamaq üçün, daxil etmələrin və məlumatların cədvəllərdəki sonrakı yaşam dövrlərinin necə işlədiyini bilmək lazımdırMergeTree ClickHouse (diaqramlar Alexey Zatelepinin təqdimatından alınmışdır): Daxil edilir

  • məlumat blokudur. Bizim halda, buraya metriklər gəldi. Hər belə blok diskə yazılmadan əvvəl yaradılan cədvələ uyğun olaraq
    ClickHouse + Graphite: diskdə istifadə olunan yeri əhəmiyyətli dərəcədə azaltmaq.
  • sıralanır. ORDER BYSıralamadan sonra,
  • parça ) məlumat diskinə yazılır. (partServer, arxa planda çox sayda parçanın olmamasına diqqət yetirir və arxa plan
    ClickHouse + Graphite: diskdə istifadə olunan yeri əhəmiyyətli dərəcədə azaltmaq.
  • birləşmələrini merge (merge, sonra mərləşdirir).
    ClickHouse + Graphite: diskdə istifadə olunan yeri əhəmiyyətli dərəcədə azaltmaq.
    ClickHouse + Graphite: diskdə istifadə olunan yeri əhəmiyyətli dərəcədə azaltmaq.
  • Server, məlumatlar aktiv şəkildə daxil olmağa başladıqda mərlərini avtomatik olaraq dayandırır partiya (partition), lakin prosesi əllə işə salmaq mümkündür işlətmək lazım olsa, MySQL məlumat fayllarını yenilərək onları müasir saxlanma formatına keçirəcək..
  • Əgər partiyada yalnız bir parça qalıbsa, sadə komanda ilə birləşdirmək mümkün deyil, buna görə istifadə etmək lazımdır OPTIMIZE ... FINAL

Beləliklə, ilk metriklər gəlir. Və bunlar bir qədər yer tutur. Sonrakı hadisələr bir çox faktordan asılı olaraq bir az dəyişə bilər:

  • Partiya açarı çox kiçik (bir gün) və ya çox böyük (bir neçə ay) ola bilər.
  • Retention konfiqurasiyası aktiv partiyada (metriklərin yazıldığı yer) bir neçə mühüm məlumat toplama həddini saxlayır, ya da saxlamaya bilər.
  • Əgər çox məlumat varsa, arxa planda birləşdirilmələr səbəbiylə ən erkən parçalar (optimal olmayanda) yeni kiçik parçalarla öz-özünə birləşməyəcək.

Və həmişə eyni formada bitir. ClickHouse-da metriklərin tutduğu yer yalnız artır, əgər:

  • dəyişik etməzsə OPTIMIZE ... FINAL əllə və ya
  • Bütün parçalara davamlı olaraq məlumat daxil etməmək, nəhayət fon birləşməni başlatmaq üçün

İkinci metod, həyata keçirilməsi ən sadə görünür və beləliklə, o yanlışdır və əvvəlcə sınanmışdır.
Mən python-da kifayət qədər sadə bir skript yazdım ki, bu skript son 4 il ərzində hər gün üçün saxta metriklər göndərirdi və hər saat crontab ilə işə düşürdü.
ClickHouse DBMS-in bütün işi o prinsipi əsasında qurulub ki, bu sistem nəhayət bütün fon işlərini görəcək, amma nə vaxt olacağı bilinmir, buna görə də köhnə böyük hissələrin yeni kiçiklərlə birləşmək üçün başlayacağı anı gözləyə bilmədim. Aydın oldu ki, məcburi optimizasiyaların avtomatlaşdırılması üsulunu axtarmaq lazımdır.

ClickHouse + Graphite: diskdə istifadə olunan yeri əhəmiyyətli dərəcədə azaltmaq.

ClickHouse sistem cədvəlindəki məlumat

Cədvəl strukturuna nəzər salaq system.parts. Bu, ClickHouse serverindəki bütün cədvəllərin hər bir parçası haqqında ətraflı məlumatdır. O, aşağıdakı sütunları əhatə edir:

  • verilənlər bazasının adı (database);
  • cədvəl adı (table);
  • hissənin adı və ID (partition & partition_id);
  • hissənin yaradıldığı vaxt (modification_time);
  • hissədə minimum və maksimum tarix (parçalanma günlər üzrə aparılır) (min_date & max_date);

Həmçinin aşağıdakı maraqlı sahələri olan cədvəl var system.graphite_retentions,

  • verilənlər bazasının adı (Tables.database);
  • cədvəl adı (Tables.table);
  • metrikanın yaşı, növbəti agregasiyanın tətbiq olunmalı olduğu vaxt (age);

Beləliklə:

  1. Bizim parçalar cədvəlimiz və agregasiya qaydaları cədvəlimiz var.
  2. Onların kəsişməsini birləşdirərək bütün *GraphiteMergeTree cədvəllərini alırıq.
  3. Bütün parçalarda axtarırıq ki,
    • bir neçə hissə vardır
    • və ya növbəti agregasiya qaydasının tətbiq olunma vaxtı gəlib çatıb, modification_time bu vaxtdan köhnədir.

Həyata keçirmə

Bu sorgu

SELECT
    concat(p.database, '.', p.table) AS table,
    p.partition_id AS partition_id,
    p.partition AS partition,
    -- Tətbiq oluna bilən "ən köhnə" qayda
    -- parça üçün, amma gələcəkdə deyil, sm (*)
    max(g.age) AS age,
    -- Hissədəki hissələrin sayı
    countDistinct(p.name) AS parts,
    -- Hissədə ən köhnə metrik 00:00:00 növbəti gündür
    toDateTime(max(p.max_date + 1)) AS max_time,
    -- Hissə hansı vaxt optimallaşdırılmalıdır
    max_time + age AS rollup_time,
    -- Hissədəki ən köhnə hissənin nə vaxt yeniləndiyi
    min(p.modification_time) AS modified_at
FROM system.parts AS p
INNER JOIN
(
    -- Bütün *GraphiteMergeTree cədvəlləri üçün bütün qaydalar
    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
    -- Yalnız aktiv hissələr
    p.active
    -- (*) Və yalnız o satırlar, harada ki, agregasiya qaydaları artıq tətbiq olunmalıdır
    AND ((toDateTime(p.max_date + 1) + g.age) < now())
GROUP BY
    table,
    partition
HAVING
    -- Yalnız optimizasiya vaxtından gənc parçalar
    (modified_at  1)
ORDER BY
    table ASC,
    partition ASC,
    age ASC

hər bir *GraphiteMergeTree cədvəlinin bölmələrini qaytarır ki, mərkəzləşdirmələri, disk sahəsinin boşaldılması ilə nəticələnməlidir. İndi isə sadəcə olaraq, onların hamısına sorğu ilə keçmək lazımdır. OPTIMIZE ... FINAL. Son icraatda, aktiv yazma olan bölmələri itələmə ehtiyacının olmadığı da nəzərə alınıb.

B именно делает проект graphite-ch-optimizer. Keçmiş yoldaşlarım Yandex.Market-də bunu prod-da test etdilər, işin nəticələrini aşağıda görə bilərsiniz.

ClickHouse + Graphite: diskdə istifadə olunan yeri əhəmiyyətli dərəcədə azaltmaq.

Əgər proqramı ClickHouse serverində işə salsanız, o, sadəcə olaraq, demon rejimində işləməyə başlayacaq. Saatda bir dəfə sorğu icra olunacaq, yeni bir neçə gün ərzində optimallaşdırıla biləcək bölmələrin olub-olmadığını yoxlayacaq.

Gələcək planlarımız — ən azı deb paketlərini təmin etməkdir, mümkün olduqda isə rpm paketləri də.

Nəticə olaraq

Keçən 9 aydan çox müddətdə mən içindəki şirkətimdə InnoGames ClickHouse və graphite-web arasında işləməkdə çox zaman keçirdim. Bu, yaxşı bir təcrübə idi, nəticədə whisper-dan ClickHouse-a müştərilər üçün metriklərinin saxlanması üçün keçid edə biləcəyik. Ümid edirəm ki, bu məqalə — bizim bu stekdə müxtəlif hissələrdə etdiyimiz təkmilləşdirmələr haqqında bir sıra yazıların başlanğıcı olacaq, eyni zamanda gələcəkdə nələrin ediləcəyini göstərəcək.

Sorğunun hazırlanması üçün bir neçə litr pivə və admin günləri vurdum ki, v0devil, ona görə də ona təşəkkürümü ifadə etmək istəyirəm. Həmçinin bu məqalənin redaktəsi üçün.

Layihənin github-da səhifəsi

Mənbə: habr.com

DDoS qoruması olan saytlara etibarlı hosting satın alın, VPS VDS serverlər 🔥 DDoS qoruması olan saytlara etibarlı hosting satın alın, VPS VDS serverlər | ProHoster