Ali Fattahi
Ali Fattahi
خواندن ۴ دقیقه·۷ ماه پیش

مانیتورینگ و تشخیص ناهنجاری (‌Anomaly) در داده ها با استفاده از Grafana+Prometheus

در اغلب شرکت ها برای نظارت بر سرورها ، منابع، شبکه و… ،‌ از ابزارهای مانیتورینگ استفاده میکنند که به آنها کمک میکند با مشاهده داده ها و نمودارها، پیش از وقوع یک حادثه، اقدامات پیشگیرانه را انجام دهند. یکی از چالش های تیم های نظارت، این است که به مرور زمان، تعداد این نمودارها زیاد میشود و عملا امکان بررسی همزمان همه آنها وجود ندارد. برای حل این مساله اقدام به تعریف تعدادی هشدار برای هریک از انها میکنند تا در زمان وقوع مشکل و یا قبل از آن متوجه شده و اقدامات لازم را انجام دهند.


به عنوان مثال، ما برای دیسک، یک مانیتور و هشدار تنظیم می‌کنیم تا در زمانی که ظرفیت استفاده شده ی آن به ۸۰٪ رسید یک هشدار برای ما ارسال شود و پیش از وقوع حادثه،‌ اقدامات لازم را انجام دهیم.

به نظر همه چیز خوب است تا این که یک ناهنجاری رخ میدهد.

ناهنجاری چیست ؟

به بیان ساده، بی نظمی در داده‌ها و هر داده‌ی دورافتاده (outlierها) را میتوان یک ناهنجاری در نظر گرفت. به عنوان مثال افزایش یا کاهش حجم استفاده شده دیسک در یک بازه زمانی کوتاه را میتوان یک ناهنجاری نامید.

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

چطور هنجارها را تشخیص دهیم ؟

راه های زیادی برای تشخیص ناهنجاری در داده های time series وجود دارد. از محاسبات ساده گرفته تا استفاده از شبکه های عصبی مانند LSTMها. ما در این پست قرار است از روش "3sigma rule" استفاده کنیم که به نام قانون 99-95-68 نیز شناخته میشود

به صورت خلاصه ،‌ قانون 3Sigma بیان میکند که تقریبا تمام داد های نرمال ما باید در ۳ انحراف معیار از مقدار متوسط داده های ما باشد.

3-sigma قانون
3-sigma قانون

انتظار می‌رود حدود 68 درصد از داده‌های ما در یک انحراف استاندارد، 95 درصد در 2، و تقریباً تمام داده‌های ما در 3 انحراف استاندارد از میانگین باشد.

در این مقاله، ما می‌خواهیم مقدار انحراف معیار را نسبت به میانگین آن اندازه گیری کرده و در صورتی که بالاتر از عدد 3.0 بود به عنوان یک ناهنجاری در نظر بگیریم. به عبارتی باید مقدار Z-Score ما بالاتر از 3.0 باشد

z-score فرمول
z-score فرمول

در Grafana برای محاسبه ی این فرمول به ۳ مورد نیاز داریم

  • یک Datapoint که مقادیر یک بازه زمانی (x) را نمایش میدهد
  • میانگین داده های ما در یک دوره زمانی طولانی تر(μ)
  • انحراف معیار در بازه زمانی یکسان (طولانی تر) (σ)

برای این مبحث ما از متریک node_disk_writes_completed_total استفاده میکنیم. این متریک نشان دهنده تعداد write های موفق بر روی دیسک است.

محاسبه ی میانگین و انحراف معیار مورد نظر ما با استفاده از از توابع داخلی Prometheus به سادگی قابل انجام است.

محاسبه میانگین - avg_over_time :

avg_over_time(node_disk_writes_completed_total{instance=&quot$node&quot,job=&quot$job&quot,device=~&quot$diskdevices&quot}[1d]))

محاسبه انحراف معیار - stddev_over_time:

stddev_over_time(node_disk_writes_completed_total{instance=&quot$node&quot,job=&quot$job&quot,device=~&quot$diskdevices&quot}[1d])

دو کوئری بالا مقادیر میانگین و انحراف معیار را در یک بازه زمانی ۱ روزه [1d] به ما میدهد

آخرین بخش از داده های ما به دست آوردن یک Datapoint برای x در فرمول ما است که با گرفتن یک میانگین دیگر در طول زمان میتوان آن را به دست آورد اما این بازه زمانی توسط یک متغیر در داشبورد گرافانا مشخص میشود و مقدار ثابت ۱ روزه ندارد.

avg_over_time(node_disk_writes_completed_total{instance=&quot$node&quot,job=&quot$job&quot,device=~&quot$diskdevices&quot}[$__rate_interval]

جمع بندی کوئری ها و قرار دادن در فومول Z-Score

(avg_over_time(node_disk_writes_completed_total{instance=&quot$node&quot,job=&quot$job&quot,device=~&quot$diskdevices&quot}[$__rate_interval]) -avg_over_time(node_disk_writes_completed_total{instance=&quot$node&quot,job=&quot$job&quot,device=~&quot$diskdevices&quot}[1d])) / stddev_over_time(node_disk_writes_completed_total{instance=&quot$node&quot,job=&quot$job&quot,device=~&quot$diskdevices&quot}[1d])

نتایج :

با اجرای کوئری بر روی داده های مانیتورینگ نمودارهای زیر را مشاهده میکنیم

نمودار میله ای داده ها
نمودار میله ای داده ها

به میله های بزرگ از چپ به راست توجه کنید. ما میخواهیم برای این میله ها هشدار ارسال کنیم اما نه برای میله های کوچک در سمت چپ انها

این نموداری است که کوئری بررسی ناهنجاری به ما میدهد:

نمودار ناهنجاری
نمودار ناهنجاری

اگر مقدار آستانه (threshold >=3) تنظیم شود،‌میله های کوچکتر در هشدارها قرار نمیگیرند اما میله های بزرگ در هشدار ما قرار میگیرند زیرا که خیلی بزرگ هستند.

یک مثال دیگر

نمودار میله ای داده ها
نمودار میله ای داده ها


نمودار بالا دارای میله های بسیار بیشتری نسبت به مثال قبل است (به عبارتی دارای نویز بیشتری است)، بنابراین ما یک آستانه (threshold) ایستا نمی‌خواهیم که روی هر یک از میله ها عمل کند بلکه باید روی میله های خارج از حد معمول عمل کند. با اجرای کوئری Anomaly خروجی زیر را دریافت میکنیم

نمودار ناهنجاری
نمودار ناهنجاری

توجه داشته باشید که چگونه نتایج به امتیاز z 2.5 نزدیک می شوند، اما هرگز از آستانه 3 ما فراتر نمی روند، به طور خودکار این واقعیت را در نظر میگیرد که سیگنال نویز بیشتری دارد.


صحبت نهایی:

پیاده سازی هشدارها برای تشخیص ناهنجاری در داده های مانیتورینگ یکی از موارد حیاتی برای پیشگیری از وقوع حوادث است. بر اساس فرمول بالا علاوه بر این که می توان ناهنجاری ها را در مصرف Ram/CPU/Disk/Load و… را تشخیص داد،‌ میتوان برای شناسایی زمان بیکاری CPU، حافظه فعلی موجود،‌ فضای فعلی موجود در دیسک مورد استفاده قرار گیرد

تشخیص ناهنجاریمانیتورینگgrafanaprometheus
شاید از این پست‌ها خوشتان بیاید