ClickHouse + Graphite: дискний зайны зарцуулалтыг хэрхэн бууруулах вэ

ClickHouse + Graphite: дискний зайны зарцуулалтыг хэрхэн бууруулах вэ

Сайн байна уу, Хабр.

Хэрэв хэн нэгэн нь системийг ашиглаж байгаа бол бал чулуу-вэб мөн хадгалалтын гүйцэтгэлийн асуудалтай тулгарсан шивнэх (IO, дискний зай зарцуулсан), дараа нь ClickHouse-г орлуулах боломж нэг байх ёстой. Энэ мэдэгдэл нь гуравдагч этгээдийн хэрэгжүүлэлтийг аль хэдийн демон хүлээн авах хэмжигдэхүүн болгон ашигласан гэсэн үг юм. нүүрстөрөгчийн зохиолч буюу нүүрстөрөгч.

ClickHouse нь тайлбарласан асуудлуудыг сайн шийддэг. Жишээлбэл, шивнэхээс 2ТиБ өгөгдлийг шилжүүлсний дараа тэдгээр нь 300GiB-т багтдаг. Би харьцуулалтын талаар дэлгэрэнгүй ярихгүй, энэ сэдвээр олон нийтлэл бий. Нэмж дурдахад, саяхан болтол манай ClickHouse хадгалах сангийн бүх зүйл төгс байгаагүй.

Хэрэглэсэн зайтай холбоотой асуудал

Эхлээд харахад бүх зүйл сайн ажиллах ёстой. Дагаж байна баримт бичиг, хэмжүүр хадгалах схемийн тохиргоог үүсгэнэ үү (цаашид retention), дараа нь графит вэбэд зориулсан сонгосон арын хэсгийн зөвлөмжийн дагуу хүснэгт үүсгэнэ үү: нүүрстөрөгчийн даралтын байшин+графит-кликхаус буюу агуулах, аль стекийг ашиглахаас хамаарна. Тэгээд... цагийн бөмбөг дэлбэрч байна.

Аль нь болохыг ойлгохын тулд * гэр бүлийн хөдөлгүүрийн хүснэгтэд оруулга хэрхэн ажилладаг, өгөгдлийн цаашдын амьдралын замыг мэдэх хэрэгтэй.MergeTree ClickHouse (диаграмыг презентации Алексей Зателепин):

  • Оруулсан блок өгөгдөл. Манай тохиолдолд хэмжүүрүүд ирсэн.
    ClickHouse + Graphite: дискний зайны зарцуулалтыг хэрхэн бууруулах вэ
  • Ийм блок бүрийг дискэнд бичихээс өмнө түлхүүрийн дагуу ангилдаг. ORDER BYХүснэгтийг үүсгэх үед тодорхойлсон.
  • Ангилсаны дараа, кусок (part) өгөгдлийг дискэнд бичдэг.
    ClickHouse + Graphite: дискний зайны зарцуулалтыг хэрхэн бууруулах вэ
  • Сервер нь арын дэвсгэр дээр хянадаг тул ийм хэсгүүд олон байдаггүй бөгөөд арын дэвсгэрийг ажиллуулдаг слияния (merge, цаашид нэгтгэнэ).
    ClickHouse + Graphite: дискний зайны зарцуулалтыг хэрхэн бууруулах вэ
    ClickHouse + Graphite: дискний зайны зарцуулалтыг хэрхэн бууруулах вэ
  • Мэдээлэл идэвхтэй урсахаа болих үед сервер өөрөө нэгтгэх ажиллагааг зогсооно партицию (partition), гэхдээ та процессыг тушаалаар гараар эхлүүлж болно OPTIMIZE.
  • Хэрэв хуваалтад зөвхөн нэг хэсэг үлдсэн бол та ердийн командыг ашиглан нэгтгэхийг ажиллуулах боломжгүй, та ашиглах ёстой. OPTIMIZE ... FINAL

Тиймээс эхний хэмжүүрүүд гарч ирнэ. Мөн тэд бага зэрэг зай эзэлдэг. Дараах үйл явдлууд нь олон хүчин зүйлээс шалтгаалан бага зэрэг ялгаатай байж болно:

  • Хуваалтын түлхүүр нь маш жижиг (өдөр) эсвэл маш том (хэдэн сар) байж болно.
  • Хадгалах тохиргоо нь идэвхтэй хуваалт дотор (хэмжээг тэмдэглэсэн) хэд хэдэн чухал өгөгдөл цуглуулах босготой таарч болно, үгүй ​​ч байж болно.
  • Хэрэв маш их өгөгдөл байгаа бол хамгийн эртний хэсгүүд нь арын дэвсгэр дээр нэгтгэгдсэний улмаас аль хэдийн асар том хэмжээтэй байж болох юм (хэрэв та оновчтой бус хуваах түлхүүрийг сонговол) шинэ жижиг хэсгүүдтэй нийлэхгүй.

Тэгээд үргэлж адилхан дуусдаг. ClickHouse дахь хэмжигдэхүүнүүдийн эзэлдэг зай зөвхөн дараах тохиолдолд л нэмэгддэг:

  • хэрэглэхгүй OPTIMIZE ... FINAL гараар эсвэл
  • Бүх хуваалтуудад өгөгдлийг байнга бүү оруул, ингэснээр эрт орой хэзээ нэгэн цагт дэвсгэр нэгдэл эхлэх болно.

Хоёрдахь арга нь хэрэгжүүлэхэд хамгийн хялбар, тиймээс энэ нь буруу бөгөөд эхлээд туршиж үзсэн.
Би сүүлийн 4 жилийн турш өдөр бүр дамми хэмжигдэхүүн илгээж, цаг тутамд cron ажиллуулдаг маш энгийн питон скрипт бичсэн.
ClickHouse DBMS-ийн бүх үйл ажиллагаа нь энэ систем нь эрт орой хэзээ нэгэн цагт бүх үндсэн ажлыг гүйцэтгэхэд суурилдаг, гэхдээ хэзээ нь тодорхойгүй байгаа тул хуучин асар том хэсгүүд хоорондоо нэгдэж эхлэхийг би хүлээж чадсангүй. шинэ жижиг. Бид албадан оновчлолыг автоматжуулах арга замыг хайх хэрэгтэй болсон нь тодорхой болсон.

ClickHouse + Graphite: дискний зайны зарцуулалтыг хэрхэн бууруулах вэ

ClickHouse системийн хүснэгтүүдийн мэдээлэл

Хүснэгтийн бүтцийг авч үзье систем.хэсгүүд. Энэ нь ClickHouse сервер дээрх бүх хүснэгтийн хэсэг бүрийн талаарх дэлгэрэнгүй мэдээлэл юм. Бусад зүйлсээс гадна дараах багануудыг агуулна.

  • db нэр (database);
  • хүснэгтийн нэр (table);
  • хуваалтын нэр ба ID (partition & partition_id);
  • хэсэг үүссэн үед (modification_time);
  • Нэг хэсэг дэх хамгийн бага ба хамгийн их огноо (хуваалтыг өдрөөр хийдэг) (min_date & max_date);

Мөн ширээ байна system.graphite_retentions, дараах сонирхолтой талбаруудтай:

  • db нэр (Tables.database);
  • хүснэгтийн нэр (Tables.table);
  • дараагийн нэгтгэлийг ашиглах хэмжүүрийн нас (age);

Тиймээс:

  1. Бидэнд хэсгүүдийн хүснэгт болон нэгтгэх дүрмийн хүснэгт байна.
  2. Бид тэдгээрийн огтлолцлыг нэгтгэж, бүх хүснэгтийг авах болно *GraphiteMergeTree.
  3. Бид бүх хуваалтыг хайж байна:
    • нэгээс илүү хэсэг
    • эсвэл дараагийн нэгтгэх дүрмийг хэрэглэх цаг ирсэн, мөн modification_time энэ мөчөөс илүү хөгшин.

Реализация

Энэ хүсэлт

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

нэгтгэснээр дискний зайг чөлөөлөх *GraphiteMergeTree хүснэгтийн хуваалт бүрийг буцаана. Ганцхан хүсэлтээр бүгдийг нь давж гарах л үлдлээ OPTIMIZE ... FINAL. Эцсийн хэрэгжилт нь идэвхтэй бичлэг бүхий хуваалтуудад хүрэх шаардлагагүй гэдгийг харгалзан үздэг.

Төсөл яг ийм зүйл хийдэг графит-ч-оптимизатор. Yandex.Market-ийн хуучин хамтрагчид үүнийг үйлдвэрлэлд туршиж үзсэн бөгөөд ажлын үр дүнг доороос харж болно.

ClickHouse + Graphite: дискний зайны зарцуулалтыг хэрхэн бууруулах вэ

Хэрэв та програмыг ClickHouse-тэй сервер дээр ажиллуулбал зүгээр л дэмон горимд ажиллаж эхэлнэ. Цаг тутамд нэг удаа хүсэлтийг гүйцэтгэж, оновчтой болгох боломжтой гурван хоногоос дээш хуучин хуваалтууд гарч ирсэн эсэхийг шалгана.

Бидний ойрын төлөвлөгөө бол ядаж deb багцуудыг, боломжтой бол rpm-ээр хангах явдал юм.

Оронд дүгнэлтийг

Сүүлийн 9+ сарын хугацаанд би компанидаа ажилласан инно тоглоомууд ClickHouse болон graphite-web-ийн уулзвар дээр маш их цаг зарцуулсан. Энэ нь сайн туршлага байсан бөгөөд үүний үр дүнд шивнэхээс ClickHouse руу хэмжүүрийн хадгалалт болгон хурдан шилжсэн. Энэ нийтлэл нь бид энэ стекийн янз бүрийн хэсгүүдэд ямар сайжруулалт хийсэн, цаашид юу хийх талаар цувралын эхлэл болно гэж найдаж байна.

-тэй хамт хүсэлтийг боловсруулахад хэдэн литр шар айраг, админ хоног зарцуулсан v0devil, үүний төлөө би түүнд талархлаа илэрхийлэхийг хүсч байна. Мөн энэ нийтлэлийг хянан үзэхийн тулд.

Github дээрх төслийн хуудас

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх