الستیک سرچ / کیبانا / لاگ استش - شفاف ببینیم


این مقاله با بررسی روند توسعه یک سیستم ریکامندر برای سایت های خبری ایرانی نشون میده که چرا استفاده از مجموعه ELK برای توسعه یک اپلیکیشن واقعی نه تنها بسیار مفید بلکه حیاتی و ضروریه…


من مسئولیت توسعه یک سیستم ریکامندر رو در یکتانت دارم که به وبسایت های خبری فارسی عرضه می شه. سیستمی که در هر صفحه از یک سایت چند مطلب پیشنهادی رو به کاربران نشون می ده. مثلا در صفحه زیر از سایت انتخاب که یک خبر از کرونا نوشته سه مطلب دیگه در مورد همین اتفاق در باکس "مطالب مرتبط" نمایش داده شده اند.

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


برای آشنایی بهتر با خود سیستم ریکامند و استفاده ELK در اون دونستن این موارد کمک می کنه.

1. برای بررسی کیفیت این سیستم از معیار CTR (نرخ کلیک به نمایش) استفاده می شه. درواقع ما تعداد کاربرهایی که روی مطالب این باکس کلیک کردند رو بر تعداد کل کاربرهایی که وارد صفحه ها شدند، تقسیم می کنیم. (با یک ساده سازی) حاصل هر چه قدر بیشتر باشه، یعنی بهتر عمل کردیم.

2. در این سیستم بعضی مواقع صفحه ای به کاربران پیشنهاد داده نمی شه و اون باکس حذف می شه. این به کانفیگ های سیستم و عملکرد سیستم های دیگه ای که باهاشون ارتباط هست بستگی داره و ممکنه کم یا زیاد بشه.

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

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

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

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

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


(زنگ تفریح) اگر فیلم See رو ندید حتما ببینید و اگه دیدید، به ارتباط دو تا عکس زیر و مقاله فکر کنین!

(حاشیه) یک راه حل بد

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

1. برنامتون و خودتون رو کند می کنه. شما برای هر نوع ایونتی باید یک مدل توی دیتابیستون درست کنید و این با کوئری های اضافه همراهه. بعد باید بشینید راه حلی برای ذخیره کردن بهینه آبجکت ها پیدا کنید. مثلا از یک دیتابیس سریع استفاده کنید، داده هارو async ذخیره کنید، aggregate کنید یا ... این ها همه پیچیدگی ناخواسته به کد و نرم افزار شما ایجاد می کنه.
2. هر موقعی که تصمیم بگیرید، ایونت هارو تغییر بدید (اطلاعات بیشتری بهشون اضافه کنید یا مدل دیگه ای از دانش رو ثبت کنید) باید با دیتابیس درگیر بشید. باید کدهای جدید برای مدل های مختلف بنویسید.
3. باید پنل فرانت اند و API بک اند طراحی کنید! پنل فرانت به سادگی یک جدول هم کلی وقت گیره مخصوصا اگه این کار رو بلد نباشید! این ممکنه وابستگی به افرادی که فرانت بلدند توی محل کارتون ایجاد کنه و کندترتون کنه. علاوه بر اون باید بعدا هم مرتب تغییرش بدید. جدای از این که خیلی محدودیت ها ممکنه داشته باشه. حتی وجود پنل ادمین در فریم ورک هایی مثل جنگو هم دردی رو دوا نمی کنه.
بسیار ساده بگم. شما به زودی بی خیال ادامه مانیتور کردن می شید. تصمیم می گیرید که به داشته های زندگی راضی باشید و مسیر رو کور ادامه بدید.
پ.ن: برای موارد خیلی اساسی مثلا کلیک در سیستمی که بر اساس کلیک پول می گیره احتمال داره دیتابیس راه مطمئن تری باشه اما برای انواع و اقسام ایونت ها که در حجم بالا و با تنوع زیاد تولید می شن، این راه حل عملی نیست.


راه حل خوب؟

برای ثبت اتفاقات سیستم یک روش معقول وجود داره و اون لاگ کردنه! بله. خیلی راحت هر اتفاقی افتاد انتهای یک فایل بنویسید.

logger.log('an event occurred')

اگه خوب کانفیگوریشن هارو انجام داده باشید همراه این مسیج، زمان، شماره خط کد، اسم تابعی که این ایونت توش بوده و اطلاعات لازم دیگه هم می تونه نوشته بشه. تهش خیلی ساده یه خط این شکلی میره ته فایل!

[11/04/2020 21:00:00 INFO [main.py:2] an event occurred] 

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

لاگ ها قبلا هم به طور خودکار توسط خیلی سیستم ها مثل nginx تولید می شد اما تبدیل این لاگ های حجیم به یک دانش مفید مهمه. این جاست که ELK وارد میدان می شه.

استک ELK ساخته شده تا به این نیاز پاسخ بده. این استک از 3 عضو Elastic search, Logstash, Kibana ساخته شده. لاگ هاتون رو وصل می کنید به این مجوعه و می رید تو کیبانا و نمودارای قشنگتون رو می کشید. (توضیح فنی تر انتهای متن)

مثال 1

من موقعی که هر درخواستی از سیستمم بشه اگه از کش استفاده بشه می نویسم cache hit وگرنه می نویسم cache missed. در نتیجه با کیبانا نمودار زیر رو درست کردم که برای هر سایت میزان استفاده از کش رو نشون می ده. چرا برای سایت های مختلف فرق می کنه؟

مثال 2

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

جدول از آمار بازدیدها و کلیک های سایت های مختلف
جدول از آمار بازدیدها و کلیک های سایت های مختلف

مثال 3

توی یک A/B testing قصد داشتم ببینم که ریکامندر در مقایسه با یک الگوریتم ساده تر (مثلا الگوریتمی که پربازدید ترین مطالب سایت (تِرِند) رو پیشنهاد می داد) چطور کار می کنه. به خاطر همین به صورت رندوم جواب رو با الگوریتم های مختلف برگردوندم و در لاگ موقع کلیک ثبت می کردم که توی چه الگوریتمی کلیک شده. نتیجه زیر نشون داد که الگوریتم ریکامندر از الگوریتم تِرِند بسیار بهتره. این کار رو می شد برای مقایسه دو الگوریتم خوب و یا دو کانفیگ مختلف از یک الگوریتم انجام داد.


مثال 4

من از یک سیستم پشتیبان استفاده می کنم که بعضی مواقع پاسخ گو نیست! نمودار زیر به من نشون می ده که میزان پاسخگو نبودن این سیستم در یک هفته گذشته چطور بود و کجا به اوج خودش رسیده. این طوری می تونم از مسئولش دقیق تر پیگیر مشکل بشم.


یک دولوپر در حال تحلیل نمودارها
یک دولوپر در حال تحلیل نمودارها


نکته مهم: قابلیت و استفاده این مجموعه احتمالا فقط این جا نیست. مثلا ممکنه داده های غیر لاگ رو هم بخواید با مجموعه ELK نمایش بدید یا از دیتابیس Elasticsearch استفاده دیگه ای داشته باشید. این مقاله صرفا توضیح یک مورد استفاده این مجموعه در کنار هم هست.


بخش فنی

استک ELK چه طور هست؟ این استک از سه جز اصلی الستیک سرچ، کیبانا و لاگ استش تشکیل شده که بهشون بیت ها هم می تونند اضافه بشن.

الستیک سرچ (Elasticsearch)

الستیک سرچ به عنوان قلب این مجموعه یک دیتابیس جست و جو بر اساس متن هست. یعنی خیلی خوب می شه توش روی متن های ذخیره شده کوئری زد.(از ایندکس لوسین استفاده می کنه)

الستیک سرچ یک API به بیرون می ده که با اون می شه کوئری هایی رو داخلش زد. یک API هم می ده که ابزارهای دیگه مثل لاگ استش یا فایل بیت - که جلوتر در موردشون توضیح داده می شه - بتونند ازش استفاده کنند. در واقع کل داده های لاگ ما در داخل این دیتابیس ذخیره می شن و بعدا با کوئری زدن به نتایجی که می خوایم می رسیم.

الستیک سرچ به شکل قلب
الستیک سرچ به شکل قلب

الستیک سرچ به طور مجزا secure می شه و برای ارتباط با هر کدوم از ماجول های دیگه می شه آتنتیکیشن جدا آماده کرد. (خبری چند وقت پیش برای لو رفتن داده حدود 40 میلیون کاربر تلگرام منتشر شده بود که ادعا می کرد که این اطلاعات از یک دیتابیس الستیک سرچ بدون پسورد سرقت شده اند!)

سوال انتقادی: در راه حل بد من ادعا کردم که استفاده از دیتابیس روش خوبی نیست و حالا در راه حل خوب نهایتا از دیتابیس Elasticsearch استفاده شد! پس چی شد؟!

کیبانا (Kibana)

کیبانا ابزاری هست که باهاش می شه نمودارها رو در یک پنل کاربری درست کرد و بعد خودش اون ها رو تبدیل به کوئیری الستیک سرچ می کنه. کیبانا کوئری رو از طریق API الستیک کال می کنه و نهایتا خروجی اون رو تبدیل به نمودارهای گرافیکی می کنه. مثلا در نمونه زیر به سادگی دو فیلتر روی داده انجام شده. یکی فیلتر داده های 15 دقیقه پیش و دیگری وجود لغت click در داده که نشون دهنده لاگ مربوط به کلیک هست. بعد یک piechart درست شده که بر اساس لغت پابلیشر به 4 قسمت مختلف تقسیم کرده و تعداد رو شمرده. (در اون زمان 4 وب سایت از سرویس ریکامندر استفاده می کردند.)

نمونه نمودار
نمونه نمودار
  • نکته مهم: اطلاعات خود کیبانا (داشبوردها، ویژوال ها و ...) در خود الستیک سرچ ذخیره میشن.

لاگ استش (Logstash)

لاگ استش لاگ ها رو می گیره، پارسشون می کنه و به الستیک سرچ می فرسته. مثلا اگه توی لاگ اطلاعات زمان دارید می تونید در این مرحله از لاگ استخراج کنید تا به سری زمانی (مثال 4) برسید. علاوه بر این توی مثال بالا لغت publisher رو هم لاگ استش از توی لاگ ها استخراج کرده. می تونه IP ها رو از لاگ هایی که داخلشون این اطلاعات هست استخراج کنه و به موقعیت مکانی دقیق شامل latitude, longitude, city, country و ... تبدیل کنه. علاوه بر این می تونه مثلا اعداد رو بعد از استخراج از داخل استرینگ به عدد واقعی تبدیل کنید تا الستیک قابلیت اجرای عملیات های ریاضی مثل جمع و مدین رو روشون داشته باشه. این کارها با پیداکردن پترن توسط یک ماجول داخلی به اسم grok یا dissect انجام می شه و تبدیل ها رو فیلترهای تخصصی به نام های Date, geoip و ... انجام می دن.

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

استک ELK
استک ELK


بیت ها (Beats)

برای جمع آوری داده ها از سیستم های مختلف و انتقال اون ها از یک سری بیت می شه استفاده کرد. اصلی ترین اون ها Filebeat هست.فایل بیت کار جمع آوری داده از فایل های لاگ معمولی و انتقال اون به لاگ استش رو انجام می ده. توی حالت ساده می شه فایل لاگ رو مستقیم به خود لاگ استش وصل کرد اما مثلا وقتی فایل لاگ روی یک سرور دیگه هست و لاگ استش جای دیگه، فایل بیت به عنوان یک ماجول تخصصی مسئولیت این انتقال رو به عهده میگیره. مزایای حرفه ای تری مثل مدیریت نرخ ارسال لاگ ها به لاگ استش درمواقع سنگینی رو هم می فهمه و می شه باهاش کدگزاری های لازم برای حفظ امنیت داده هارو انجام داد.

(در حالت ساده می شه هم خود فایل بیت رو به الستیک وصل کرد.)

معماری سیسم به همراه بیت ها
معماری سیسم به همراه بیت ها

علاوه بر اون بیت های دیگه مثل metricbeat و heartbeat کمک می کنه که وضعیت سلامتی سرور و اپلیکیشنتون رو مانیتور کنید.

دیتای جمع آوری شده توسط Heartbeat در کیبانا
دیتای جمع آوری شده توسط Heartbeat در کیبانا


انواع بیت ها برای انواع داده ها
انواع بیت ها برای انواع داده ها


قابلیت های کیبانا

کیبانا از یک سری ویژوالایزیشن های آماده تشکیل شده که لیستش در زیر نشون داده شده. در هر کدوم می تونید یک مجموعه از داده ها رو ورودی بدید و بر اساس فیلترهای مختلف (مثلا وجود کلمه های خاص در لاگ ها) می تونید محورهای مختلف نمودارهاتون رو تعیین کنید، یا نموداررو به نمودارهای کوچک تر تبدیل کنید و ...

چون قاعده کار بین بیشتر اون ها یکسان هست، خیلی سریع می تونید باهاش آشنا بشید.


قسمت خیلی قشنگ و راحت کیبانا دشبوردهاش هستن. هر دشبورد خیلی ساده یک مجموعه از ویژوالایزیشن های بالاست که کنار هم قرار گرفته تا راحت کار کنید. خیلی راحت می تونید هر ویژوال رو با سایز دلخواه اون جا بگذارید و بعد ذخیره کردن، با بازکردن دشبورد همه ویژوال هارو یک جا می بینید.

یک نمونه دشبورد خفن
یک نمونه دشبورد خفن


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

پنل ورود کاربر به کیبانا
پنل ورود کاربر به کیبانا


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

  • کانواس: برای درست کردن مطالب تبلیغاتی. می تونید این ها رو برای مشتری ها بفرستید. داده ها رو زنده بهتون نشون می ده.
کانواس
کانواس
  • نقشه: برای تصویر سازی داده های نقشه که latitude و longitude دارند. (اگه یادتون باشه گفتم که لاگ استش IP رو می تونه تبدیل به این داده ها بکنه.) داده های پیچیده تر نقشه هم ساپورت می کنه.
نقشه
نقشه
  • کیبانا لنز: برای درست کردن گرافیک های خفن تر به طور ساده تر که حتی بهتون پیشنهاد خودکار برای نمودارها میده. این قابلیت تازه اضافه شده و در نسخه بتاست!
کیبانا لنز
کیبانا لنز
  • ماشین لرنینگ: کارهای ماشین لرنینگ ساده رو می شه انجام داد. مثلا وقتی که می خواید از روی یک سری زمانی آینده رو پیش بینی کنید!
  • داده زنده لاگ: با این می تونید لاگ های جدید رو زنده ببینید و فیلتر کنید. این به جای tail کردن روی لاگ های سرور هست.


به علاوه کیبانا یک سری پلاگین هم داره که به صورت اوپن سورس براش دولوپ می شه. مثل نمونه زیر که (درست نخوندم چیه ولی احتمالا) یک چراغ خطر داره که توش وضعیت سیستم رو جالب تر ویژوالایز کنید! البته بیشتر پلاگین ها تخصصی تر و مفید برای شرایط خاصند. من از پلاگین enhanced table استفاده کردم که همون جدول خود کیباناست ولی اجازه وارد کردن فیلدهای محاسبه شده رو می ده.

در آخر این که توی کیبانا می تونیم وضعیت خود Elasticsearch رو مانیتور کنیم. ایندکس هاش، کلاسترهاش، منابع مصرفیش، لایسنسش و ... بیشتر تغییرات از طریق همین پنل قابل اعماله و این کار با سیستم رو راحت تر می کنه.

برای جمع بندی، عکس زیر به عنوان قابلیت های کیبانا رو در یک قاب نشون می ده.

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

قدرت زیرساختی

این مجموعه قدرت پردازشی بالایی داره. الستیک سرچ به راحتی کانفیگور می شه تا در مدیریت حافظه و مموری بهتره عمل کنه. مثلا سیاست هایی داره که آبجکت های قدیمی رو با زمان بندی خوبی کم کم کاهش دسترسی بده و نهایتا حذف کنه. به علاوه distributedه. می شه روی چند سرور یا کلاستر همزمان اجراش کرد و با هماهنگی لاگ استش خودش پردازش هارو تقسیم و مدیریت می کنه. علاوه بر این میشه از replica استفاده کرد تا درصورتی که یک سرور سوخت یا فیل شد ریپلیکای داده ها از سرورهای دیگه استفاده بشن. البته این برای وقتیه که یا حفظ داده هاتون اهمیت بالایی داره و یا اویلبل بودن سیستم مهمه.

سخن آخر

این مقاله تجربه حدود 2 یا 3 ماه استفاده من با استک ELK هست که تا حد ممکن ساده توضیح داده شده. در این ساده سازی ها ممکنه نکاتی از قلم افتاده باشه. ممنون می شم که در این مورد نظرات و انتقادات خودتون رو با من به اشتراک بزارید. :)

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

مرسی
آرمین

لینک پست در لینکدین

مطلب بعدی: ریکامندر سیستم یکتانت | الگوریتم ها

Contact: