ClickHouse + Graphite. ինչպես զգալիորեն նվազեցնել սկավառակի տարածության սպառումը

ClickHouse + Graphite. ինչպես զգալիորեն նվազեցնել սկավառակի տարածության սպառումը

Ողջույն, հաբր.

Եթե ​​ինչ-որ մեկը շահագործում է համակարգը գրաֆիտ-վեբ և բախվել է պահեստավորման աշխատանքի հետ կապված խնդրի հետ շշուկով (IO, սկավառակի տարածություն սպառված), այնուհետև հավանականությունը, որ ClickHouse-ը փոխարինվել է, պետք է ձգտի մեկին: Այս հայտարարությունը ենթադրում է, որ երրորդ կողմի իրականացումն արդեն օգտագործվում է որպես դեյմոն ստացող չափումներ, օրինակ carbonwriter կամ գնա-ածխածին.

ClickHouse-ը լավ է լուծում նկարագրված խնդիրները։ Օրինակ, շշուկից 2TiB տվյալներ փոխանցելուց հետո դրանք տեղավորվում են 300GiB-ի մեջ: Ես մանրամասն չեմ անդրադառնա համեմատության վրա, այս թեմայի վերաբերյալ շատ հոդվածներ կան: Բացի այդ, մինչև վերջերս ամեն ինչ կատարյալ չէր մեր ClickHouse պահեստի հետ:

Սպառված տարածքի հետ կապված խնդիրներ

Առաջին հայացքից ամեն ինչ պետք է լավ աշխատի։ Հետևելով փաստաթղթավորում, ստեղծեք կոնֆիգուրացիա չափումների պահպանման սխեմայի համար (հետագա retention), այնուհետև ստեղծեք աղյուսակ՝ գրաֆիտ-վեբի համար ընտրված հետին պլանի առաջարկության համաձայն. carbon-clickhouse+graphite-clickhouse կամ graphouse, կախված նրանից, թե որ բուրգ է օգտագործվում: Եվ... ժամային ռումբը պայթում է:

Հասկանալու համար, թե որն է, դուք պետք է իմանաք, թե ինչպես են աշխատում ներդիրները և տվյալների հետագա կյանքի ուղին * ընտանիքի շարժիչների աղյուսակներում:MergeTree ClickHouse (գծապատկերները վերցված են շնորհանդեսներ Ալեքսեյ Զատելեպին).

  • Տեղադրված է блок տվյալները։ Մեր դեպքում դա չափիչն էր, որը եկավ:
    ClickHouse + Graphite. ինչպես զգալիորեն նվազեցնել սկավառակի տարածության սպառումը
  • Յուրաքանչյուր այդպիսի բլոկ դասավորված է ըստ բանալիի, նախքան սկավառակի վրա գրվելը: ORDER BYնշված է աղյուսակը ստեղծելիս:
  • Տեսակավորումից հետո՝ кусок (part) տվյալները գրվում են սկավառակի վրա:
    ClickHouse + Graphite. ինչպես զգալիորեն նվազեցնել սկավառակի տարածության սպառումը
  • Սերվերը հետևում է ֆոնին այնպես, որ նման կտորներ շատ չլինեն, և գործարկում է ֆոն слияния (merge, այսուհետ միաձուլվել):
    ClickHouse + Graphite. ինչպես զգալիորեն նվազեցնել սկավառակի տարածության սպառումը
    ClickHouse + Graphite. ինչպես զգալիորեն նվազեցնել սկավառակի տարածության սպառումը
  • Սերվերը դադարում է միաձուլումների գործարկումն ինքնուրույն, հենց որ տվյալները դադարում են ակտիվորեն հոսել դեպի партицию (partition), բայց դուք կարող եք գործընթացը սկսել ձեռքով հրամանով OPTIMIZE.
  • Եթե ​​բաժանման մեջ մնացել է միայն մեկ կտոր, ապա դուք չեք կարողանա միաձուլումը կատարել սովորական հրամանի միջոցով, դուք պետք է օգտագործեք OPTIMIZE ... FINAL

Այսպիսով, առաջին չափումները գալիս են: Եվ նրանք որոշակի տեղ են զբաղեցնում: Հետագա իրադարձությունները կարող են որոշակիորեն տարբերվել՝ կախված բազմաթիվ գործոններից.

  • Բաժանման բանալին կարող է լինել կամ շատ փոքր (օրական) կամ շատ մեծ (մի քանի ամիս):
  • Պահպանման կազմաձևը կարող է տեղավորել մի քանի կարևոր տվյալների համախմբման շեմեր ակտիվ բաժանման ներսում (որտեղ չափումները գրանցվում են), կամ գուցե ոչ:
  • Եթե ​​շատ տվյալներ կան, ապա ամենավաղ կտորները, որոնք ֆոնային միաձուլման պատճառով կարող են արդեն հսկայական լինել (եթե ընտրեք ոչ օպտիմալ բաժանման բանալի), չեն միաձուլվի թարմ փոքր կտորների հետ:

Եվ դա միշտ ավարտվում է նույնով: ClickHouse-ում չափումների զբաղեցրած տարածքը մեծանում է միայն այն դեպքում, եթե՝

  • չդիմել OPTIMIZE ... FINAL ձեռքով կամ
  • շարունակական հիմունքներով մի մտցրեք տվյալները բոլոր բաժիններում, որպեսզի վաղ թե ուշ սկսվի ֆոնային միաձուլումը

Երկրորդ մեթոդը, թվում է, ամենահեշտն է իրագործելի, և, հետևաբար, այն սխալ է և առաջինը փորձարկվել է:
Ես գրեցի բավականին պարզ python սցենար, որն ուղարկում էր կեղծ չափումներ ամեն օրվա համար վերջին 4 տարիների ընթացքում և աշխատում էր cron ամեն ժամ:
Քանի որ ClickHouse DBMS-ի ամբողջ աշխատանքը հիմնված է այն փաստի վրա, որ այս համակարգը վաղ թե ուշ կկատարի ամբողջ ֆոնային աշխատանքը, բայց հայտնի չէ, թե երբ, ես չկարողացա սպասել այն պահին, երբ հին հսկայական կտորները կսկսեն միաձուլվել: նոր փոքրերը. Պարզ դարձավ, որ մենք պետք է ճանապարհ փնտրենք հարկադիր օպտիմալացումների ավտոմատացման համար:

ClickHouse + Graphite. ինչպես զգալիորեն նվազեցնել սկավառակի տարածության սպառումը

Տեղեկություններ ClickHouse համակարգի աղյուսակներում

Եկեք նայենք աղյուսակի կառուցվածքին համակարգ.մասեր. Սա համապարփակ տեղեկատվություն է ClickHouse սերվերի բոլոր աղյուսակների յուրաքանչյուր մասի մասին: Պարունակում է, ի թիվս այլ բաների, հետևյալ սյունակները.

  • դբ անունը (database);
  • սեղանի անվանումը (table);
  • բաժանման անվանումը և ID-ն (partition & partition_id);
  • երբ ստեղծվեց կտորը (modification_time);
  • նվազագույն և առավելագույն ամսաթիվը մեկ կտորով (բաժանումը կատարվում է օրական) (min_date & max_date);

Առկա է նաև սեղան համակարգ.գրաֆիտի_պահումներ, հետևյալ հետաքրքիր դաշտերով.

  • դբ անունը (Tables.database);
  • սեղանի անվանումը (Tables.table);
  • մետրային տարիքը, երբ պետք է կիրառվի հաջորդ ագրեգացումը (age);

So.

  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. Վերջնական իրականացումը հաշվի է առնում նաև այն փաստը, որ ակտիվ ձայնագրությամբ միջնորմներին դիպչելու կարիք չկա։

Սա հենց այն է, ինչ անում է նախագիծը graphite-ch-optimizer. Yandex.Market-ի նախկին գործընկերները փորձեցին այն արտադրության մեջ, աշխատանքի արդյունքը կարող եք տեսնել ստորև։

ClickHouse + Graphite. ինչպես զգալիորեն նվազեցնել սկավառակի տարածության սպառումը

Եթե ​​ծրագիրը գործարկեք սերվերի վրա ClickHouse-ով, այն պարզապես կսկսի աշխատել դեյմոն ռեժիմով: Ժամը մեկ անգամ հարցումը կկատարվի՝ ստուգելով, թե արդյոք հայտնվել են երեք օրից ավելի հին բաժանմունքներ, որոնք կարող են օպտիմիզացվել:

Մեր անմիջական ծրագրերն են տրամադրել առնվազն դեբային փաթեթներ, իսկ հնարավորության դեպքում նաև պտույտ/րոպե:

Փոխարենը մի եզրակացության

Վերջին 9+ ամիսների ընթացքում ես եղել եմ իմ ընկերության ներսում Inno խաղեր շատ ժամանակ է ծախսել սեղմելով ClickHouse-ի և graphite-web-ի խաչմերուկում: Դա լավ փորձ էր, որի արդյունքում արագ անցում կատարվեց շշուկից դեպի ClickHouse՝ որպես չափումների պահեստ: Հուսով եմ, որ այս հոդվածը մի շարքի սկիզբն է այն մասին, թե ինչ բարելավումներ ենք արել այս փաթեթի տարբեր մասերում և ինչ է արվելու ապագայում:

Հարցումը մշակելու համար ծախսվել է մի քանի լիտր գարեջուր և ադմինիստրատիվ օրեր v0 սատանա, որի համար ուզում եմ իմ երախտագիտությունը հայտնել նրան։ Եվ նաև այս հոդվածը վերանայելու համար:

Ծրագրի էջ github-ում

Source: www.habr.com

Добавить комментарий