ЦлицкХоусе + Грапхите: како значајно смањити потрошњу простора на диску

ЦлицкХоусе + Грапхите: како значајно смањити потрошњу простора на диску

Поздрав хабр.

Ако неко експлоатише систем графитна мрежа и наишао на проблем перформанси складиштења шапат (ИО, потрошен простор на диску), онда би шанса да је ЦлицкХоусе постављена као замена требало да тежи једној. Ова изјава имплицира да се имплементација треће стране већ користи као демон који прима метрику, нпр. царбонвритер или го-царбон.

ЦлицкХоусе добро решава описане проблеме. На пример, након преноса 2ТиБ података из шапата, они се уклапају у 300ГиБ. Нећу се задржавати на поређењу у детаље; има доста чланака на ову тему. Поред тога, донедавно није све било савршено са нашим ЦлицкХоусе складиштем.

Проблеми са заузетим простором

На први поглед, све би требало да функционише добро. Следећи документација, креирајте конфигурацију за шему складиштења метрика (даље retention), а затим креирајте табелу према препоруци изабраног бацкенд-а за грапхите-веб: царбон-цлицкхоусе+грапхите-цлицкхоусе или грапхоусе, у зависности од тога који стек се користи. И... темпирана бомба експлодира.

Да бисте разумели који, морате знати како функционишу уметци и даљи животни пут података у табелама мотора породице *МергеТрее ЦлицкХоусе (графикони преузети из презентације Алексеј Зателепин):

  • Umetnuto блок података. У нашем случају, метрика је стигла.
    ЦлицкХоусе + Грапхите: како значајно смањити потрошњу простора на диску
  • Сваки такав блок се сортира према кључу пре него што се упише на диск. ORDER BYнаведен при креирању табеле.
  • Након сортирања, кусок (part) подаци се уписују на диск.
    ЦлицкХоусе + Грапхите: како значајно смањити потрошњу простора на диску
  • Сервер прати у позадини да нема много таквих комада и покреће позадину слияния (merge, у даљем тексту спајање).
    ЦлицкХоусе + Грапхите: како значајно смањити потрошњу простора на диску
    ЦлицкХоусе + Грапхите: како значајно смањити потрошњу простора на диску
  • Сервер престаје да ради обједињавање сам од себе чим подаци престану да активно тече у партицию (partition), али можете ручно покренути процес помоћу команде OPTIMIZE.
  • Ако је у партицији остао само један комад, тада нећете моћи да покренете спајање користећи уобичајену команду; морате користити OPTIMIZE ... FINAL

Дакле, стижу прве метрике. И заузимају мало простора. Накнадни догађаји могу донекле варирати у зависности од многих фактора:

  • Кључ за партиционисање може бити или веома мали (један дан) или веома велики (неколико месеци).
  • Конфигурација задржавања може да одговара неколико значајних прагова агрегације података унутар активне партиције (где се бележе метрике), а можда и не.
  • Ако има много података, онда се најранији делови, који због спајања у позадини могу већ бити огромни (ако одаберете неоптималан кључ за партиционисање), неће спојити сами себе са свежим малим комадима.

И увек се исто заврши. Простор који заузимају метрика у ЦлицкХоусе-у се повећава само ако:

  • не примјењују OPTIMIZE ... FINAL ручно или
  • немојте стално убацивати податке у све партиције, да би пре или касније почело спајање у позадини

Чини се да је други метод најлакши за имплементацију и стога је нетачан и први је испробан.
Написао сам прилично једноставну Питхон скрипту која је слала лажне метрике за сваки дан у протекле 4 године и покретала црон сваки сат.
Пошто се цео рад ЦлицкХоусе ДБМС заснива на чињеници да ће овај систем пре или касније обавити све позадинске послове, али се не зна када, нисам могао да дочекам тренутак када се стари огромни комади удостоје да почну да се спајају. нове мале. Постало је јасно да морамо тражити начин да аутоматизујемо принудне оптимизације.

ЦлицкХоусе + Грапхите: како значајно смањити потрошњу простора на диску

Информације у системским табелама ЦлицкХоусе

Хајде да погледамо структуру табеле систем.делови. Ово су свеобухватне информације о сваком делу свих табела на ЦлицкХоусе серверу. Садржи, између осталог, следеће колоне:

  • дб име (database);
  • име табеле (table);
  • име и ИД партиције (partition & partition_id);
  • када је комад настао (modification_time);
  • минимални и максимални датум у комаду (подела се врши по дану) (min_date & max_date);

Ту је и сто систем.грапхите_ретентионс, са следећим интересантним пољима:

  • дб име (Tables.database);
  • име табеле (Tables.table);
  • метрички узраст када треба применити следећу агрегацију (age);

Дакле:

  1. Имамо табелу делова и табелу правила агрегације.
  2. Комбинујемо њихов пресек и добијамо све табеле *ГрапхитеМергеТрее.
  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

враћа сваку партицију табеле *ГрапхитеМергеТрее чије би спајање требало да ослободи простор на диску. Остаје само да их све прођете са захтевом OPTIMIZE ... FINAL. Коначна имплементација такође узима у обзир чињеницу да нема потребе додиривати партиције са активним снимањем.

То је управо оно што пројекат ради грапхите-цх-оптимизер. Бивши колеге из Иандек.Маркет-а су то покушали у производњи, резултат рада се може видети у наставку.

ЦлицкХоусе + Грапхите: како значајно смањити потрошњу простора на диску

Ако покренете програм на серверу са ЦлицкХоусе, он ће једноставно почети да ради у демонском режиму. Једном на сат ће се извршавати захтев који проверава да ли су се појавиле нове партиције старије од три дана које се могу оптимизовати.

Наши непосредни планови су да обезбедимо барем деб пакете, а ако је могуће и рпм.

Уместо закључка

Током протеклих 9+ месеци био сам у својој компанији ИнноГамес провео доста времена петљајући на раскрсници ЦлицкХоусе-а и графитне мреже. Било је то добро искуство, које је резултирало брзим преласком са шапата на ЦлицкХоусе као складиште метрике. Надам се да је овај чланак нешто као почетак серије о томе која смо побољшања направили у различитим деловима овог стека и шта ће бити урађено у будућности.

Неколико литара пива и админ дана потрошено је на израду захтева, заједно са в0девил, на чему желим да му изразим своју захвалност. И за преглед овог чланка.

Страница пројекта на гитхуб-у

Извор: ввв.хабр.цом

Додај коментар