ویرگول
ورودثبت نام
hamed sahami
hamed sahamihttps://www.linkedin.com/in/hamedsahami/
hamed sahami
hamed sahami
خواندن ۵ دقیقه·۱ سال پیش

Monitoring Clickhouse

سریعترین دیتابیس برای کارهای تحلیلی که این روزها برای خیلی از فعالان حوزه بیگ دیتا شناخته شده است. همواره استفاده از هر منبع ذخیره سازی اطلاعات برای محیط عملیاتی نیاز جدی و مبرمی به مانیتورینگ و پایش مداوم درخواست ها یا کوئری های در حال پردازش دارد. چگونگی استفاده کاربران و میزان استفاده آنها از منابع سرویس دهنده (در کلاستر یا کلاسترهای سازمان) بایستی به طور منظم مورد بررسی قرار بگیرد تا بهینه سازی و یا گاها آموزش های لازم در دستور کار دپارتمان داده قرار بگیرد.

علاوه برای خیل ابزارهای گوناگون مانیتورینگ در جامعه سورس باز کلیک هاوس، میتوانیم از بسترهای مصورسازی (Visulization) در سازمان مانند Metabase, Superset و حتی PowerBI با کمک نمونه کد های زیر استفاده کنیم.

مانیتورینگ کوئری ها

به طور کلی کار را بر اساس دو شاخصه زیر می توانیم دسته بندی کنیم:

  • مانیتورینگ
  • شناسائی اشکالات

نمای کلی از کلاستر

با استفاده از کوئری زیر میتوانیم چگونگی اطلاعات کمی و کیفی جداول درون دیتابیس را مشاهده کنیم تا فراوانی و در نمای دیگر اشتباهات سهوی در ساخت و طراحی جداول را شناسایی کنیم.

SELECT table, sum(rows) AS rows, max(modification_time) AS latest_modification, formatReadableSize(sum(bytes)) AS data_size, formatReadableSize(sum(primary_key_bytes_in_memory)) AS primary_keys_size, any(engine) AS engine, sum(bytes) AS bytes_size FROM clusterAllReplicas(default, system.parts) WHERE active GROUP BY database, table ORDER BY bytes_size DESC
Global overview of your cluster
Global overview of your cluster


پر هزینه ترین کوئری ها در کلیک هاوس

در گام بعدی با استفاده یک کوئری تلاش میکنیم تا کوئری هایی که برای اجرا به سمت کلیک هاوس ارسال
شده اند را پس از مرتب سازی بر اساس شاخصی مانند مدت اجرا/پردازش کوئری مشاهده کنیم که در مورد استفاده شما میتواند تغییر پیدا کند.


SELECT
type,
query_start_time,
formatReadableTimeDelta(query_duration_ms) AS query_duration,
query_id,
query_kind,
is_initial_query,
query,
concat(toString(read_rows), ' rows / ', formatReadableSize(read_bytes)) AS read,
concat(toString(result_rows), ' rows / ', formatReadableSize(result_bytes)) AS result,
formatReadableSize(memory_usage) AS `memory usage`,
exception,
concat('\n', stack_trace) AS stack_trace,
user,
initial_user,
multiIf(empty(client_name), http_user_agent, concat(client_name, ' ', toString(client_version_major), '.', toString(client_version_minor), '.', toString(client_version_patch))) AS client,
client_hostname,
databases,
tables,
columns,
used_aggregate_functions,
used_dictionaries,
used_formats,
used_functions,
used_table_functions,
ProfileEvents.Names,
ProfileEvents.Values,
Settings.Names,
Settings.Values
FROM system.query_log
WHERE (type != 'QueryStart') AND (query_kind = 'Select') AND (event_date >= (today() - 1)) AND (event_time >= (now() - toIntervalDay(1)))
ORDER BY query_duration_ms DESC
LIMIT 10
Most expensive SELECT queries
Most expensive SELECT queries

در این نمونه برای سازمان تلاش کردم از ابزار متابیس برای مصور سازی این اطلاعات استفاده کرده ام و برای مشاهده کوئری های اجرا شده از طریق این ابزار و کاربران سازمان ستونی را برای شناسایی و مشاهده اطلاعات کاربر مرتبط نیز اضافه کرده ام تا برای بررسی دقیق تر مشکل با آنها بتوانم ارتباط بگیرم.

کوئری اصلاح شده


SELECT
type,
query_start_time,
query_duration_ms,
formatReadableTimeDelta(query_duration_ms/1000) AS query_duration,
query_id,
query_kind,
is_initial_query,
query,
case when extract(query, 'userID: (\\d+)')!='' then concat('https://***.com/admin/people/',extract(query, 'userID: (\\d+)'),'/edit') else 'N/A' end AS MetabaseUserID,
concat(toString(read_rows), ' rows / ', formatReadableSize(read_bytes)) AS read,
concat(toString(result_rows), ' rows / ', formatReadableSize(result_bytes)) AS result,
formatReadableSize(memory_usage) AS `memory usage`,
exception,
concat('\n', stack_trace) AS stack_trace,
user,
initial_user,
multiIf(empty(client_name), http_user_agent, concat(client_name, ' ', toString(client_version_major), '.', toString(client_version_minor), '.', toString(client_version_patch))) AS client,
client_hostname,
databases,
tables,
columns,
used_aggregate_functions,
used_dictionaries,
used_formats,
used_functions,
used_table_functions,
FROM system.query_log
WHERE (type != 'QueryStart') AND (query_kind = 'Select') AND (event_date >= (today() - 1)) AND (event_time >= (now() - toIntervalDay(14)))
order by query_duration_ms desc

خروجی این کار که برای مدیر سرویس کلیک هاوس نیز سفارشی سازی شده است مانند تصویر زیر خواهد بود.

نمونه اطلاعات در بستر متابیس
نمونه اطلاعات در بستر متابیس

نمونه جزییات قابل مشاهده در هر یک از سطرهای اطلاعاتی نیز به شکل دیالوگ نیز قابل مشاهده و بررسی خواهد بود.

جزییات استخراج شده از کوئری
جزییات استخراج شده از کوئری

نکته! بدلیل یکسان بودن بستر مانیتورینگ و پایش داده های کلیک هاوس به آسانی با کلیک بروی لینک سفارشی شده میتوان از هویت کاربران نیز آگاه شد تا با آنها مذاکره یا Action مورد نیاز را در دستور کار قرار داد.

در بررسی جزییات نتیجه بدست آمده از کوئری میزان حجم اطلاعات خوانده شده از دیسک، حافظه جانبی یا RAM و مدت کوئری را میتوان مورد بررسی قرار داد.

مقایسه مدت اجرای کوئری ها

بر این اساس و نیاز مندی کوئری زیر میتواند به شما امکان مقایسه مدت اجرا یا هر متریک دیگری که در مقایسه کوئری ها نیاز دارید با جای گزاری و بازنویسی بخش یا ستون مربوطه در کوئری زیر صورت پذیرد.

SELECT query_id, query, formatReadableTimeDelta(query_duration_ms) AS query_duration FROM clusterAllReplicas(default, system.query_log) WHERE (type != 'QueryStart') AND (query_kind = 'Select') AND (event_time >= (now() - toIntervalHour(1))) ORDER BY event_time DESC LIMIT 10


Compare metrics between two queries
Compare metrics between two queries

در ادامه دو نسخه از یک کوئری را میتوان با شناسایی کوئری آی دی آنها از system.querylog با استفاده کوئری زیر مقایسه کرد.

WITH query_id = '...query_id_old_version...' AS first, query_id = '...query_id_new_version...' AS second SELECT PE.Names AS metric, anyIf(PE.Values, first) AS v1, anyIf(PE.Values, second) AS v2 FROM clusterAllReplicas(default, system.query_log) ARRAY JOIN ProfileEvents AS PE WHERE (first OR second) AND (event_date = today()) AND (type = 2) GROUP BY metric HAVING v1 != v2 ORDER BY (v2 - v1) / (v1 + v2) ASC, v2 ASC, metric ASC

متوسط مدت و تعداد درخواست ها

د ر نمونه کوئری و نمودار زیر می توانید تعداد و مدت صرف شده "بصورت میانگین" برای اجرای کوئری های پردازش در کلیک هاوس را مشاهده کنید تا رفتارهای نامتعارف و بحران های در حال اتفاق را مشاهده و گاها پیش بینی نمایید.

SELECT
toStartOfHour(event_time) AS event_time_h,
count() AS count_m,
avg(query_duration_ms) AS avg_duration
FROM clusterAllReplicas(default, system.query_log)
WHERE (query_kind = 'Select') AND (type != 'QueryStart') AND (event_time > (now() - toIntervalDay(3)))
GROUP BY event_time_h
ORDER BY event_time_h ASC
Average query duration and number of requests
Average query duration and number of requests

تعداد کوئری ها بر اساس کلاینت های کلیک هاوس

کوئری زیر میتواند به شما امکان مشاهده و محاسبه تعداد کوئری ها بر اساس نام کلاینت را ارائه کند تا کانال های ارتباطی بهره برداران و میزان کارهای دریافتی از سمت آنها را شناسایی نموده و برای مدیریت یا بهبود آنها اقدام مناسبی را اتخاذ نمایید.

SELECT
toStartOfMinute(event_time) AS event_time_m,
if(empty(client_name), 'unknow_or_http', client_name) AS client_name,
count(),
query_kind
FROM clusterAllReplicas(default, system.query_log)
WHERE (type = 'QueryStart') AND (event_time > (now() - toIntervalMinute(10))) AND (query_kind = 'Select')
GROUP BY
event_time_m,
client_name,
query_kind
ORDER BY
event_time_m DESC,
count() ASC
LIMIT 100


Number of SQL queries by client or use
Number of SQL queries by client or use


نتیجه گیری

در واقع امکان مشاهده و پایش تمام سرویس ها و اتفاقات به صورت چشمی توسط انسان کاری نشدنی یا به عبارتی دیگر نامطمئن است. بنابراین پیشنهاد میکنم تا با پیاده سازی کد و یا اسکریپت های مطلوب اقدام به بررسی های برنامه ریزی شده و سیستماتیک نمایید و به هنگام کشف موارد قابل رسیدگی و پیشگیری به کارشناسان و مدیران سرویس اعلان "notification" های مناسب ارسال نمایید و در صورت نبود بستر مورد نیاز از ایمیل استفاده شود.


monitoring
۵
۰
hamed sahami
hamed sahami
https://www.linkedin.com/in/hamedsahami/
شاید از این پست‌ها خوشتان بیاید