ابزار و کتابخانه ها

نگاهی به صنعت مانیتورینگ با معرفی Prometheus

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

درباره برایان برزیل

در این اپیزود که در اکتبر ۲۰۱۶ منتشر شده است جف میرسون با برایان برزیل در مورد ابزار مانیتورینگ Prometheus صحبت می‌کند. برایان، مؤسس Robust Perception است. این شرکت، کمک می‌کند که کاربران ابزار متن‌باز Prometheus افزایش یافته و آن‌ها را پیشتیبانی می‌کند. برایان به شدت، به پروژه Prometheus تعهد دارد. او قبل از شرکت Robust Perception در گوگل کار می‌کرد.

برایان، به SE Radio خوش آمدی.

سلام جف، خوشحالم که اینجا هستم.

بگذار با صحبت در مورد مانیتورینگ آغاز کنیم. مانیتورینگ چیست؟

طی سال گذشته با افراد زیادی صحبت کرده‌ام. افراد مختلف، درباره اینکه مانیتورینگ چیست، برداشت‌های خیلی متفاوتی دارند. برای مثال، وقتی می‌گفتم من کار مانیتورینگ را انجام می‌دهم، برخی افراد بودند که فکر می‌کردند که من به ترافیک شبکه‌شان نگاه می‌کنم تا ببینم آیا در محل کار، سراغ فیسبوک می‌روند یا خیر. روشن است که ما چنین کاری نمی‌کنیم. من مانیتورینگ را در چهار چیز می‌بینم. یکی این است که وقتی مشکلی ایجاد شده یا احتمال مشکلی (یک مشکل کسب و کار) وجود دارد، به شما هشدار دهد. دوم، این است که اطلاعاتی که برای دیباگ آن مشکل نیاز دارید را به شما بدهد. مورد سوم، نمایش روندهای بلندمدت برای اخذ تصمیمات کسب و کار است. مثلاً اگر بدانید که نرخ موفقیت از کَش (Cache Hit Rate) فرضاً ۹۰٪ باشد و اگر تغییر شما بخواهد آن را ۹۵٪ بکند، به این معناست که می‌توانید از دست سخت‌افزارش خلاص شوید و آن را [برای کار دیگری] اضافه کنید. مورد چهارم، لوله‌‌کشی‌های کلی است. برای مثال، اگر هارد دیسک خراب شود، دست آخر، باید فردی را بفرستید که آن را تعمیر کند چون هنوز روبات‌ها برای انجام این کار به قدر کافی خوب نیستند. این‌ها، ۴ چیزی هستند که من در ارتباط با مانیتورینگ در فضای کام‍پیوترها، می‌بینم.

عالی. یک مثال از چیزهایی بزنید که وقتی در گوگل کار می‌کردید، آن را مانیتور می‌کردید.

من قبلاً در بخش Ads در گوگل کار می‌کردم. بنابراین ما چیزهایی از قبیل تعداد پرس‌وجوهای ورودی در ثانیه را مانیتور می‌کردیم. مدت زمان تأخیر (Latency) و همینطور جزییات سیستم‌ها را هم مانیتور می‌کردیم. بنابراین ما خربارها داده آماری داشتیم.

درست است. می‌خواهم بعداً از آن، جهت مثال استفاده کنم. ما امروز در مرود Prometheus صحبت می‌کنیم. و شما ادعا کرده‌اید که Prometheus نسل بعدی سیستم‌های مانیتورینگ است. آیا می‌توانید در این مورد صحبت کنید که مانیتورینگ با Prometheus با ابزارهای نسل‌های قبلی چه تفاوتی دارد؟

اگر به نسل‌های قبل نگاه کنید فرضاً چیزی مانند Nagios را یا چیزهای دیگر منتج از آن را می‌بینیم که چند مورد هستند. Nagios براساس قاعده «بررسی کردن هر ماشین» کار می‌کند. درواقع، یک شِل‌اسکریپت را اجرا می‌کنم که خروجی درست یا غلط برمی‌گرداند و براساس آن یک هشدار به کاربر انسانی می‌فرستم. اگر ۵ ماشین داشته باشید که مراقب‌شان بوده و آن‌ها را نگهداری و تغذیه می‌کنید، این می‌تواند خوب باشد اما در نسل کنونی که افراد در مورد [معماری] بدون سرور (Serverless)، ابر و [کدهای] بومی ابر (Cloud Native) صحبت می‌کنند، ممکن است هزارها ماشین کوچک داشته باشید که دائم آشکار و پنهان می‌شوند. بنابراین، آن هشدارهای در سطح ماشین‌های منفرد آنقدرها مفید نیست.
همچنین ممکن است یک ماشین، کمی کند باشد اما این لزوماً به آن معنی نیست که آن سرویس در کل مشکلی داشته باشد. چون ممکن است همچنان SLA را برآورده کنید. به عنوان یک مثال فنی، فرض کنید که نوعی وب‌سرویس را اجرا می‌کنید. و در مورد میزان تأخیر (Latency) یک SLA دارید که می‌گوید تأخیر باید زیر یک ثانیه باشد. در این حالت خیلی دشوار است که فقط از Nagios استفاده کنید و برای تأخیر بیش از یک ثانیه هشدار داشته باشید. چون فقط می‌توانید به هرکدام از ماشین‌ها نگاه کنید و باید این داده را به نوعی فراهم کنید و نمی‌توانید دید کلی سطح سرویس را ببینید. در نهایت افراد به این می‌رسند که وقتی CPU بالا رفت، هشدار دهند. این می‌تواند حاکی از چنین مشکلی باشد مثلاً ممکن است به خاطر یک بن‌بست (Deadlock) باشد اما موارد زیادی از مثبت‌های اشتباهی (False Positive) هم می‌تواند باشد فرضاً اگر چرخش [فایل‌های] لاگ کمی بیشتر زمان برده باشد.

پرومتئوس

یک سرویس مانیتورینگ متن‌باز برای پایش لحظه‌ای سامانه‌های کلان‌داده و یک دیتابیس سری زمانی.

پرومتئوس

 

کمی در این مورد صحبت کنید که چرا حرکت به سمت معماری ابری، نحوه مانیتورینگ ما را عوض می‌کند.

معماری ابری و همینطور ریزسرویس‌ها ( Microservices ) بر ما اثر دارند. قبلاً چند ماشین لخت (Bare Metal) داشتید و چون بیشتر از چند تا نبودند، می‌توانستید کارتان را به شکل دستی راه بیاندازید. اما وقتی به محیط‌های پویاتر و ابری می‌رویم، دیگر ماشین‌ها مطرح نیستند. آن چیزی که خواهید داشت یک سطح برای پردازش است. چون فرضاً می‌گویید: «به من دو CPU، یک گیگ RAM و کمی دیسک بده» و این‌ها یک جایی قرار می‌گیرد. بنابراین دیگر انقیاد محکمی بین سرویس‌ها یا نمونه پروسس‌هایی که اجرا می‌کنید با ماشین‌های واقعی نیست. چون دیگر از ماشین MySQL صحبت نمی‌کنید بلکه ماشینی وجود خواهد داشت که در حال حاضر، بخشی از سرویس MySQL را اجرا می‌کند.

وقتی در مورد مانیتورینگ صحبت می‌کنیم، آیا این شامل عمل پاسخ دادن به رخدادها هم می‌شود یا تنها مربوط به پردازش رخدادها و تولید متریک‌های مربوط به آن رخدادها است؟

این یکی از چیزهایی است که به آن بستگی دارد که با چه کسی صحبت کنید. من به شخصه می‌گویم که وقتی مانیتورینگ بر روی چیزی مانند PagerDuty نشسته است همانجا کارش تمام می‌شود و شما در حال پاسخ آنی هستید. دیگران می‌گویند که [آن‌ها] هم بخشی از سیستم است. احتمالاً به فلسفه فرهنگ‌تان بر می‌گردد. مثلاً اگر یک NOC داشته باشید و این جزیی از سیستم کنترلی‌تان برای در حال اجرا نگاه داشتن امور باشد، مسلماً این هم بخشی از مانیتورینگ‌تان می‌شود. اگر روش‌‌تان به این شکل باشد که همه چیز مبتنی بر SLA باشد و خیلی از هوشمندی‌‌ها را به سیستم‌های پشت صحنه بسپرید، این هم خودش، یک نوع پاسخ آنی مجزایی می‌طلبد. احتمالاً تنها وابسته به برداشت خودتان است و جواب روشنی ندارد.

در گذشته، شرکت‌های نرم‌افزاری در نهایت ابزارهای مانیتورینگ متنوعی را استفاده می‌کردند. چرا اینطور می‌شد؟

مسأله این است که طی زمان، ابزارهای مختلفی توسعه داده شده‌‌اند که هرکدام یک کار خاص را به خوبی انجام می‌دادند و یا یک یکپارچه‌سازی خاص را به خوبی پشتیبانی می‌کردند. مثلاً اگر بخواهید از ElasticSearch استفاده کنید، زنجیره خودش را دارد و فرضاً اگر از Cassandra استفاده کنید، آن هم پشته ابزار خودش را دارد و هرکدام از این دو تنها با ابزار خودشان یکپارچه می‌شوند و به خوبی کار می‌کنند. بنابراین در طی زمان، همه این ابزارها را بکار خواهید گرفت تا چیزهای مختلفی را رسیدگی کنند. یکی از چیزهای Prometheus که فکر می‌کنم شسته و رفته است این است که ما همه اینجور یکپارچه‌سازی‌ها را داریم و از این جهت خیلی خوب است. اما برای همه سیستم‌های مانیتورینگی که الان وجود دارد، چه تجاری‌ها و چه متن‌بازها، باید این‌ها را پیاده‌سازی کنید. و این آزاردهنده است که به جای اینکه بر روی مسائل جالب‌تر تمرکز کنیم، همه وقت‌مان را برای پیاده‌سازی مجدد این یکپارچه‌سازی‌ها صرف می‌کنیم. بنابراین یکی از چیزهایی که در Prometheus هست، صادرکننده‌های ( Exporter ) از دیگران است. ما همچنین API‌ها و واسط‌هایی (Interface) فراهم می‌کنیم که می‌توانید برای سیستم‌های مانیتورینگ دیگر از آن استفاده کنید. بنابراین مجبور نیستید که چیزهای زیادی را تکرار کنید.

وقتی یک شرکت نرم‌افزاری می‌خواهد چند ابزار مانیتورینگ را اجرا کند، سوء اثر اصلی که حاصل می‌شود همین «کار تکراری» است که می‌گویید؟

بله، یکی از آن‌ها، تکرار کردن است. و هر کدام از آن ابزارها، فلسفه متفاوت، مدل داده کمی متفاوت، ادبیات مختلف و سطوح متفاوتی از قدرت دارند. و شما برای هر سیستمی که باشد، چه یک سیستم Build باشد، یا یک زبان باشد یا حتی یک ویرایشگر متن باشد، برای هرکدام از این اضافات که در اکوسیستم‌تان داشته باشید، سربار شناختی بیشتری برای همه اعضاء تیم‌تان خواهید داشت. بنابراین تنها مربوط به مانیتورینگ نیست، مربوط به این است که یک چیز بیشتر خواهید داشت که همه باید یاد بگیرند و باید مسائل بغرنج مربوط به انواع حالت‌های خاص‌ آن را فرا بگیرند و از این‌جور چیزها. بنابراین اگر بتوانید آن‌ها را یک‌کاسه کنید طوریکه اندازه سیستمی که افراد باید یاد بگیرند کوچک‌تر شود، این برای همه بهتر است.

از آنجاییکه ما به بحث در مورد Prometheus می‌پردازیم، [باید اشاره کرد که] Prometheus مبتنی بر یک ابزار مانیتورینگ ساخته شده داخل گوگل است که Borgman نام دارد. چه چیز منحصر بفردی در مورد Borgman وجود دارد؟

من در مورد تاریخچه Borgman اطلاع خیلی زیادی ندارم، فقط خیلی از آن استفاده کرده‌ام. وقتی به Prometheus می‌نگرید، می‌بینید مقصود آن، محیط‌های پویا بوده است. و برچسب‌ها (Label) هایی دارد که بسته به اینکه به چه سیستمی نگاه کنیم، تگ (Tag) یا بُعد (Dimension) خوانده می‌شوند و یک زبان پرس‌وجوی قدرتمند دارد. می‌تواند مقدار زیادی داده را خورده، آن را پردازش کرده و داده‌ها و اطلاعات واقعاً با کیفیتی از آن تولید کند. فکر می‌کنم این واقعاً منحصر بفرد است که برچسب‌ها را دارید و زبان پرس‌وجو را دارید.

Borgman سیستم مانیتورینگی است که Borg را در گوگل مانیتور می‌کند. Prometheus چیست؟ چرا Prometheus تولید شد؟

Prometheus در SoundCloud با کار جولیوس و مَت آغاز شد. تا آنجایی که من می‌دانم به این خاطر بود که آن‌ها StatsD داشتند اما قابلیت افزایش مقیاس خوبی برایشان نداشت. بنابراین شروع کردند که یک سیستم بهتر توسعه دهند. اینجا بود که Prometheus آغاز شد. من یک سال و نیم بعد، درگیر شدم و الان ۳ سال و نیم می‌شود که [در این پروژه] هستیم. به نوعی یک واکنشی به این بود که سیستم‌های مانیتورینگ موجود به مقدار کافی خوب نبودند.

بسیار خوب. Prometheus دید ما به سلامتی داخلی سرویس‌های‌مان را بهبود می‌بخشد. Prometheus در مقایسه با دیگر سیستم‌های مانیتورینگ چه کاری انجام می‌دهد؟

آیا ابزار خاصی را در ذهن دارید؟ چون ۳ یا ۴ دسته چشمگیر وجود دارد.

نه. چیز خاصی در ذهن ندارم. برجسته‌ترین تضادی که شما در ذهن دارید چیست؟

یک مورد [تضاد] بزرگ که می‌بینید بین لاگ با متریک است. دیگری بین لاگ و متریک با پروفایل است و بعد [تفاوتش با اینکه] همه آن‌ها بصورت جعبه‌سیاه باشد. بنابراین من با صحبت در مورد لاگ آغاز می‌کنم. مثلاً ممکن است با پشته ELK یا FluentD یا یکی از این روش‌ها کار می‌کنید. لاگ‌ها و متریک‌ها به داده‌های یکسانی اما با روش‌های مختلفی می‌نگرند. مثلاً در یک خط لاگی که متناظر با هر درخواست کاربر تولید می‌کنید، فیلدهای خیلی زیادی می‌تواند قرار بگیرد اما عملاً با توجه به پهنای باند و دیسک، فرضاً به ۵۰ یا ۱۰۰ فیلد محدود می‌شوید. مثلاً نمی‌توانید ۱۰۰۰ مورد داشته باشید چون فضای خیلی زیادی از دیسک یا پهنای باند خیلی زیادی از شبکه می‌گیرد. در مقابل، متریک‌ها درباره هر درخواست مجزایی اطلاع ندارند چون از لحاظ زمانی فشرده شده‌اند. یعنی هر ۱۰ ثانیه یا ۲۰ ثانیه یا یک دقیقه یکبار، یک تصویر گرفته می‌شود. بنابراین از آنجایی که در هر درخواست منفردی، گرفته نمی‌شوند و در بعد زمان، تجمیع می‌شوند، می‌توانید ۱۰۰۰۰ تا از آن‌ها را داشته باشید و مشکلی ایجاد نمی‌کند. اما آن ریز اطلاعات مربوط به هر درخواست را از دست می‌دهید. اینجا است که این تضاد بزرگ وجود دارد. من آن را اینطور می‌بینم که با یک سیستم متریک مانند Prometheus آغاز می‌کنید و بعد به عمق می‌روید تا بفهمید کدام زیرسیستم، به خطا خورده است. فرضاً تأخیر را در داخل معماری ریزسرویس‌هایتان ( Microservices ) پیگیری می‌کنید تا ببینید کدام سرویس بوده و به دیگر متریک‌ها نگاه می‌کنید چرا که ۱۰۰۰۰ تا از آن‌ها را دریافت می‌کنید و بعد می‌فهمید که به نظر می‌رسد از زیرسیستم صدور صورتحساب باشد. و حال که می‌دانم از آن زیرسیستم است و می‌دانم کدام مسیرهای درخواست، به آن می‌رود، به سراغ لاگ‌ها می‌روم و می‌بینم که کدام کاربران بوده‌اند که پرس‌وجوهای کندی داشته‌اند و متوجه می‌شوم که فلان کاربر بوده و درخواست از آن می‌رفته است. بنابراین، این تعاملات وجود دارد که متریک‌ها محدوده چیزی که دارد رخ می‌دهد را مشخص می‌کنند و بعد می‌توانید به سراغ لاگ بروید تا حال که می‌دانید از کدام زیرسیستم بوده اطلاعات بیشتری بگیرید و ببینید کدام درخواست، مشکل را ایجاد کرده است. در اینجاست که من این تعاملات را می‌بینم. دیگری، پروفایل است. این می‌تواند هر چیزی مثلاً GDB یا strace باشد و یا هر ابزار پروفایل واقعی هم می‌تواند باشد. آن هم مشابه با لاگ‌ها و متریک‌ها است با این تفاوت که هر دو این کار‌ها را برای یک پریود زمانی کوچک انجام می‌دهد چون در غیر اینصورت خیلی سنگین می‌شود. زیرا اگر در هر مایکروثانیه یا هر ۱۰۰ مایکروثانیه یک نمونه بگیرید و تمامی رخدادها را واکشی کنید، اطلاعات فوق‌العاده زیادی جمع می‌شود و نمی‌توانید همواره آن را روشن نگه دارید چون خیلی سنگین است. با این حال وقتی، محدوده مشکل را باریک کرده‌اید، می‌توانید آن را از ابزار پروفایل، بیرون بکشید و مشکل را دیباگ کنید و وقتی آن را فهمیدید، خاموشش کنید چون نمی‌توانید آن را همواره روشن نگه دارید.

یکی از چیزهایی که فهرست کردید این است که می‌خواهید به جای ماشین‌ها، سرویس‌ها را مانیتور کنید. منظورتان از این جمله چیست؟

همانطور که در مثالی که قبلاً داشتیم اشاره کردم، اگر ماشینی داشته باشم که MySQL را اجرا می‌کند، آنگاه در مدل قدیمی که ماشین‌ها مانیتور می‌شدند یک چک برای این می‌داشتم که [ماشین] MySQL روشن شده باشد و چک‌هایی هم داشتم که CPU و حافظه، خوب باشند. اما اگر آن [نمونه MySQL]، جزیی از یک مجموعه از چندین رونوشت‌ تکراری (Redundant Replica) بود، دیگر هرکدام از ماشین‌های مجزای MySQL برایم مهم نیست. تنها برایم مهم است که به تعداد کافی MySQL در حال اجرا باشد که سرویس خوبی فراهم کند. فرض کنید MySQL به شکل خیلی ساده‌ای استفاده شده است. در اینصورت ممکن است تنها نگاه کنم که آیا مقدار مصرف CPU مناسب است؟ و آیا میزان تأخیر در کل ناوگان خوب است؟ حال اگر دو تا از ماشین‌ها پایین آمده باشند اما تمامی متریک‌های دیگر خوب باشد و همه با قابلیت اطمینان خوب، سرویس خوبی بگیرند، در اینصورت دلیلی برای هشدار دادن نیست. بنابراین، در مورد هرکدام از ماشین‌های مجزا فکر نمی‌شود بلکه در مورد سرویسی که روی هم رفته، کاربر در دید سراسری آن می‌گیرد، فکر می‌شود. این همان دید حیوان خانگی در مقابل گله گاوها (Pets vs. Cattle) است.

بسیار خوب. بگذار در مورد Prometheus در عمل صحبت کنیم. کلاینت Prometheus چیست؟

یک تعداد کتابخانه‌ کلاینت Prometheus وجود دارد. فکر کنم برای ۱۱ زبان باشد. فکر می‌کنم برای اینکه بیشترین بهره را از یک سیستم متریک ببریم (دقیقاً مانند سیستم لاگ) نیاز دارید که آن را در کد بیاورید. ما برای این منظور، کتابخانه‌های کلاینت را فراهم کرده‌ایم. GO و Python و جاوا و Ruby اصلی‌ها هستند. به این شکل است که به داخل کد می‌روید و یک خط کد می‌گذارید تا فلان چیز یک عدد اضافه شود یا اینکه هرزمانی که به یک تابع می‌روید حساب می‌کنید که چقدر طول کشیده و ردش را می‌گیرید. آنگاه همه این‌ها در حافظه نگه داشته می‌شود و هر از گاهی Prometheus می‌آید و یک تصویر از آن را برمی‌دارد. بنابراین در بطنش به این شکل است که شما می‌گویید: «این‌ها اطلاعاتی هستند که می‌خواهم عرضه کنم» و آنگاه ما همه امور مربوط به ثبت و ضبط، همروندی و کارایی آن را برای‌تان انجام می‌دهیم.

اگر بر فرض، مثال بستر تبلیغاتی (Adds Platform) که بر روی آن کار کرده‌اید را در نظر بگیریم، کلاینت Prometheus نیاز است که چه‌جور فراخوانی‌هایی را پیاده‌سازی کند؟ چه متدهایی را باید پیاده‌سازی کند؟ نیاز است که بتواند به چه چیزهایی پاسخ دهد و چه‌جور اطلاعاتی را نیاز است که تولید کند؟

خود کلاینت، خیلی کلی است. ما ۴ نوع [متریک] داریم: Counter ،Gauge ،Summary و Histogram. که در آن، Gauge می‌تواند مربوط به درخواست‌های درحال پیشرفت باشد چون مانند Gauge ای که در ماشین دارید بالا و پایین می‌رود. اگر خیلی بالا برود، مشکلی دارید. این مثلاً می‌تواند بزرگی یک صف در مقایسه با ظرفیت آن باشد. مورد دیگر Counter است که مثلاً تعداد درخواست‌هایی که وارد شده را می‌شمارد یا تعداد درخواست‌هایی که برای یک فرمت خاص از تبلیغات داشته‌اید (فرضاً فرمت flash در مقایسه با متن) را می‌شمارد و Summary و Histogram ‌می‌تواند برای مدت زمان تأخیر باشد و یا برای تعداد بایت‌ها در هر درخواست باشد تا آن را در زمان ردیابی کنید و ببینید چه توزیعی دارد. این شکل از نگاشت‌هایی که در ارتباط با هرکدام از انواع برای فراهم‌کننده‌هایش دارید، در سطح کتابخانه است. اما در انتها، برعهده کاربر است که بر روی آن چیزهایش را بسازد چون کتابخانه، چیزی در مورد [منطق کسب و کارتان یعنی] فرضاً تبلیغات نمی‌داند.

چه فرآيندی برای برپا کردن چنین کلاینتی وجود دارد؟ چه‌جور قلاب‌های برنامه‌نویسی باید نوشته شود تا این متریک‌هایی که می‌خواهید را بیرون دهید؟

مثلاً برای Python کاری که انجام می‌دهید این است که با pip کلاینت Python را نصب می‌کنید یعنی می‌نویسید: pip install prometheus_client و بعد آن را مانند چیزهای دیگری که در python دارید import می‌کنید. بعد متریک‌های‌تان را می‌سازید. مثلاً یک متریک با نام MY_METRIC از نوع Summary می‌سازید و به آن یک نام و یک رشته [توضیحی] کمکی می‌دهید. حال اگر فرض کنیم که می‌خواهید مدت زمان یک تابع را با آن اندازه بگیرید تنها کافیست که آن تابع را با رشته @MY_METRIC.time() نشان بگذارید و کار تمام است. بنابراین فقط دو خط کد است. یکی برای برپا کردن متریک و دیگری برای استفاده از آن.

بسیار خوب. و آنگاه سرور Prometheus چیست؟

سرور Prometheus بخش هسته آن است. آن چیزی است که می‌رود و با کلاینت‌ها و صادرکننده‌ها ( Exporter ) صحبت می‌کند و همه داده‌ها را واکشی می‌کند و بر روی حافظه محلی ذخیره می‌کند (من ترجیح می‌دهم SSD باشد) و قواعدی در زمینه هشدارها، بر روی آن‌ها اجرا کرده و آن هشدارها را می‌فرستد. همینطور برای درخواست‌های امور گرافیکی آماده است و داده‌ها را بر روی HTTP بیرون می‌فرستد که روش کاری است که تقریباً تمامی راه‌حل‌های مبتنی بر داشبورد دارند.

آیا برای هرکدام از سرویس‌های مختلفی که می‌خواهید مانیتور کنید به یک سرور Prometheus نیاز دارید؟

می‌توانید یک سرور Prometheus داشته باشید. مشکلی در این زمینه نیست. در‌واقع به شکل غافلگیرکننده‌ای کارا است. تنها یک نمونه از آن می‌تواند ۸۰۰۰۰ نمونه بر ثانیه را بردارد. اما آنچه معمولاً رخ می‌دهد این است که به دلایل سازمانی، هر تیمی Prometheus خود را دارد. اما مشکلی نیست که همگی را داخل یکی بگذارید.

این دلایل سازمانی برای اینکه برای هر تیم یک Prometheus سرور داشته باشیم چیست؟

مثلاً اگر دو تیم جدل داشته باشند که به چه روشی کار کنند و عقاید متفاوتی داشته باشند. یا منابع مختلفی باشد که بحث باشد که چه کسی باید کدام را مدیریت کند. در اینصورت ممکن است هرکدام سرور Prometheus خود را داشته باشند. جنبه انزواسازی (Isolation) هم اینجا مطرح است. اگر این اتفاق افتاد که یک تیم، متریکی را قرار داد که خیلی بزرگ بود و مشکل ایجاد کرد، این می‌تواند بر روی همه افراد دیگری که بر روی آن سرور Prometheus هستند اثر بگذارد. بنابراین یک روش نگاه به آن می‌تواند این باشد که بتوانیم بگوییم که: «هرکدام از شما، سرور خود را دارید.» البته اجرا کردنPrometheus خیلی ساده است و یک دیمون (Daemon) استاندارد لینوکس است.

شماره اشاره کردید که کلاینت‌های متفاوت Prometheus ممکن است متریک‌هایشان را به روش‌های مختلفی پیاده‌سازی کنند. آیا برای برپا کردن سرور Prometheus تصمیمات شخصی هم مطرح است؟

بله، تصمیمات شخصی زیادی وجود دارد. مورد اصلی آن در ارتباط با اکتشاف سرویس (Service Discovery) و آنچه ما آن را برچسب‌دهی مجدد (Relabling) می‌‌گوییم، بوجود می‌آید. فرضاً به این نگاه کنید که دو سازمان مختلف چطور در مورد ماشین‌های خود فکر می‌کنند. مثلاً ممکن است ماشین‌های یکی در [ابر] آمازون و دیگری، سیستم‌های لخت باشد. آنکه در آمازون است به نواحی دسترس‌پذیری (Availability Region) اهمیت می‌دهد اما آنکه سیستم‌های لخت دارد، فقط به مراکز داده (Data Center) اهمیت می‌دهد. بنابراین این دو، مدل‌های خیلی متفاوتی از دنیا دارند. پس روشی که در مورد مقصدهای خود فکر می‌کنند و کلید/مقدارهایی که به آن‌ها نسبت می‌دهند، متفاوت خواهد بود. مطلب جالب این است که روشن شده نه تنها بین شرکت‌ها، تفاوت فراوانی وجود دارد -تا جاییکه هیچکدام از ابزارها، مدل ذهنی یکسانی ندارند- بلکه بین تیم‌های یک شرکت و حتی داخل یک تیم هم تفاوت‌ها رایج است به این خاطر که افراد مختلف در مورد محیط عملیات، محیط توسعه، انتشار قناری ( Canary Release) و … ایده‌های متفاوتی دارند. شاید برخی امور را توسط مشتری‌ها، ترتیب دهند و برخی توسط تیم این کار را بکنند. اینجاست که شخصی بودن‌ها پیش می‌آید که چطور کارها را ترتیب می‌دهید. یکی از مزایای Prometheus این است که هرکسی که یک سرور Prometheus راه می‌اندزد، می‌تواند کار خود را بکند و دنیا را همانطوری مدل کند که برایش معنی‌ می‌دهد.

سرور Prometheus چطور کلاینتی که می‌خواهد به آن وصل شود را کشف می‌کند؟

برای اکتشاف سرویس، چندین گزینه وجود دارد. ما EC2 و Azure را پشتیبانی می‌کنیم. بخش مربوط به Google Compute Engine فکر می‌کنم همچنان در حال بازبینی کد باشد. بنابراین می‌توانیم ماشین‌ها را بوسیله این‌ها، اکتشاف کنیم. همینطور Marathon و Kubernetes را هم داریم که می‌توانیم داده‌ها به همراه هر متادیتایی که بتوانند به ما بدهند را از آن‌ها واکشی کنیم. چیزهای دیگری هم مانند Nerve و مجموعه سرورهایی که بر روی ZooKeeper تعریف می‌شود هم هست. همچنین Cunsol است که افراد از آن استفاده می‌کنند. این‌ها، عمومی‌تر هستند و به شکل خاص برای اکتشاف سرویس طراحی شده‌اند. همه این‌ها وجود دارد. ما می‌توانیم برویم و از این‌ها واکشی کنیم و کاربر می‌تواند در هرجایی که بخواهد، با استفاده از برچسب‌دهی مجدد (Relabling) داده‌هایش را مدل کند.

وقتی فرآیندهای مربوط به اکتشاف سرویس انجام شد، الگوی تعاملی بین سرور Prometheus و کلاینت آن چیست؟

سرور Prometheus یک درخواست HTTP می‌فرستد (ممکن است HTTPS باشد) که می‌گوید: «یک خراش از داده‌هایت برایم بفرست» عموماً این را به آدرس /metrics می‌فرستد و کلاینت Prometheus متریک‌ها را بازمی‌فرستد. آنگاه اتصال HTTP خود را باز نگه می‌دارند و به ارسال درخواست‌های HTTP عادی خود در فواصل منظم ادامه می‌دهند.

فواصل مرسوم چقدر است؟

بستگی دارد. پیش‌فرض آن، ۱۵ ثانیه است. افراد مختلف از کسری از ثانیه تا چند دقیقه آن را تنظیم می‌کنند.

در مورد اینکه می‌خواهید قبل از ping کردن کلاینت Prometheus چقدر صبر کنید، تصمیم‌گیری به چه ترتیبی است؟

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

وقتی سرور Prometheus برپا شد، کلاینت را راه می‌اندازید اما معمولاً کلاینت یک نمونه از یک سرویس چندنمونه‌ای است. بنابراین بگذار از این رفع ابهام کنیم که تعامل بین سرور و همه این نمونه‌های یک کلاینت چگونه است. این به چه روش کار می‌کند؟ آیا اینطور است که کلاینت‌های مختلف به شکل نوبتی، ping می‌شوند یا همه آن‌ها همزمان ping می‌شوند؟ چطور کار می‌کند؟

کاملاً از هم مستقل‌اند. اکتشاف سرویس، گلدان تمامی مقصدها را تولید می‌کند. فرضاً اگر فواصل زمانی‌مان ۱۰ ثانیه‌ای باشد، هویت این مقصدها، درهم‌سازی (Hash) می‌شود و بنابراین، بار روی آن‌ها پخش می‌شود و بعد براین اساس، نمونه‌گیری می‌کنیم. بنابراین مثلاً اگر دو تا باشند، یکی می‌تواند بر روی ثانیه اول و دیگری بر روی ثانیه هفتم بیافتد و بعد با همین آفست، تکرار می‌شوند. و اگر تعداد میزبان‌های خیلی زیادی داشته باشید، تعداد بیشتری از این واکشی‌ها در آن ۱۰ ثانیه خواهیم داشت. اما هرکدام از آن‌ها یک goroutine است و از هم مستقلند و تنها برای سازگاری، درهم‌سازی شده‌اند.

داده‌های مربوط به نمونه‌های مختلف چطور با هم تجمیع می‌شوند؟

بصورت پیش‌فرض، Prometheus تنها داده‌ها را می‌گیرد. اساساً دو روش برای تجمیع وجود دارد. یکی این است که وقتی فرضاً برای نمایش گرافیکی، درخواستی از Grafana می‌فرستید، آن‌جا نوعی تجمیع مثلاً جمع زدن خواهید داشت که محاسبات را درجا انجام می‌دهد. اما اگر چندین سری‌ زمانی داشته باشید این ساختار می‌تواند کمی پرهزینه شود. گزینه دیگر این است که Prometheus می‌تواند قواعدی را اجرا کند. ما به آن‌ها، قواعد ضبط (Recording Rules) می‌گوییم. سیستم‌های دیگر به آن قواعد برجا (Standing Rules) یا پرس‌وجوهای برجا هم می‌گویند. این‌ها می‌توانند به شکل منظم، محاسبه شده و [دسته‌ای از سری‌های زمانی] را پیش‌تجمیع کند. این دسترسی ارزان‌تری است چون می‌توانید به جای هزارها سری زمانی، با یکی در تماس باشید.

آیا کلاینت‌ها داده‌ها را به سرور می‌فرستند؟ به نظر می‌رسد که یک سرور مرکزی داده‌ها را از کلاینت‌ها واکشی می‌کند.

بله، Prometheus یک سیستم مبتنی بر واکشی (Pull-based) است. مثلاً هر ۱۰ ثانیه واکشی می‌کند.

چرا چنین مناظره‌ای در ارتباط با مانیتورینگ مبتنی بر بیرون‌دهی (Push-based) در مقابل مانیتورینگ مبتنی بر واکشی (Pull-based) وجود دارد؟

مطمئن نیستم اما حدس‌هایی دارم که چرا اینگونه است. همانند بحث در مورد Vim یا Emacs تا مقداری یک بحث عقیده‌ای است. به اعتقاد من، از نظر فنی، تفاوت خیلیی زیادی بین این دو نیست. فکر می‌کنم واکشی یک کمی بهتر است اما فقط یک کمی. یکی از چیزهایی که فکر می‌کنم ممکن است بر رویش اثر بگذارد این است که Nagios یک سیستم واکشی است که مقیاس دادن آن، دشوار است و از این نظر، افراد فکر می‌کنند که چون Nagios مبتنی بر واکشی است و مقیاس‌پذیر نیست پس کلاً واکشی، مقیاس‌پذیر نیست که نوعی سفسطه ابتدایی است. در واقعیت، هم بیرون‌دهی و هم واکشی، هر دو به خوبی مقیاس می‌پذیرند. این یکی از بحث‌ها است که ممکن است مطرح شود. دیگری این است که به دلایل شبکه‌ای، استفاده از بیرون‌دهی، در بسیاری از شرکت‌های SaaS متداول است بنابراین افراد به این علت در آن قرار گرفته‌اند. اما از بیشتر این اعتقادات شدیدی که وجود دارد که بیرون‌دهی یا واکشی نمی‌تواند مقیاس بپذیرد واقعاً سر در نمی‌آورم چون اگر زمان صرف کنید می‌توان هر دو را مقیاس داد.

می‌توانید کمی در این مورد صحبت کنید که تفاوت مقیاس‌پذیری یک سیستم مبتنی بر بیرون‌دهی با سیستم مبتنی بر واکشی در چیست؟

قطعاً. در یک سیستم مبتنی بر بیرون‌دهی، جریانی از نمونه‌ها دارید که معمولاً به یک نوع ترازگر بار ( Load Balancer ) می‌روند. بعد به چیزی نیاز دارید که این نمونه‌ها را برداشته و آن‌ها را چندپاره کند یعنی برای پخش کردن بین چندین سرور، درهم‌سازی کند و در آنجا [سرورهای مقصد] آن‌ها را پردازش کند. بنابراین در این حالت، ترازگر بار جایی است که کارها می‌تواند چالش بیشتری پیدا کند چون ممکن است حجم عظیمی از داده را در یک جا داشته باشید. در یک سیستم مبتنی بر واکشی به ترازگر بار نیاز ندارید چون پاره مربوط به هرکدام از سرورهای Prometheus از قبل تعیین شده‌ است. مثلاً ممکن است یک نمونه برای MySQL داشته باشید که داده‌های آن را واکشی می‌کند. بنابراین نیاز به یک عمارت بزرگ برای مدیریت کردن همه داده‌ها ندارید.

اگر بخواهیم بیشتر در مورد Prometheus صحبت کنیم، وقتی داده را با سرور Prometheus از کلاینت Prometheus می‌گیریم، این داده به چه شکلی است؟ قالب داده چیست؟

دو قالب داده وجود دارد. یکی که بیشتر کاربرها می‌بینند و تمامی کلاینت‌ها تولید می‌کنند، به شکل متنی است. به این ترتیب که چند مورد متادیتای توضیحات [آورده می‌شود] و بعد مثلاً گفته می‌شود که mymetric 3 یا mymetric 1.5. همینطور ممکن است برچسب‌هایی هم در داخل آکولاد آورده شود. قالب دیگر که معادل همان است Protobuf است. در حال حاضر، فقط کلاینت GO آن را تولید می‌کند و در‌واقع سرور Prometheus و کلاینت آن برای اینکه بفهمند از کدام قالب استفاده کنند یک مذاکره‌ دارند. اما قالبی که اکثر افراد به آن می‌رسند همان قالب ساده متنی است و با فرض اینکه به Escaping نیاز نداشته باشید خیلی ساده می‌توانید آن را تولید کنید.

حجم داده مانیتورینگ کاملاً چشمگیر است. داده‌ها کجا ذخیره می‌شوند؟ آیا مستقیماً بر روی سرور Prometheus ذخیره می‌شوند؟ یا سرور آن را به پایگاه داده دیگری می‌فرستد؟

داده‌ها در نهایت بر روی سرور Prometheus ذخیره می‌شوند. ما به دلایل کارایی، SSD را توصیه می‌کنیم. در‌واقع با روش کدگذاری جدید، برای موارد کاربرد عملیاتی بازاء هر نمونه ۱.۳ بایت مصرف می‌شود و همانجا می‌نشیند. اما ما دیده‌ایم که Prometheus خودش برای ذخیره‌گاه داده‌ها در بلندمدت درنظر گرفته نمی‌شود. چون برای یک ذخیره‌گاه داده بلندمدت، یک سیستم ذخیره‌سازی توزیع‌شده لازم می‌شود. و این یعنی که باید یک سیستم توزیع‌شده داشته باشیم و درست انجام دادن آن خیلی خیلی سخت می‌شود. من فکر نمی‌کنم که بخواهید مشکلات این سیستم‌های توزیع‌شده بعدی را داشته باشید چون اگر با سرور Prometheus به شدت همبسته شده باشد، ممکن است وقتی به هنگام ضرورت می‌خواهد به کمک‌تان بیاید، کاملاً قفل شود. بنابراین ما نوعی از ذخیره‌گاه بلندمدت را داریم که Prometheus داده‌ها را به آن بیرون می‌فرستد. در حال حاضر، می‌تواند به Influx و Graphite و OpenTSDB بفرستد البته هنوز در مرحله پشتیبانی تجربی قرار دارد. در نهایت، می‌خواهیم بتوانیم افزونه‌های برای سیستم‌های دیگر را هم داشته باشیم تا داده‌ها را به شکل بلندمدت ذخیره کنند. Prometheus همچنین می‌توانند به شکل نامحسوس، داده‌ها را از آن‌ها باز بگیرد. پس ما ناهمبستگی (Decoupling) داریم از این نظر که Prometheus شاید چندین هفته یا چندین ماه داده را در خود دارد بنابراین حتی اگر ذخیره بلندمدت مشکلی داشته باشد، می‌توانید در هنگام ضرورت، مانیتورینگ‌های حساس را داشته باشید.

آیا اینطور است که داده‌های روی سرور Prometheus رونوشت‌برداری نشده‌اند و از نظر از دست رفتن، آسیب‌پذیر هستند؟

بله، درست است. ما کلاً داده‌های Prometheus را بی‌دوام (Ephemeral) می‌دانیم و بیش از هر چیز دیگری، یک نهان‌گاه (Cache) است. اما از نظر قابلیت اطمینان، اگر دسترس‌پذیری بالا (High Availability) را بخواهید و نخواهید به تنها یک ماشین بسنده کنید با مدل واکشی که Prometheus دارد این کار خیلی ساده است. کافی است که یک سرور ثانویه دیگر روشن کنید که معادل اولی عمل می‌کند. پس هر دو داده‌ها را دارند و هر دو هشدار می‌دهند.

درسته. این مدل رونوشت‌برداری از نظر تفاوتی که بالقوه بین این دو [رونوشت] هست، آسیب‌پذیر است اما خوب این مانیتورینگ است و آنقدر برایتان مهم نیست اگر در یک نمونه متریک، مقدار اندکی تفاوت وجود داشته باشد.

بله. مسأله این است که در مانیتورینگ، شرایط رقابتی (Race Condition) خیلی زیادی وجود دارد که چنین چیزی اهمیت ندارد. شما حتی در سیستم‌های مبتنی بر بیرون‌دهی (Push-based) هم دقیقاً همین را دارید. اگر شبکه کمی کند یا تند شود یا زمانبند کرنل، اندکی خاموش شود، نتایجِ اندکی متفاوت خواهید گرفت. بیشتر رقابت‌ها چنین مرتبه‌ای دارند و از این نظر چیز یکسانی را خواهید دید. همینطور اگر فکرش را بکنید، در آن مثال فواصل ۱۰ ثانیه واکشی، نمی‌دانید که آن ۱۰ ثانیه‌ها کجا قرار می‌گیرند. اگر پاسخ‌های متفاوتی بگیرید و اینکه در کجای آن ۱۰ ثانیه قرار می‌گیرید از نظر هشدارها، خیلی تأثیرگذار باشد، آنگاه مانیتورینگ شما خیلی خوب یا مستحکم و مقاوم نیست. بنابراین بهرحال باید از این نظر مقاوم باشید چون این ذات مانیتورینگ است.

یک چیزی که می‌شنوم این است که داده‌های مانیتورینگ نیاز نیست به میزان داده‌های کسب و کار، مانا (Durable) باشد. این به نظر در نحوه نگاه به داده‌های کسب و کار در مقابل داده‌های مانیتورینگ یک تفاوت اساسی هست. آیا از نظرهای دیگری هم هست که ملزومات، روی معماری Prometheus تأثیر بگذارد؟

به آن میزان مصالحه‌های مهندسی، مانایی وجود ندارد چون Prometheus دسترس‌پذیری (Availability) را نسبت به سازگاری (Consistency) اولویت می‌دهد. چون در نهایت، اگر شبکه‌تان خراب شود، چیزی مانند ZooKeeper نمی‌خواهید که آن‌هم پیرو آن خراب شود. قابلیت اطمینان در دیگر جاها، مثلاً بین Prometheus و سیستم مدیریت هشدارها [هم مطرح است]. سیستم مدیریت هشدارها، همه هشدارها را دریافت می‌کند چون منطق مربوط به هشدارها داخل Prometheus است. اوست که هشدارها را تولید می‌کند و تحویل سیستم مدریت هشدارها می‌دهد. سپس سیستم مدیریت هشدارها با ایمیل، PagerDuty ، Slack ، HipChat یا … صحبت می‌کند. اگر بخواهید با JSON و HTTP صحبت می‌کند. روشی که ما برای قابل اطمینان ساختن این ارتباط داریم این است که سرور Prometheus به شکل مداوم این پیام‌ها را تکرار می‌کند. به همین ترتیب در سمت سیستم مدیریت هشدار هم امکان چندین بار تکرار مجدد با فواصل زمانی وجود دارد. مثلاً اگر افراد گاهی، فراخوانی‌ها را لغو کنند و آن‌ها را به شکل تصادفی نادیده بگیرند یا خواب باشند یا هر چیز که باشد، تکرار آن مثلاً بعد از یک ساعت آن هشدار را می‌فرستد چون هنوز پاسخی رخ نداده است. بنابراین چندین تکرار مجدد در همه جای سیستم وجود دارد تا کارها به خوبی و قابل اطمینان انجام شوند. در عمل به علت خرابی یا هر چیز دیگری، ممکن است یک هشدار را برای یک دقیقه از دست بدهید اما یک دقیقه بعد آن را می‌گیرید و این مشکلی ندارد چون بهرحال ۵ دقیقه برای افراد طول می‌کشد که لپ‌تاب‌‌شان را به کار اندازند.

در اینجا به یک دلیل اجتناب از ZooKeeper اشاره کردید. سیستم‌هایی مانند ZooKeeper یا Consul همواره با توافقی (Consensus) که فراهم می‌کنند برای هماهنگ کردن (Coordination) یک سیستم توزیع‌شده مفید هستند. جنبه‌های منفی نیاز به هماهنگی برای توافق چیست؟ چرا وقتی از Prometheus استفاده می‌کنید می‌توانید از توافق اجتناب کنید؟

وقتی نیاز به سازگاری (Consistency) دارید توافق چیز خوبی است. مثلاً تولید داده‌ها، شاید بهترین نمونه‌ای باشد که نیاز دارید همه چیز ایده‌آل باشد. در زمینه مانیتورینگ با Prometheus ما یک انتخاب مهندسی ;کردیم که از توافق و از یک سیستم با سازگاری بالا (Highly Consistent) استفاده نکنیم. چون مسأله این است که اگر فرضاً یک حد نصاب اکثریت (Quorum) داشته باشید مثلاً اگر ۳ نُد داشته باشید و یک گسست شبکه (Network Partition) داشته باشید که یکی از آن‌ها را بیرون بیاندازد و به خاطر خرابی یکی از ماشین‌ها، یکی دیگر هم خارج شود، به ناگاه دیگر نمی‌توانید به حرکت ادامه دهید. یعنی بسته به اینکه واقعاً چطور تنظیم کرده باشید، ممکن است تعلیق شده و سیستم مانیتورینگ دیگر کار نکند. در حالیکه Prometheus با جدا کردن کامل سرورها از یگدیگر، از همه این موضوعات اجتناب کرده است.

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

برای قابلیت اطمینان می‌توانید دو سرور Prometheus را اجرا کنید که ممکن است داده‌های کمی متفاوتی داشته باشند. اما سیستم هشداردهی قابل اطمینانی فراهم می‌کنند چون دو تا ایز آن‌ها دارید.

درسته. بگذار کمی در مورد مدل پرس‌وجو صحبت کنیم. برای پرس‌وجو از سرور Prometheus چه API ای‌ وجود دارد؟

مورد اصلی آن API به شکل HTTP است که پرس‌وجو را می‌فرستید و نتایج را برمی‌گرداند. اساساً این روشی است که همه راه‌حل‌های گرافیکی با آن کار می‌کنند. می‌گوییدکه: «در این زمان، این پرس‌وجو را اجرا کن!» یا «در این بازه‌های زمانی مثلاً هر ۱۰ ثانیه، نتایج را به من بده!»

از پرس‌وجو‌هایی که ممکن است در ارتباط با داده‌های مانیتورینگ داشته باشیم، یک نمونه بگویید.

برای یک نمونه ساده، فرضاً اگر یک شمارشگر درخواست‌ها داشته باشید مثلاً اگر request_total نام داشته باشد -البته این نام کمی مبهم است- آنگاه اولین کاری که می‌خواهید بکنید این است که آن را به نرخ مثلاً تعدادش در ثانیه تبدیل کنید چون یک شمارشگر همواره زیاد می‌شود اما اینکه در نمودارتان ببینید که فقط بالا می‌رود چندان مفید نیست. بنابراین می‌خواهید که request_total[1min] را داشته باشید تا نرخ تعداد آن در ثانیه را بدهد تا آن را بکشید. اما این برای هر نمونه [از آن سرویس] خواهد بود در حالیکه آمارهای در سطح سرویس برای‌مان حائز اهمیت است. بنابراین می‌خواهید این نمونه‌ها را بخوانید و از هم تشخیص دهید و سپس می‌توانیم بر روی این داده‌ها، نرخ مجموع‌ مستقل از هرکدام از نمونه‌ها را در یک بازه ۵ دقیقه‌ای حساب کنیم. و نرخ این متریک را بر روی همه سرورهای Prometheus خواهیم داشت.

البته این یک سئوال کلی در زمینه مانیتورینگ است اما چه شرایط مختلفی وجود دارد که یک مهندس در کار روزانه‌اش از سرور مانیتورینگ پرس‌وجو داشته باشد؟ آیا تنها برای برپا کردن یک داشبورد این کار را می‌کنم؟ آیا برای فهمیدن شرایط هنگام مثلاً آتش‌سوزی این کار را می‌کنم؟ چه دلایل مختلفی برای پرس‌وجو از سرور مانیتورینگم خواهم داشت؟

معمولاً از طریق داشبوردهای از پیش‌آماده از آن استفاده می‌کنید چون آمارهای مهمی از قبیل تعداد درخواست‌ها در ثانیه، خطاها، میزان تأخیر، مصرف CPU، مصرف حافظه و … از پیش در داشبوردها آمده‌اند. احتمالاً آماری برای هر سرویسی و چندتایی هم برای برخی از زیرسیستم‌های آن سرویس‌ها دارید. اما وقتی پایین‌تر می‌روید و می‌خواهید یک مشکل را خطایابی کنید، وقتی به مقدار کافی داخل شوید، ممکن است برای آن چیزی که می‌خواهید، داشبوردی وجود نداشته باشد و مستقیماً پرس‌وجو را بنویسید. ممکن است اینطور باشد که همانطور که دارید متریک‌ها را کاوش می‌کنید از یک طرف هم به کدها نگاه کنید و با خود بگویید: «فلان متریک در اینجا وجود دارد و اگر اضافه شده باشد به این معناست که وارد این مسیر از کد شده‌ایم و این در خطایابی کمکم می‌کند» اما داشبوردی برای آن متریک وجود نداشته باشد پس پرس‌وجویی می‌نویسید و نتیجه‌اش را می‌بینید که: «بله، در آن مسیر کد رفته است.» یعنی به این ترتیب در حال جابجایی بین کد و پرس‌وجوهای موردی هستید.

درسته. مثلاً در زمینه تبلیغات شاید پرس‌وجوی موردی به این خاطر باشد که برای هرکدام از وب‌سایت‌های مشخصی که درخواست تبلیغات داشته‌اند داشبوردی نداشته باشید اما اگر با آن وب‌سایت خاص به مشکلی بخورید ممکن است بخواهید که یک پرس‌وجوی موردی برای آن داشته باشید و از کلیه نمونه‌های آن وب‌‌سایت که درخواست تبلیغات کرده‌اند، پرس‌وجو کنید.

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

آیا از Prometheus برای لاگ استفاده می‌کنم یا اینکه از متریک‌های Prometheus متوجه مشکلی می‌شوم و بعد شاید به سراغ لاگ‌های سرور مورد نظر بروم؟

عموماً Prometheus آن [مشکل] را کشف کرده است. Prometheus اغلب در کشف مسائل سیستمی خوب است. فرضاً متوجه می‌شوید که: «الان نرخ فلان خطا ۱ درصد یا ۲ درصد شده است» و بعد همه سرورها را می‌بینید و متوجه می‌شوید که: «فلان سرور ۲۰ درصد خطا دارد و بقیه خطایی ندارند» و الان وقتش رسیده که به آن سرور نگاه کنید و ببینید چه مشکلی هست. به این ترتیب می‌توانید عمیق شوید و به آن سرور نگاه کنید و شاید لاگ‌هایش را ببینید. از طرف دیگر، اگر بخواهید یک مورد از انواع چیزهای ممکن را بیابید، لاگ گزینه بهتری است.

با گسست در شبکه (Network Partition) چه رخ می‌دهد؟ وقتی بین سرور Prometheus و کلاینت‌هایی که قرار است از آن‌ها واکشی شود، گسست شبکه رخ می‌دهد و این گسست برای مدت زمان مدیدی طول می‌کشد آیا این داده‌ها، از دست می‌روند یا راهی برای بازیابی آن‌ها هست؟

در اینصورت، داده‌ها از دست می‌روند. چون Prometheus تلاش می‌کند که خراشی از داده‌ها را بگیرد و مهلتش تمام می‌شود و تنها گزارش می‌کند که متغیرهای در دسترس آن، صفر است و کار تمام می‌شود. حال سؤال این است که اگر یک تنظیمات HA داشته باشید و یکی [از سرورهای Prometheus] در یک طرف گسست باشد و آن یکی در طرف دیگر باشد، آیا بعداً می‌توانند با هم همگام شده و داده‌ها ادغام شود؟ اما مشکل آن بیشتر یک مشکل معنایی است چون این درواقع، یک سناریوی بیزانیتین (Byzantine) است و شما نمی‌دانید که کدامیک درست است. مشکل دوم این است که یک قطعی داشته‌اید یا در وسط یک وضعیت ضعف شبکه (Network Flakiness) قرار دارید. در این حال دارید با همان سرعت گام‌های عادی خود حرکت می‌کنید اما اگر بخواهید که داده‌های قبلی را بگیرید بار خود را دو برابر یا سه برابر می‌کنید که می‌تواند قطعی را بدتر کند. بنابراین این دو مشکل وجود دارد: یکی معنایی است که مشخص نیست کدامیک معنای درستی دارند و دیگری اینکه در‌واقع می‌تواند قطعی را بدتر کند. در این نوع شرایط اصلاً نمی‌ارزد که در ارتباط با قابلیت اطمینان سیستم ریسک کنیم یعنی از نظر آن باری که در زمان قطعی هست و از نظر کد[هایی که برای آن باید پیاده‌سازی شود] و ریسک‌هایی که در آن هست. در عوض فقط می‌گوییم: «ما یکبار در هر فصل وقتی که قفسه‌ها (Rack) جابجا می‌شود و کسی می‌خواهد آن‌ها را تمیز کند ممکن است یک وقفه‌ای داشته باشیم اما اشکالی ندارد.» و با درک اینکه «ساده بهتر است»، از این دست مصالحه‌های مهندسی انجام می‌دهیم.

آیا سرویس‌های با حساسیت بالای مشخصی وجود دارند که برای آن‌ها این استراتژی قابل قبول نباشد؟

احتمالاً وجود دارند. اما در آنصورت به دنبال نوع دیگری از مانیتورینگ خواهید بود. چون در آنصورت، در عوض هر چیز دیگری بدنبال سازگاری هستید و این شرایطی است که اگر مانیتورینگ خراب شود، سرویس را خاموش می‌کنید. چون ادامه دادن پذیرش پرس‌وجوها برای‌تان بد است زیرا نمی‌توانید با اطمینان آن‌ها را مانا (Persist) کنید.

اگر معماری داشته باشم که چند سرویس با حساسیت بالا داشته باشد که برای آن‌ها واقعاً به یک مانیتورینگ سازگار نیاز داشته باشم چطور می‌توانم این چارچوب ناهمگون که بیشترش با استفاده از Prometheus خوب کار می‌کند را مطابقت دهم؟ Prometheus چطور می‌تواند با مانیتورینگ ناهمگون مطابقت یابد؟

احتمالاً به شرایط دقیقی وابسته است که با آن سر و کار دارید. زیرا با Prometheus اگر انتخاب بین سازگاری و دسترس‌پذیری باشد ما همواره دسترس‌پذیری را انتخاب می‌کنیم چون ما با وقفه‌های کوچک در داده‌ها مشکلی نداریم. ما می‌توانیم سیستم‌تان را مانیتور کنیم و از طریق همه این متریک‌ها بگوییم کلاً چطور کار می‌کند اما اگر با این وقفه‌های کوچک مشکل داشته باشید، برای سطح دقت بی‌نقص، به راه حل‌های دیگری نیاز دارید. مثلاً برای داده‌های مربوط به سیستم‌های سلامت پزشکی، ایده بدی است که آن را در Prometheus قرار دهیم. من شرکت‌هایی می‌شناسم که چنین سیستم‌هایی را مانیتور می‌کنند و برای این کار خوب هستند.

آیا Prometheus می‌تواند سلامت خودش را مانیتور کند؟

بله، کاملاً عادی است که Prometheus خراشی از داده‌های خودش بگیرد.

معماری آن چه شکلی است؟ آیا سرور مجزایی دارید که سرورِ سرورهای Prometheus باشد؟

بله، این عموماً ایده خوبی است. البته این هم که هر Prometheus از خودش خراش بردارد هم عادی است.

بسیار خوب. جالب است. رویه به راه انداختن آن، برای شرکتی که می‌خواهد از Prometheus استفاده کند چیست؟

عموماً بهتر است کار را از بخشی کوچک و بدون ریسک آغاز کنید. یعنی یک NodeExporter برمی‌دارید و آن را بر روی برخی از ماشین‌ها نصب می‌کنید و Prometheus را اجرا می‌کنید تا آن‌ها را مانیتور کند و از کرنل لینوکس حدود ۵۰۰-۶۰۰ تا داده‌های آماری می‌گیرید. داده‌هایی مربوط به فایل سیستم، CPU، شبکه، دیسک و … . می‌توانید به آن‌ها نگاه کنید و اگر خوشتان آمد آن را به چیزهای زیرساختی مانند Cassandra و MySQL و PostgreSQL و HAProxy و … گسترش دهید. و بعد اگر واقعاً با آن راحت بودید می‌توانید ارزش واقعی را داخلش کنید یعنی وقتی که مستقیم در کد قرار دهید و این کتابخانه‌های کلاینت را در کد خود استفاده کنید. البته روشن است که اگر مستقیماً به سراغ کتابخانه‌های کلاینت بروید، درخواست زیادی است چون باید بگویید که: «از توسعه‌دهنده‌هایم می‌خواهم که انبوهی از کدبرای سیستمی بنویسند که می‌خواهیم آزمایش کنیم» متقاعد کردن برای این سخت است اما اگر بگویید: «می‌توانید NodeExporter را در ۲۰ دقیقه راه‌اندازی و اجرا کنید و خاموش کردنش هم ساده است» یک نفر می‌تواند آن را انجام دهد و متقاعد کردن چنین چیزی ساده‌تر است.

چه نوع سرویس‌هایی هستند که مانیتور کردن آن‌ها با Prometheus ممکن است سخت باشد یا نسبت به آنچه تا کنون تعریف کرده‌ایم، معماری پیچیده‌تری می‌طلبد؟

یک چیزی که می‌تواند دردسرساز شود، تعداد خیلی زیادی از پروسس‌های کوتاه‌مدت است. Prometheus فرض می‌کند که این‌ها برای مدتی زنده هستند. مثلاً اگر هر ۱۰ ثانیه نمونه‌گیری داشته باشید، و چیزهایی که دارید از این کوتاه‌تر باشند، داده‌ها را از دست می‌دهید. بعضی چیزها هستند مثلاً یکی از آن‌ها فکر می‌کنم Spark باشد که شامل چیزهای زیادی است که خیلی کوتاه‌مدت هستند. حتی یک معماری Serverless خالص دردسرساز خواهد بود هرچند آن چالش‌های دیگری هم بهمراه دارد. غیر از این، اگر در انتها به چیزی برسید که بیشتر شبیه لاگ باشد تا متریک، این می‌تواند بعلت تعداد داده‌ها چالش‌زا باشد. Prometheus با متریک‌ها کار می‌کند و اگر بخواهید هربار که یک Job اجرا می‌کنید یک سری زمانی جدید ایجاد کنید، در نهایت با محدودیت‌های کارایی مواجه می‌شوید.

افراد از چه ابزارهایی را در ترکیب با Prometheus استفاده می‌کنند؟

متداول‌ترینش Grafana است که چیزی است که ما برای ترسیم‌های گرافیکی پیشنهاد می‌کنیم. احتمالاً این پراستفاده‌ترینش باشد. ابزار دیگری که بین همه دسته کاربران رایج باشد، نمی‌شناسم چون خیلی متفاوت هستند.

شرکت شما یعنی Robust Perception مشاوره Prometheus انجام می‌دهد. وقتی کاربران به سراغ شما می‌آیند، عموماً در چه شرایطی هستند؟

شرکت‌ها کوچک و بزرگ هستند. شرکت‌های کوچکتر ممکن است اصلاً مانیتورنگی نداشته باشند و تنها می‌خواهند کمک شوند که چیزها را راه‌اندازی و اجرا کنند. شرکت‌های بزرگتر، عموماً سیستم‌های مانیتورینگی و تیم‌های مانیتورینگ دارند اما خیلی خوب، افزایش مقیاس نمی‌دهند. برای کارهای عملیاتی تلاش‌های زیادی می‌شود اما به آن مقیاس، ارزش ایجاد نمی‌شود. چیزها، همراستا نیستند. مثلاً می‌پرسند: «چطور از Prometheus به بهترین شکل استفاده کنیم؟ چطور آن را مستقر کنیم؟ چطور اطمینان یابیم که می‌تواند افزایش مقیاس داشته باشد؟ آیا نقایصی هست که بتوانیم از آن اجتناب کنیم؟ … »

بله. این شرکت‌هایی که همین حالا هم سیستم‌های مانیتورینگی برپا کرده‌اند چطور Prometheus را با بقیه زیرساخت‌های مانیتورینگ‌شان یکپارچه می‌کنند؟

Prometheus هم مانند هر سیستم مانیتورینگ دیگری وقتی وارد می‌شود ابتدا بیشتر یک چیز با جنبه مشورتی است که در کنار کار است و به مرور زمان نقش اعلان هشدار (Alerting) را هم می‌گیرد. و مدتی دو سیستم مانیتورینگ خواهید داشت تا زمانیکه بتوانید انتقال یابید. اما واقعاً به این وابسته است که چه فرآیندهایی دارید و با هشدارهایی که از سیستم‌ جدیدی می‌آید یا در داشبورد سیستم جدیدی است چه رفتاری می‌کنید. در حال حاضر بیشتر شرکت‌ها از Grafana استفاده می‌کنند و بهمین خاطر استفاده از یک داشبورد جدید برایشان ساده است. چالش معمولا در ارتباط با اعلان هشدار است که چه فرآیندی دارد. برای مثال اگر روی Sensu از Uchiwa استفاده می‌کنید Prometheus روش دیگری دارد و باید فکر کنید که چطور آن دو را با هم یکپارچه کنید. آیا یک ادغام‌کننده می‌نویسید؟ یا آیا همینجور می‌خواهید که دو تا چیز داشته باشید که نگاه کنید؟ یا شاید یک مدل عملیاتی کاملاً متفاوتی داشته باشید.

وقتی Prometheus اجرا می‌شود چه جنبه‌ای از سازمان ممکن است تغییر کند؟

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

جالب است. با Prometheus فرآيند کاری یک شخص آماده به زنگ (On-call) یا یک فردSRE چه تغییری می‌کند؟

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

آیا می‌دانید که Prometheus تا چه حدی از بازنویسی Borgman آمده است و از چه جنبه‌هایی با آن متفاوت است؟

جزییات زیادی از Borgman در دسترس عموم نیست. مقدار کمی اطلاعات در کتاب SRE و برخی ارائه‌های در مورد ماینتورینگ هست. حدس چندانی در این مورد ندارم.

در آینده پروژه Prometheus چه چیزهایی قرار دارد؟

چیز اصلی که در حال حاضر بدنبالش هستیم، گسترش حجم ذخیره‌سازی در بلند مدت است که می‌خواهیم به آن بپردازیم چون یک درخواست بزرگ کاربران بوده است. همینطور به دنبال این هستیم که دسترس پذیری بالا (Highly Available) برای مدیر هشداردهی (Alert Manager) داشته باشیم چون الان تبدیل به تنها نقطه شکست (Single Point of Failure) شده است. ما برای این منظور به دنبال یک رهیافت سازگاری تدریجی (Eventually Consistency) هستیم تا به هنگام گسست شبکه (Network Partition) به کارش ادامه دهد. این دو مورد چیزهای بزرگش هستند. و بغیر از آن بهبود مستمر کتابخانه کلاینت و تهیه صادرکننده‌های بیشتر ( Exporter ) و افزودن ویژگی‌های بیشتر هم مطرح است.

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

در Prometheus برچسب‌ها (Label) یکی از جنبه‌های اصلی هستند و این برچسب‌ها هستند که همه‌جا منتشر می‌شوند. بنابراین می‌توانید منشاء هشدارها را مبتنی بر برچسب‌ها قرار دهید. معمولاً برای هر شرکتی یک مدیر هشداردهی (Alert Manager) یا خوشه‌ای از آن‌ها با یک پیکربندی عمومی مشترک وجود خواهد داشت که به این معنی است که سرورهای مختلف Prometheus می‌توانند هشدارها را به تیم‌های دیگر بفرستند. فرضاً به عنوان سرویس زیرساخت Cassandra می‌توانم بگویم: «داری از سهمیه‌ات خارج می‌شوی» یا هر چیز شبیه آن. اساساً یک درخت دارید و افراد مختلفی می‌توانند باشند مثلاً می‌توان گفت: «این سرویس MySQL است. آن‌ها می‌خواهند به سراغ Slack و PagerDuty بروند و اینجا هم سرور Cassandra است و آن‌ها از HipChat و OpsGenie استفاده می‌کنند» و می‌توانید به این شکل بنا کنید. مساله بزرگ دیگر این است که ما گروه‌بندی داریم. مثلاً وقتی یک هشدار می‌آید می‌تواند منجر به یک اعلان در PagerDuty شود فرضاً می‌تواند این باشد که اگر یک ماشین پایین آمده، لازم است کسی بیاید و آن را درست کند اما در عین حال، می‌توانید برای مردن صد ماشین، تنها یک اعلان داشته باشید. بنابراین کاهش عظیمی در تعداد اعلان‌ها می‌توانید داشته باشید. بنابراین در حین پردازش آن، پیجرتان پنج دقیقه ممتد روی میز وول نمی‌خورد. یک اعلان می‌آید که می‌‌گوید صد ماشین است. این به آن معناست که به هنگام اضطرار، احتمال اضافه‌بار شدنتان (Overload) کاهش می‌یابد و بهتر می‌فهمید که چه دارد رخ می‌دهد. مزیت دیگر این است که می‌توانید آن را به هر شکلی انجام دهید. مثلاً در مورد ماشین‌ها ممکن است بخواهید ماشین‌های هر مرکز داده را تجمیع کنید. اما فرض کنید که سیستمی دارید که داده‌ها را در سطح جهانی، رونوشت‌برداری (Replicate) می‌کند. و هشداری دارید که داده‌ها بیات (Stale) شده‌اند. می‌توانید آن را براساس نام هشدار تجمیع کنید. چون احتمالاً اگر فراهم‌کننده بالادستی داده‌ها، به مشکلی خورده باشد همه مراکز داده‌ها در یک زمان هشدار خواهند داد. بنابراین اگر آن را به یک اعلان، کاهش دهید به این ایده نزدیک‌تر می‌شویم که بازاء هر عامل منشاء، تنها یک اعلان داشته باشیم که خیلی عالی است. چیز دیگری که در مدیر هشداردهی نیاز دارید، امکان ساکت کردن آن است. مثلاً قبل از تعمیرات می‌توانید برچسب‌هایی بگذارید و بگویید که اگر این شرایط برقرار شد تا ۲ ساعت هشدار نده. وقتی می‌خواهید کار گسترش داشته باشید این خیلی می‌تواند مفید باشد. یکی از چیزهای جالب‌تر در مورد مدیرهشداردهی، بحث کارایی (Performance) آن است چون با وجود این متریک‌ها و برچسب‌ها خیلی محتمل است که تعداد زیادی هشدار ایجاد کنید. بنابراین باید اطمینان یابید که کاملاً کارا است. خیلی راحت ممکن است که در یک لحظه ده‌ها هزار هشدار فعال داشته باشید.

فکر می‌کنم الان جای منطقی برای پایان دادن به بحث باشد. کجا می‌توانیم اطلاعات بیشتری در مورد شما و کارتان بیابیم؟

جای اصلی که بخواهید نگاه کنید وب‌سایت Robust Perception است. یک وبلاگ آنجا هست که من معمولاً هفته‌ای یکبار در آن پست می‌گذارم و برای خود Prometheus هم prometheus.io همه چیز را دارد.

اخیراً در مورد چه چیزهایی نوشته‌اید؟

یک کم بیشتر به این نگاه کرده‌ام که چرا ما به جای اینکه برای هرماشینی یک عامل (Agent) داشته باشیم برای هر چیزی یک صادرکننده (Exporter) داریم. به این موضوع نگاه کرده‌ام که چطور می‌تواند برای بحث اجماع (Consensus) مانیتورینگ داشت. به این پرداخته‌ام که شمارنده‌ها (Counter) چگونه کار می‌کنند و … . خیلی پست داشته‌ام. سخت است که همه‌اش را ردیف کنم.

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

خواهش می‌کنم.

مجتبی بنائی

دانشجوی دکترای نرم‌افزار دانشگاه تهران (yun.ir/smbanaie)، مدرس دانشگاه و فعال در حوزه توسعه نرم‌افزار و مهندسی داده که تمرکز کاری خود را در چند سال اخیر بر روی مطالعه و تحقیق در حوزه کلان‌داده و زیرساخت‌های پردازش داده و تولید محتوای تخصصی و کاربردی به زبان فارسی و انتشار آنها در سایت مهندسی داده گذاشته است. مدیریت پروژه‌های نرم‌افزاری و طراحی سامانه‌های مقیاس‌پذیر اطلاعاتی از دیگر فعالیتهای صورت گرفته ایشان در چند سال گذشته است.

1 دیدگاه

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

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

جای خالی در معادله زیر را با کی برد انگلیسی وارد کنید : * Time limit is exhausted. Please reload CAPTCHA.

این سایت از اکیسمت برای کاهش هرزنامه استفاده می کند. بیاموزید که چگونه اطلاعات دیدگاه های شما پردازش می‌شوند.

دکمه بازگشت به بالا