Skip to content

فصل ۵ — پایش متریک و هشدار (Metrics Monitoring and Alerting)

خلاصهٔ تحلیلی — این متن چکیدهٔ مفاهیم فصل به زبان فارسی است، نه ترجمهٔ واژه‌به‌واژه.

طراحی یک سیستم داخلی پایش متریک و هشدار در ابعاد شرکت‌های بزرگ (مشابه Prometheus، Datadog و Grafana). مرزبندی مهم گام ۱: فقط متریک‌های عملیاتی (CPU، حافظه، QPS و…) — نه لاگ (قلمرو ELK) و نه tracing توزیع‌شده.

گام ۱ — نیازمندی‌ها

  • مقیاس: ۱۰۰ میلیون DAU؛ ۱٬۰۰۰ استخر سرور × ۱۰۰ ماشین × ۱۰۰ متریک ≈ ۱۰ میلیون متریک.
  • نگهداری ۱ سال با سیاست کاهش دقت: دادهٔ خام ۷ روز، دقت ۱ دقیقه تا ۳۰ روز، دقت ۱ ساعت تا ۱ سال.
  • کانال‌های هشدار: ایمیل، تلفن، PagerDuty و webhook.
  • غیرکارکردی: مقیاس‌پذیری، تأخیر کم برای داشبورد و هشدار، پایایی (هشدار حیاتی نباید گم شود) و انعطاف برای فناوری‌های آینده.

گام ۲ — طراحی سطح بالا

پنج جزء بنیادی: جمع‌آوری داده، انتقال داده، ذخیره‌سازی، هشدار و بصری‌سازی.

مدل داده — سری زمانی

هر متریک یک سری زمانی است: نام متریک + مجموعه‌ای از برچسب‌ها (label، مثل host و env) + آرایه‌ای از جفت‌های (مقدار، timestamp). قالب رایج ورودی «line protocol» است (Prometheus، OpenTSDB). الگوی دسترسی: نوشتن سنگین و دائمی، خواندن spiky (داشبورد و هشدارها به‌صورت انفجاری کوئری می‌زنند).

انتخاب storage — دیتابیس سری زمانی

دیتابیس رابطه‌ای برای این کار مناسب نیست: کوئری‌هایی مثل میانگین متحرک به SQL پیچیده نیاز دارند، هر برچسب ایندکس جدا می‌خواهد و در نوشتن سنگین ضعیف است. NoSQL عمومی هم مهندسی اسکیمای پیچیده می‌طلبد. راه درست TSDB اختصاصی است (InfluxDB، Prometheus): کش درون-حافظه‌ای + دیسک، فشرده‌سازی داخلی، مدیریت retention و کوئری بهینه برای برچسب‌ها — به شرط کاردینالیتی پایین برچسب‌ها. نکتهٔ کارایی از مقالهٔ فیس‌بوک (Gorilla): ~۸۵٪ کوئری‌ها مربوط به ۲۶ ساعت اخیرند؛ TSDB ای که از این خاصیت بهره ببرد بسیار سریع‌تر است.

اجزا

منبع متریک ← جمع‌کنندهٔ متریک ← TSDB ← سرویس کوئری ← سیستم هشدار و سیستم بصری‌سازی.

گام ۳ — بررسی عمیق

جمع‌آوری: pull یا push؟

  • Pull (سبک Prometheus): جمع‌کننده‌ها endpoint استاندارد /metrics سرویس‌ها را دوره‌ای می‌خوانند؛ فهرست endpoint ها از service discovery (etcd/ZooKeeper) می‌آید. برای چند جمع‌کننده بدون داده تکراری، هر جمع‌کننده با consistent hashing مالک زیرمجموعه‌ای از سرورهاست. مزیت‌ها: دیباگ آسان (endpoint را خودت باز کن)، health check طبیعی (پاسخ ندادن = خرابی)، اصالت داده (فهرست از پیش تعریف شده).
  • Push (سبک CloudWatch/Graphite): agent روی هر سرور متریک‌ها را (با تجمیع محلی برای کاهش حجم) به کلاستر جمع‌کننده می‌فرستد؛ جمع‌کننده پشت load balancer با auto-scaling. مزیت‌ها: کارهای کوتاه‌عمر (batch job) را از دست نمی‌دهد (در pull به push gateway نیاز است)، با فایروال/شبکهٔ پیچیده سازگارتر است.

جمع‌بندی کتاب: برنده‌ای وجود ندارد؛ سازمان بزرگ احتمالاً هر دو را لازم دارد (به‌ویژه با serverless که جای نصب agent ندارد).

مقیاس‌دهی خط لولهٔ انتقال

بین جمع‌کننده و TSDB یک صف (Kafka) قرار می‌گیرد: جداسازی جمع‌آوری از پردازش و جلوگیری از گم شدن داده هنگام در دسترس نبودن دیتابیس. مقیاس‌دهی با پارتیشن‌ها: بر اساس نام متریک (تا consumer بتواند تجمیع کند)، برچسب‌ها، و اولویت‌بندی متریک‌های مهم. جایگزین: سیستم‌هایی مثل Gorilla بدون صف واسط هم به همان پایایی می‌رسند — نگهداری Kafka در مقیاس تولید کار کوچکی نیست.

محل تجمیع (aggregation)

سه گزینه: agent کلاینت (فقط منطق ساده مثل شمارندهٔ دقیقه‌ای)، خط لولهٔ ingestion (با Flink؛ حجم نوشتن بسیار کم می‌شود اما دادهٔ خام و دقت از دست می‌رود و رویدادهای دیررس چالش‌اند) و سمت کوئری (بدون از دست دادن داده اما کوئری کندتر).

سرویس کوئری و زبان کوئری

سرویس کوئری جدا، کلاینت‌ها را از TSDB مستقل می‌کند و کش نتایج بار دیتابیس را کم می‌کند — اما استدلال مخالف هم معتبر است: ابزارهای بصری‌سازی/هشدار plugins قدرتمندی برای TSDB های معروف دارند و TSDB خوب کش خودش را دارد. TSDB ها به‌جای SQL زبان اختصاصی دارند (مثل Flux در InfluxDB) چون تحلیل سری زمانی در SQL به‌شدت ناخوانا می‌شود.

بهینه‌سازی فضا

  • کدگذاری delta-of-delta: به‌جای timestamp کامل ۳۲ بیتی، اختلاف‌ها ذخیره می‌شوند (مثلاً «۱۰ ثانیه» فقط ۴ بیت).
  • Downsampling: مطابق سیاست retention، دادهٔ قدیمی به دقت ۱ دقیقه و بعد ۱ ساعت تجمیع می‌شود.
  • Cold storage برای دادهٔ کم‌مصرف قدیمی.

سیستم هشدار

جریان: قواعد به‌صورت فایل‌های YAML تعریف و در کش بارگذاری می‌شوند ← alert manager دوره‌ای سرویس کوئری را صدا می‌زند و در صورت نقض آستانه رویداد هشدار می‌سازد ← فیلتر/ادغام/حذف تکرار هشدارها + کنترل دسترسی + retry ← وضعیت هشدارها (inactive/pending/firing/resolved) در یک KV store (مثل Cassandra) با تضمین «حداقل یک‌بار اطلاع‌رسانی» ← رویدادها به Kafka ← consumer ها به کانال‌های مختلف ارسال می‌کنند.

ساختن یا خریدن؟

برای هشدار و بصری‌سازی، استدلال «خریدن» (Grafana و ابزارهای موجود) بسیار قوی است؛ ساخت سیستم بصری‌سازی باکیفیت دشوار است و ابزارهای موجود با TSDB های محبوب یکپارچگی خوبی دارند. در مصاحبهٔ سطح ارشد آمادهٔ دفاع از این تصمیم باشید.

نکات کلیدی فصل

  • ماهیت داده (سری زمانی، write-heavy، read-bursty) انتخاب storage را دیکته می‌کند — ابزار تخصصی به‌جای دیتابیس عمومی.
  • بحث pull/push جواب مطلق ندارد؛ دانستن مبادله‌ها مهم‌تر از انتخاب برنده است.
  • صف واسط، تجمیع در لایهٔ درست و downsampling سه اهرم اصلی مهار حجم داده‌اند.
  • alert manager باید تکرارزدایی، ادغام و retry را خودش حل کند تا کانال‌ها اسپم نشوند و هشداری گم نشود.
  • «build vs buy» بخشی از طراحی است، نه پاورقی.

یادداشت‌های مترجم

  • TSDB (پایگاه دادهٔ سری زمانی)، label، retention و downsampling در متن به‌تناسب لاتین/فارسی آمده‌اند.