ClickHouse + Graphite: چگونه مصرف فضای دیسک را به میزان قابل توجهی کاهش دهیم

ClickHouse + Graphite: چگونه مصرف فضای دیسک را به میزان قابل توجهی کاهش دهیم

درود، حبر.

اگر کسی از سیستم سوء استفاده کند گرافیت-وب و با مشکل عملکرد ذخیره سازی مواجه شد نجوا (IO، فضای دیسک مصرف شده)، سپس شانس اینکه ClickHouse به عنوان جایگزین انتخاب شود، باید به یک افزایش یابد. این عبارت نشان می‌دهد که برای مثال، پیاده‌سازی شخص ثالث قبلاً به‌عنوان معیارهای دریافت شبح استفاده می‌شود کاربن نویس یا گو-کربن.

ClickHouse مشکلات توصیف شده را به خوبی حل می کند. به عنوان مثال، پس از انتقال 2TiB داده از Whisper، آنها در 300GiB قرار می گیرند. من در مورد مقایسه با جزئیات صحبت نمی کنم؛ مقالات زیادی در مورد این موضوع وجود دارد. علاوه بر این، تا همین اواخر، همه چیز با فضای ذخیره سازی ClickHouse ما عالی نبود.

مشکلات فضای مصرفی

در نگاه اول، همه چیز باید به خوبی کار کند. ذیل مستندات، یک پیکربندی برای طرح ذخیره‌سازی معیارها ایجاد کنید (بیشتر retention، سپس یک جدول مطابق با توصیه باطن انتخاب شده برای graphite-web ایجاد کنید: کربن-کلیک خانه+گرافیت-کلیک خانه یا گرافیوزبسته به اینکه کدام پشته استفاده می شود. و... بمب ساعتی منفجر می شود.

برای اینکه بفهمید کدام یک، باید بدانید که درج ها چگونه کار می کنند و مسیر زندگی بیشتر داده ها در جداول موتورهای خانواده *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);
  • نام و شناسه پارتیشن (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. اجرای نهایی همچنین این واقعیت را در نظر می گیرد که نیازی به لمس پارتیشن ها با ضبط فعال نیست.

این دقیقاً همان کاری است که پروژه انجام می دهد graphite-ch-optimizer. همکاران سابق Yandex.Market آن را در تولید امتحان کردند، نتیجه کار در زیر قابل مشاهده است.

ClickHouse + Graphite: چگونه مصرف فضای دیسک را به میزان قابل توجهی کاهش دهیم

اگر برنامه را روی سروری با ClickHouse اجرا کنید، به سادگی در حالت دیمون شروع به کار می کند. هر ساعت یک بار یک درخواست اجرا می شود و بررسی می شود که آیا پارتیشن های جدید قدیمی تر از سه روز ظاهر شده اند که می توانند بهینه شوند.

برنامه های فوری ما ارائه حداقل بسته های deb و در صورت امکان دور در دقیقه است.

به جای یک نتیجه گیری

در بیش از 9 ماه گذشته من در شرکت خود بودم بازی های Inno زمان زیادی را صرف سرهم بندی کردن در تقاطع ClickHouse و graphite-web کرد. این تجربه خوبی بود که منجر به انتقال سریع از Whisper به ClickHouse به عنوان ذخیره‌سازی معیار شد. امیدوارم این مقاله شروع یک سری در مورد پیشرفت هایی باشد که در بخش های مختلف این پشته انجام داده ایم و در آینده چه کارهایی انجام خواهد شد.

چندین لیتر آبجو و روزهای مدیریت برای توسعه این درخواست صرف شد v0 شیطان، که می خواهم از او تشکر کنم. و همچنین برای بررسی این مقاله.

صفحه پروژه در github

منبع: www.habr.com

اضافه کردن نظر