Database Engineering

فشرده‌سازی کاردینالیته: بهینه‌سازی جذب سری‌های زمانی با حجم بالا در Prometheus و VictoriaMetrics

قابلیت مشاهده (Observability) ستون فقرات سیستم‌های توزیع‌شده مدرن است، اما هزینه عملکرد قابل توجهی دارد: کاردینالیته. با افزودن برچسب‌ها به متریک‌ها برای امکان‌پذیری پرس‌وجوهای دقیق، اغلب به طور ناخواسته انفجارهای ترکیبی در داده‌های سری زمانی خود ایجاد می‌کنیم. این «انفجار کاردینالیته» می‌تواند منجر به خطاهای حافظه (Out-of-Memory)، گلوگاه‌های ورودی/خروجی دیسک و هزینه‌های زیرساختی سرسام‌آور شود. در این پست، استراتژی‌هایی را برای بهینه‌سازی جذب سری‌های زمانی با کاردینالیته بالا بررسی خواهیم کرد و معماری بومی Prometheus را با کارایی بومی ابری VictoriaMetrics مقایسه می‌کنیم.

درک تله کاردینالیته

کاردینالیته به تعداد سری‌های زمانی منحصر به فردی اشاره دارد که از ترکیب نام متریک‌ها و جفت‌های برچسب ایجاد می‌شود. برای مثال، قرار دادن یک متریک http_requests_total با برچسب user_id خطرناک است. اگر ۱ میلیون کاربر فعال داشته باشید، به طور ناگهانی ۱ میلیون سری زمانی منحصر به فرد ایجاد می‌کنید. Prometheus تمام داده‌ها را به صورت محلی روی دیسک در فرمتی ذخیره می‌کند که برای پرس‌وجوهای محدوده زمانی بهینه شده است، اما نه برای ترکیبات برچسب عظیم. وقتی نرخ جذب افزایش می‌یابد یا تعداد مقادیر برچسب منحصر به فرد بیش از حد بزرگ می‌شود، بخش TSDB (پایگاه داده سری زمانی) در مدیریت بخش‌های WAL (لاگ پیش‌نویس) و فایل‌های نگاشت حافظه (memory-mapped files) با مشکل مواجه می‌شود.

استراتژی ۱: فیلتر کردن پیش‌دستانه برچسب‌ها در Prometheus

خط مقدم دفاع، جلوگیری از ورود برچسب‌های با کاردینالیته بالا به سیستم است. در Prometheus، می‌توانید از metric_relabel_configs در پیکربندی اسکن خود برای حذف متریک‌ها یا برچسب‌هایی که قوانین کاردینالیته شما را نقض می‌کنند، استفاده کنید.

برای مثال، اگر به طور تصادفی یک نقطه پایانی (endpoint) را اسکن کنید که اطلاعات شخصی (PII) مانند شناسه‌های جلسه را قرار می‌دهد، باید آن برچسب را قبل از ذخیره‌سازی حذف کنید. در اینجا نحوه پیکربندی یک قانون حذف در prometheus.yml آورده شده است:

scrape_configs:
  - job_name: 'web_app'
    metrics_path: '/metrics'
    relabel_configs:
      - source_labels: [__name__]
        regex: 'my_app_(.+)'
        action: drop
    metric_relabel_configs:
      # حذف متریک‌هایی با برچسب‌های با کاردینالیته بالا مانند session_id
      - source_labels: [session_id]
        regex: '.+'
        action: drop

این رویکرد تضمین می‌کند که پایگاه داده هرگز حافظه را برای این سری‌ها اختصاص نمی‌دهد. با این حال، این یک رویکرد «از دست‌دهنده» (lossy) است؛ شما توانایی پرس‌وجو در مورد آن سری‌های خاص را کاملاً از دست می‌دهید. اطمینان حاصل کنید که فقط برچسب‌هایی را حذف می‌کنید که برای نیازهای نظارتی شما ضروری نیستند.

استراتژی ۲: بهره‌گیری از VictoriaMetrics برای جذب در مقیاس بالا

در حالی که Prometheus برای نظارت کوتاه‌مدت با وضوح بالا عالی است، برای ذخیره‌سازی بلندمدت داده‌های با کاردینالیته بالا طراحی نشده است. اینجاست که VictoriaMetrics درخشش خود را نشان می‌دهد. این ابزار به طور خاص برای رفع محدودیت‌های Prometheus در مقیاس بزرگ ساخته شده و از موتور ذخیره‌سازی و الگوریتم‌های فشرده‌سازی کارآمدتری استفاده می‌کند.

VictoriaMetrics از «VMAlert» برای هشداردهی پشتیبانی می‌کند و یک پروتکل نوشتن از راه دور (remote write) سازگار با Prometheus ارائه می‌دهد. یکی از مزایای کلیدی آن توانایی مدیریت نرخ‌های جذب بالا بدون نیاز به شاردینگ (Sharding) یا مدیریت پیچیده خوشه برای استقرارهای تک‌نودی است. این ابزار از معماری تک‌نودی استفاده می‌کند که می‌تواند میلیاردها سری زمانی منحصر به فرد را روی یک ماشین واحد مدیریت کند و پیچیدگی عملیاتی را کاهش می‌دهد.

برای مهاجرت، می‌توانید به سادگی نقطه پایانی remote_write را در پیکربندی Prometheus خود تغییر دهید تا به VictoriaMetrics اشاره کند:

global:
  scrape_interval: 15s

remote_write:
  - url: 'http://victoriametrics:8428/api/v1/write'
    queue_config:
      max_samples_per_send: 5000
      capacity: 25000

استراتژی ۳: کاهش نمونه‌ها (Downsampling) و سیاست‌های نگهداری داده

صرف‌نظر از بک‌اند، ذخیره داده‌های خام با سطح میلی‌ثانیه برای ماه‌ها اغلب غیرضروری است. هم Prometheus و هم VictoriaMetrics از کاهش نمونه‌ها پشتیبانی می‌کنند. VictoriaMetrics به ویژه اجازه می‌دهد سیاست‌های کاهش نمونه‌های تهاجمی اعمال شود که در آن داده‌های قدیمی به طور خودکار در رزولوشن‌های ۱ دقیقه‌ای یا ۱ ساعته تجمیع می‌شوند.

این امر به طور قابل توجهی ردپای دیسک را کاهش می‌دهد. با پیکربندی دوره‌های نگهداری که هزینه و نیازهای قابلیت مشاهده را متعادل می‌کنند، می‌توانید داده‌های با وضوح بالا را برای چند هفته (کافی برای عیب‌یابی حوادث اخیر) و داده‌های با وضوح پایین را برای سال‌ها نگه دارید (مفید برای تحلیل روندها).

نتیجه‌گیری

بهینه‌سازی جذب سری‌های زمانی با کاردینالیته بالا تنها درباره مقیاس‌پذیری سخت‌افزار نیست؛ این امر نیازمند نظم معماری است. با بررسی متریک‌های خود برای یافتن برچسب‌های «بد» مانند شناسه‌های کاربر، آدرس‌های IP یا شناسه‌های درخواست پویا شروع کنید. از قوانین تغییر برچسب Prometheus برای حذف این برچسب‌ها در منبع استفاده کنید. برای ذخیره‌سازی بلندمدت و تحلیل تاریخی، داده‌ها را به VictoriaMetrics منتقل کنید که فشرده‌سازی و عملکرد جذب برتری ارائه می‌دهد. با ترکیب بهداشت برچسب‌ها با بک‌اند ذخیره‌سازی مناسب، می‌توانید یک لایه قابلیت مشاهده قوی و مقرون‌به‌صرفه را حفظ کنید که با رشد برنامه شما مقیاس می‌پذیرد.

Share: