در ادامهی پستهای قبلی تو این پست داریم میریم ابزار Grafana Mimir رو یکم بررسی کنیم و ببینیم چه کمکی به ما میکنه.
خب یه مروری کنیم پستهای قبلی رو:
- دواپس چیه و چرا لازمه؟ اینجا در مورد دواپس و ضرورت استفاده از آن صحبت کردم.
- مسیر شغلی دواپس اینجا در مورد مسیر شغلی دواپس و موارد پیرامون آن صحبت کردم.
- چطور اپلیکیشن مناسب کلاد آماده کنیم؟ و اینجا توضیح دادم که چطور میتونیم یه اپلیکیشن مناسب کلاد توسعه بدیم.
- چه عمقی از لینوکس برای دواپس لازمه؟ و اینجا توضیح دادم که کدوم موارد لینوکس برای دواپس الزامی هست که اول سراغ اون موارد بریم.
- خودکارش کن، مشکلاتت حل میشه 🙂 در اینجا در مورد اتومیشن و اینکه انسیبل چیه و چه کمکی به ما میکنه صحبت کردم.
- در مسیر دواپس اینبار اجزای اصلی انسیبل تو این پست اجزای انسیبل رو معرفی کردم و آنها را شرح دادم.
- در مسیر دواپس به داکر رسیدم. (قسمت اول) تو این پست داکر رو شروع کردیم و اونو معرفی کردیم.
- در مسیر دواپس اینبار: پشت داکر چه خبره؟ (قسمت دوم) توی این پست در مورد تکنولوژی هایی که داکر ازشون استفاده میکنه توضیح دادیم.
- در مسیر دواپس اینبار: والیوم و نتورک داکر (قسمت سوم) توی این پست در مورد شبکه توی داکر و اینکه چطوری دیتای کانتینر رو میتونیم نگه داریم توضیح دادیم.
- در مسیر دواپس اینبار: داکر فایل ( قسمت چهارم ) توی این پست در مورد اینکه چطور با استفاده از داکر اپلیکیشن مون رو بیلد کنیم و ایمیج بسازیم توضیح دادیم.
- در مسیر دواپس اینبار: کامپوز فایل و داکر کامپوز (قسمت پنجم) توی این پست در مورد اینکه چطور روند دیپلوی کردن سرویسهامون و کانفیگ اونها رو به صورت کد داشته باشیم توضیح دادیم.
- در مسیر دواپس: اینبار داکر سوآرم (قسمت ششم) توی این پست در مورد داکر سوآرم و اینکه چطوری به کمک داکر چنتا سرور رو کلاستر کنیم، توضیح دادیم.
- در مسیر دواپس اینبار: دور و بری های داکر (قسمت هفتم) توی این پست در مورد ابزارهای جانبی که بهمون توی کار با داکر کمک میکنن توضیح دادیم.
- در مسیر دواپس: جمع بندی داکر (قسمت هشتم) توی این پست در مورد امنیت داکر توضیح دادیم و در آخر هم یه سری از بست پرکتیسها و تجربیات خودم رو گفتم.
- تست نوشتن و شروع مسیر CI/CD (قسمت اول) توی این پست انواع تست رو بررسی کردیم و با ابزارهای CI/CD آشنا شدیم و یه مقایسه بین گیتلب و جنکینز داشتیم.
- در مسیر CI/CD گیت رو بررسی میکنیم (قسمت دوم) توی این پست قبل ورود به گیتلب نیاز بود که گیت و ورژن کنترل سیستم ها رو یه بررسی کنیم.
- در مسیر CI/CD شناخت گیتلب (قسمت سوم) توی این پست اجزای گیتلب رو بررسی کردیم و با کامپوننتهای مختلفی که داره بیشتر آشنا شدیم.
- در مسیر CI/CD پایپلاین و رانر گیتلب (قسمت چهارم) توی این پست پایپلاین و رانر گیتلب رو بررسی کردیم.
- در مسیر CI/CD وریبل، گیتآپس و جمعبندی (قسمت پنجم) توی این پست وریبلهای گیتلب رو بررسی کردیم و یه معرفی کوتاه از گیتآپس و آتودواپس کردیم و در انتها یه مقدار تجربههای خودم رو در گیتلب باهاتون به اشتراک گذاشتم.
- مسیر Observability (قسمت اول) توی این پست معرفی observability رو داشتیم و مقایسه اش با مانیتورینگ و یه توضیح مختصر هم در مورد اپنتلهمتری دادیم.
- در مسیر Observability، الک (قسمت دوم) توی این پست استک قدرتمند ELK رو بررسی کردیم.
- در مسیر Observability، جمع بندی استک الک (قسمت سوم) توی این پست بقیه کامپوننتهای استک الک رو بررسی کردیم و fluentd و fluentbit رو مقایسه کردیم و نهایتا یه معرفی هم روی opensearch داشتیم.
- در مسیر Observability، استک پرومتئوس (قسمت چهارم) توی این پست یه معرفی اولیه داشتیم روی استک پرومتئوس.
- در مسیر Observability، استک پرومتئوس (قسمت پنجم) توی این پست یه مقدار کامپوننت های استک پرومتئوس رو بیشتر بررسی کردیم.
- در مسیر Observability، استک ویکتوریا (قسمت ششم) توی این پست استک ویکتوریا رو معرفی کردیم و سعی کردیم با پرومتئوس مقایسهاش کنیم.
توصیه میکنم که حتما این پستها رو هم مطالعه کنید. بریم که ادامه بدیم.
استک Grafana mimir
- چیه و چه کمکی به ما میکنه
همونطور که قبلتر هم اشاره کردیم پرومتئوس برای long term storage دیزاین نشده، یکی دیگه از ابزارهایی که میتونه به عنوان یک استورج long term و high available برای پرومتئوس نقش ایفا کنه، میمیر هست که ابزاری distributed هست و میتونه اسکیل هم بشه. میمیر به ما این امکان رو میده که متریک هامون رو تا یک بیلیون سری اکتیو بالا ببریم در کنارش بهمون HA میده. توسعه میمیر توی Grafana Labs شروع شد و سال ۲۰۲۲ معرفی شد و هدف این پروژه این هست که تبدیل بشه به یک دیتابیس تایمسریز که بیشترین قابلیت اسکیل و پرفورمنس رو داره.
- چرا لازم داریم که از mimir استفاده کنیم
ویژگیهایی مثل سازگاری صددرصد با پرومتئوس، قابلیت ریموت رایت، پشتیبانی از PromQL و آلرتینگ در کنار سازگاری با long-term storage هایی مثل S3 و GCS و Azure blob storage و OpenStack Swift باعث میشه تا به این فکر کنیم که ما هم لازم داریم از میمیر استفاده کنیم؟
یادم میاد وقتی که داشتم اسلایدهای Observability رو برای جلسات توضیح کانسپت دورههام آماده میکردم، اعلام کرده بودن که میمیر در آینده با ابزارهایی مثل Influx و OpenTelemetry و Graphite و Datadog هم کامپتیبل خواهد شد و چند وقت پیش سر کلاس یکی از دورهها به اون اسلاید که رسیدیم بچه ها نگاه کردن و دیدن که بله این اتفاق افتاده 🙂 و با اکثرشون سازگار شده. حقیقتا دمشون گرم اینقدر که خوبن 😀
حالا چه شکلی این اتفاق میافته ؟
به صورت native میمیر از Prometheus metrics استفاده میکنه ولی از اونجا که ویژنشون most scalable Prometheus backend هست و میخوان یه دیتابیس تایمسریز قدرتمند بدون در نظر گرفتن فورمت متریک بشن، باید از بقیه انواع متریک هم پشتیبانی کنند تا یوزرها مجبور نباشن برای استفاده از میمیر کد هاشون رو تغییر بدن.
میمیر سه تا پراکسی رو اپن سورس کرده که با استفاده از اونها میشه متریک های Graphite و Datadog و InfluxDB رو هم توی میمیر ذخیره کرد. این پراکسیها که با لیبل experimental توی پروژه هستن امکان گرفتن متریکها از هر سیستمی رو برای میمیر به وجود میارن.
با اضافه کردن این پراکسیها به عنوان یک additional endpoint به ایجنتها، هر کدوم از متریک های اونها به Prometheus time series ترجمه میشه و میتونه به فرمت پرومتئوس ریموت رایت توی میمیر ذخیره بشه. پراکسیها رو توی گیت هاب میتونید پیدا کنید و به صورت آزمایشی هستن فعلا.
در ادامه چنتا دیگه از ویژگیهای میمیر رو براتون میارم:
- High availability through replication
- Blazing fast queries through a horizontally scalable, sharded query engine
- Unlimited cardinality with the horizontally scalable compacto, tested to 1 billion active series
- Advanced multi-tenancy and isolation
- Horizontally scalable, clustered architecture
- چطور کار میکنه
توی سه مرحله زیر براتون توضیحش میدم:
- Store Prometheus metrics
تو مرحله اول باید دیتا وارد میمیر بشه، با استفاده از پرومتئوس متریکهای اپلیکیشن هارو جمع میکنیم و اونها رو توی میمیر مینویسیم یا اینکه با استفاده از Grafana Agent یا یک ابزاری که Prometheus remote write compatible باشه، دیتا رو مستقیما به میمیر میفرستیم.
- Run it easily, without sacrificing scalability or reliability
میمیر به صورت خودکار کلاستر میشه 🙂 نه نیاز به شارد هست نه رپلیکا نه ری بالانس کردن به صورت دستی. اگه میخواین کپسیتی رو افرایش بدین فقط یه نود جدید به کلاستر اضافه کنید بقیشو میمیر انجام میده 🙂
- Visualize in Grafana
میمیر به یوزر این قابلیت رو میده که کوئری بزنه و دیتای جدید رو از طریق recording rules بسازه و برای آلرت رول بذاره از طریق تننتهای مختلف.
- دیزاین
ساختار میمیر بر پایه میکروسرویسها هست. این سیستم تعدادی میکروسرویس داره که میتونن به صورت horizontal اسکیل بشن و به صورت موازی و جداگانه از هم ران بشن که به هر کدوم از این میکروسرویسها کامپوننت میگه و دیزان به شکلی هست که کد برای همه کامپوننتها کامپایل میشه و یک دونه فایل باینری داریم و پارامتر target – کنترل میکند که اون باینری رفتار کدوم کامپوننت یا میکروسرویس رو نشون بده. در ادامه در مورد mode های مختلف دیپلوی کردن میمیر و کامپوننتهاش بیشتر توضیح میدم.
- دیپلوی
گرافانا میمیر رو میتونیم به یکی از دو روش زیر دیپلوی کنیم و مود دیپلوی رو هم با پارامتر target – مشخص میکنند که یا به عنوان فلگ توی CLI اون رو مینویسم یا توی فایل yaml کانفیگ مینویسیم.
- Monolithic mode
مود دیفالت همین هست و توی این مود تمام کامپوننتهای مورد نیاز میمیر در قالب یک پروسه ران میشن که میشه اون رو به صورت target=all – مشخص کرد. مونولتیک ساده ترین راه دیپلوی میمیر هست و برای استفاده آزمایشی یا محیط توسعه مناسب هست.
با ران کردن چندین باینری میمیر با همین مقدار پارامتر target میتونیم اون رو اسکیل کنیم و بدون پیچیدگی کانفیگ این کار انجام میشه و HA خواهیم داشت.
- Microservices mode
توی این مود کامپوننتهای توی پروسههای مجزا ران میشن و برای اسکیل کردن باید هر کامپوننت را که میخوایم جداگانه اسکیل کنیم، مثلا باینری رو با پارامتر به شکل target=ingester – و target=distributor – و … اجرا میکنیم. دیپلوی با این مود بهمون انعطاف پذیری بیشتری میده و توصیه میشه که از مود میکروسرویس توی پروداکشن استفاده کنید ولی پیچیدگی خودش رو هم داره به نسبت روش قبل.
اگه میخواید میمیر رو توی این مود دیپلوی کنید استفاده از mimir-distributed Helm chart روی کوبرنتیز روشی هست که توصیه میشه.
- Read-write mode (experimental)
این روش که فعلا به صورت آزمایشی هست در واقع سعی میکنه تا جایگزینی باشه برای هر دو روش قبل! توی read-write mode کامپوننتها برای راحت تر کردن سربار عملیاتی در کنار حفط کردن امکان اسکیل و انعطاف، به سه تا گروه تقسیم میشن و این سرویس ها رو بالا میاریم که هر سرویس و کامپوننت هایی که شامل میشه به صورت زیر هست:
- read
- query-frontend
- querier
- backend
- store-gateway
- compactor
- ruler
- alertmanager
- query-scheduler
- overrides-exporter
- write
- distributor
- ingester
مثل روشهای قبل اینجا باینتری رو با پارامتر target=read – و target=write – و target=backend – مقداردهی میکنیم.
دیپلوی به روش read-write mode فعلا فقط با استفاده از روش Jsonnet and Tanka در دسترس هست.
به صورت کلی این مدل دیزاین تو استک های گرافانا جاری هست و این سه مدل دیپلویمنت رو تو tempo و loki هم داریم. کلا یه مدل دیزاین شدند.
- کامپوننت ها
میمیر از کامپوننت های زیر تشکیل شده که با هم کار میکنن. در ادامه یه توضیح مختصر در مورد هرکدوم میدم:
کامپکتور کامپوننتی stateless هست و به بهتر شدن پرفورمنس و کم کردن استفاده از استورج کمک میکنه و وظیفه اش فشرده کردن یا همون کامپکت کردن چندین بلاک هست که توسط یک tenant به یک بلاک بزرگتر داده شده. کامپکتور این کار رو با کم کردن سایز ایندکسها و از بین بردن چانکهای duplicate شده دیتا انجام میده که در نتیجه این کار هزینه استورج کم میشه و کوئری زدن رو تعداد کمتری از بلاک سریعتر هم میشه پس سرعت رو هم بیشتر میکنه.
وظیفه دیگهی کامپکتور اینه که بلاکهایی که دیگه توی هیچ ریتنشن کانفیگ شدهای نیستن رو حذف کنه و باکتهای هر تننت رو آپدیت نگه داره که میتونید در موردش بیشتر بخونید.
دیستریبیوتر کامپوننت stateless بعدی هست که دیتای تایمسریز رو از پرومتئوس یا ایجنت گرافانا دریافت میکنه و صحت و درستی دیتا رو بررسی میکنه و مطمئن میشه که لیمیتهای کانفیگ اون تننت رو رعایت کرده. بعد از معرفی کامپوننتها در مورد اینکه tenant چی هست هم توضیح میدم. در ادامه دیستریبیوتر دیتا رو به batchهای مختلف تقسیم میکنه و اونها رو به چندین ingester به صورت موازی میفرسته و seriesهارو بین ingesterها شارد میکنه اصطلاحا و هر سریز به صورت پیش فرض دارای رپلیکا ۳ هست یعنی دوتا کپی دیگه هم ازش ذخیره میکنه.
اینجستر کامپوننت stateful ی هست که دیتای ورودی رو توی استورج از طریق write path مینویسه و سمپل های کوئریها رو از طریق read path برمیگردونه.
کوئرییر کامپوننت stateless بعدی هست که دستورات PromQL رو بررسی میکنه و دیتای تایم سریز رو میگیره و لیبل میرنه برای read path. این کامپوننت برای کوئری زدن به long-term storage از کامپوننت store-gateway استفاده میکنه و برای کوئری زدن به دیتایی که اخیرا نوشته شده و هنوز منتقل نشده به دیسک از کامپوننت ingster استفاده میکنه.
کوئرییر فرانت کامپوننت stateless بعدی هست که همون API کامپوننت کوئرییر رو ارائه میده و میتونیم ازش استفاده کنیم برای شتاب دادن به read path. استفاده از این کامپوننت برای بالا اومدن کلاستر مورد نیاز نیست اما توصیه میشه که اون رو داشته باشیم تا کوئری هامون بهتر انجام بشن.
دومین کامپوننت stateful هم استور گیتوی هست که از طریق اون میشه به long-term storage کوئری زد و همونطور که بالاتر اشاره کردم querier از این کامپوننت برای گرفتن دیتای استورج استفاده میکنه و علاوه بر اون ruler هم ازش برای هندل کردن کوئری ها استفاده میکنه.
چهارتا کامپوننت اختیاری دیگه هم هست که در ادامه مختصرا توضیحشون میدم:
کامپوننتی هست که multi-tenancy و قابلیت اسکیل رو به Prometheus Alertmanager اضافه میکنه.
این کامپوننت لیمیت هارو به صورت متریک های پرومتئوس اکسپوز میکنه تا اپراتور ها بدونن که هر تننت چقدر به لیمیت هاش نزدیک شده.
کامپوننت اختیاری و stateless هست که صفی از صف ها رو نگه میداره! و لود رو بین querier های در دسترس پخش میکنه.
رولر کامپوننت stateless بعدی هست که عبارت های PromQL رو به شکلی که در رول های آلرت مشخص شده بررسی میکنه و هر تننت یه دسته از این رول هارو داره و میتونه توی namespace های مختلف اونها رو به صورت گروه داشته باشه.
- Multi-tenancy
کلا مفهوم تننت یه جورایی یه مفهوم لاجیکی هست برای ایزوله کردن یا به نوعی پارتیشن کردن ریسورس ها برای گروه های مختلف مثلا توی یک اینستنس گرافانا تننت بهمون کمک میکنه تا دیتا ها و داشبوردها و یوزر های مختلف رو جدا کنیم و بتونیم اونها رو منیج کنیم توی یک گرافانا ی سینگل که دیپلوی کردیم. معمولا از تننت ها توی محیط هایی که تیم های مختلف یا گروه های مختلف دارن از یک ریسورس مشترک رو به اشتراک میذارن استفاده میکنیم که بهشون محیط های multi-tenant میگیم. توی میمیر مثلا هر کامپوننتی که مالتی تننسی داشته باشیم برای از یک tenant ID توی هدر درخواست هاش استفاده میکنه و برای هر تننت میشه کانفیگ ها و لیمیت های مختص به اون رو قرار داد.
کلا موضوع مالتی تننت به ما کمک می کنه چندین تا مشتری و سرویس گیرنده رو روی یه استک داشته باشیم.
شاید به نوعی بشه گفت مثلا هر کدوم از مشتری های میمیر که دارن دیتا رو توی اون میریزن میتونن تننت خودشون رو داشته باشن مثلا هر اینستنس پرومتئوس یا هر ایجنت گرافانا یک تننت برای خودش داره و …
توی پستهای بعدی بیشتر ابزارهای مانیتورینگ و Observability رو بررسی میکنیم و کنار هم یاد میگیرم.
مراقب خودتون باشید. 🌹🐳🌹