این نوشته پس از تجربیات تیم رستک در پروژهی راهاندازی سامانهی خود ارزیابی کرونا که در مقالهی «رستک و کرونا! اسفند بیمار و چالشها» به تفصیل آن تجربه پرداختیم منتشر شده است. در این نوشته قصد داریم تجربه خودمان را در بهبود کارایی استفاده از Apache Solr در بازهای کوتاه، که به دلیل افزایش ناگهانی کاربران ماژول پرسشنامههای رستِک اتفاق افتاد، با شما به اشتراک بگذاریم. لازم به ذکر است که تا قبل از این رخداد، به دلیل تمرکز تیم بر رفع پیچیدگیهای کاربردی سامانه و همچنین محدود بودن کاربران توجه به کارایی تنها محدود به استفاده از مدل و ابزار مناسب برای ثبت داده و تحلیل داده بود و نیاز چندانی برای بهینه کردن جزئیات استفاده از این ابزارها احساس نشده بود.
اگر بخواهیم به صورت مختصر بیان کنیم که این ماژول چگونه دادهها را ذخیره و تحلیل میکند باید بگویم که برای این کار از یک پایگاه داده postgres و چندین هسته Apache Solr استفاده میشود که هر یک هدف مربوط به خود را دارد. پایگاه داده postgres وظیفه نگهداری پایدار از پرسشنامهها و پاسخها را به عهده دارد و از طرفی تمام نسخههای پاسخ را نیز نگهداری می کند. در کنار آن پس از ارزیابی و ثبت هر پاسخ، اسنادی مناسب فرایند تحلیل در Solr ذخیره میشود تا در ادامه برای استخراج تحلیلها از آن استفاده شود.
مزایا و معایب استفاده از Solr در اینجا Solr مزایای زیر را برای ما به ارمغان میآورد:
با وجود مزایای بالا معایب زیر نیز در استفاده از Solr وجود دارد
همانطور که گفته شد هدف اصلی استفاده از Solr پاسخگویی به درخواستها**ی زیاد دریافت تحلیل داده****ها** بوده است. اما در شرایط و کاربرد خاصی رفتار کاربران تغییر کرد و به یکباره دهها پاسخ در ثانیه به سمت این ماژول سرازیر شدند که عملاً باعث شد بخش زیادی از پاسخها برای ذخیره شدن دهها ثانیه زمان نیاز داشته باشند.
در ادامه با شبیهسازی رفتار این کاربران بر روی سرور آزمایشی توانستم مشکلات زیر را که باعث کندی در ثبت پاسخها بود کشف کنیم که خوشحال میشویم آنها را با شما به اشتراک بگذاریم.
برای شبیهسازی این رفتار تستی طراحی شد که در این تست ۴۰ کاربر همزمان به صورت پیوسته هر یک ۱۶ پاسخ را به یک پرسشنامه ارسال می کنند. از طرفی ارتباط با postgres با استفاده از Hibernate و ارتباط با Solr با استفاده از کتابخانه رسمی SolrJ انجام شده است.
پیش از هر گونه بهینهسازی، این تست در مجموع بر روی ماشین نمونه در زمان 106.99 ثانیه به پایان میرسید.
در مرحله اول بهینهسازی، به این نتیجه رسیدیم که به دلیل این که در هنگام اجرای آزمونها نیاز داشتیم که داده بلافاصله بعد از ارسال پاسخها قابل تحلیل باشند، پس از ارسال اسناد به Solr در هر درخواست با ارسال دستور commit منتظر اعمال تغییرات میشدیم که در ادامه متوجه شدیم که این عمل در تکرار زیاد بسیار کند است. از طرفی Solr به صورت خودکار، هر چند ثانیه اسناد را در پس زمینه commit میکند و نیاز به این کار وجود ندارد. گرچه میتوان در هنگام commit کردن با استفاده از ویژگی soft commit سرعت را تا حدی بهبود بخشید. پس از حذف عملیات commit در انتهای ثبت هر پاسخ، مدت زمان اجرای این تست به 41.47 کاهش پیدا کرد. با این حال، در مقایسه با حالتی که به صورت کامل قید ذخیره سازی اسناد در Solr را بزنیم ( که حدود 16.03 ثانیه طول می کشد) هنوز کند است. برای بهبود این وضعیت با بررسی بیشتر به این نتیجه رسیدیم که، این که اسناد را در یک درخواست و یا چندین درخواست مختلف به Solr بفرستیم نیز تاثیر زیادی در سرعت کلی دارد و با در نظر گرفت این موضوع به جای این که اسناد را جداگانه به Solr بفرستیم تعداد زیادی از آنها - مثلا ۶۰۰ سند - را در یک درخواست به Solr فرستادیم که با این تغییر مدت زمان اجرای این آزمون به 21.4 ثانیه کاهش پیدا کرد که در مقایسه با وقتی که اسناد تنها در پایگاه داده postgres ذخیره میشوند، رضایت بخش به نظر میرسد. با این حال نگه داشتن تعداد زیادی سند و عدم ارسال آنها به Solr در نسخه نهایی سامانه چالشهایی را دارد. از طرفی در حجم زیاد درخواست این کار نقشی حیاتی را در افزایش سرعت پاسخگویی ایفا میکند اما از طرف دیگر در زمانی که پاسخهای کمی در حال ارسال شدن هستند عملا پاسخها مدت زیادی را در انتظار میمانند تا در Solr وارد شده و قابل تحلیل باشند. به همین دلیل تصمیم گرفتیم به جای این که منتظر بمانیم تا اسناد به میزان خاصی جمع شوند عملیات ارسال اسناد به Solr را در بازههای زمانی مشخص ۱۰ ثانیهای انجام دهیم. این کار باعث میشود که در هنگامی که حجم درخواستها زیاد است در طول مدت ۱۰ ثانیه تعداد زیادی درخواست آماده ارسال شوند و از طرفی در زمان خلوتی نیز پاسخها حداکثر ۱۰ ثانیه پس از ارسال قابل تحلیل باشند.
📷
در اینجا لازم به ذکر است که هدف این نوشته بررسی دقیق کارایی ارتباط با Solr در وضعیتهای مختلف نبوده و به همین دلیل از بیان جزئیات آزمایش و همچنین روش علمی این کار که نیازمند ایزوله کردن و انجام مکرر آزمایش است خودداری شده و صرفا تاثیر دو پارامتر مختلف در ارسال دادهها به Solr را نشان دهیم. پارامتر اول، commit پس از ارسال بود که البته با توجه به مستندات Solr مشاهده بهبود در آن، مورد انتظار بود. اما پارامتر دوم، یعنی تاثیر ارسال دسته جمعی پاسخها برای ما بسیار غیر منتظره بود، زیرا در مرحله اول و با بررسی اسناد Solr این موضوع مطرح شده بود که کتابخانه SolrJ خود با استفاده از Connection Pooling فرایند ارسال و واکشی داده را به خوبی انجام میدهد؛ اما این آزمایش نشان داد که سربارهای موجود در فرایند اضافه کردن اسناد در هر درخواست فراتر از ایجاد اتصال جدید است.