دیتابیس LMDB چیست؛ بررسی راه حل‌های افزایش سرعت پاسخ سرور - سایت پی اچ دی نیوز

در این مقاله، ابتدا قصد داریم دیتابیس LMDB را بصورت خلاصه معرفی کنیم. در قدم بعدی برای اینکه نمونه‌ای از کاربرد LMDB برای ذخیره‌سازی داده‌ها ارائه دهیم، به موضوع روش‌های مختلف کاهش زمان Backend Duration در یک سایت خبری خواهیم پرداخت.کاهش زمان Backend Duration تا 26 میلی ثانیه برای افزایش سرعت وبسایتدیتابیس LMDB یا Lightning Memory-Mapped database چیست؟همانطور که از اسم این دیتابیس مشخص است، LMDB یک دیتابیس خیلی سریع و سبک است که در دسته NOSQL های نوع key-value قرار می گیرد و با زبان C نوشته شده است. از جمله دیگر ویژگی های این دیتابیس:دیتابیس LMDB از ساختار داده B+trees استفاده می کند(جستجو، درج و حذف را در زمان مصرفی لگاریتمی انجام می شوند.). این دیتابیس کاملا از ACID (Atomicity, Consistency, Isolation, Durability) پشتیبانی می کند. البته درک می کنم که LMDB ، دیتابیس شناخته شده ای نیست، اما آشنا نبودن یک دیتابیس، لزوما به معنی بی کاربرد بودنش نیست. منظور از اینکه «LMDB یک دیتابیس سَبُک است» چیه؟مسلما با دیتابیس های Embedded آشنا هستید مثل دیتابیس دَم دَستی SQLite . دیتابیس LMDB هم یک نوع دیتابیس Embedded است. یعنی LMDB نیازی به یک سرور خاص برای اجرا نداره و در واقع بصورت یک کتابخونه مورد استفاده قرار می گیره.دیتابیس LMDB چقدر می تونه سریع باشه؟برای اینکه بدونیم دیتابیس LMDB چقدر سریع است، می توانیم از یک پکیج node.js به نام lmdb-js به عنوان wrapperی برای این دیتابیس استفاده کنیم، در این صورت شاهد سرعت و تفاوت بسیار زیاد این دیتابیس، با SQLite و.. خواهیم بود.بنچمارکینگ LMDB افزایش سرعت پاسخ سرور برای بارگذاری سریعتر وبسایت (کاهش زمان Backend Duration)سرعت سایت، چه زمانی که گوگل به آن توجهی نمی کرد و چه الان که به یک فاکتور مهم در رتبه بندی سایتها تبدیل شده است، همیشه باعث رضایت کاربران و تمایل آنها به استفاده از سایتی که سرعت بیشتری دارد، می شود. ابتدا نگاهی به راه حل های کلیشه ای جهت کاهش زمان Backend duration داشته باشیم:بهینه سازی query های دیتابیس - اگر سایت از ابتدا بصورت بهینه توسعه داده شده باشد، کار زیادی در اینجا برای ریفکتورینگ وجود ندارد.استفاده از سیاست های caching و cache invalidation بصورت مناسب - برای یک سایت تعاملی پربازدید، اعمال این سیاست ها در لایه های مختلف، نیازمند تست های متعدد است اما نتیجه رضایت بخش خواهد بود.افزایش هزینه های سرور - در صورتی که دو مورد بالا، انجام شده باشند، افزایش منابع می تواند تا حدی تاثیر گذار باشد.برای نمونه فرض کنیم صفحات سایتی، توسط یک Server-Side Template Engine رندر می شوند و از یک وب فریم ورک مانند Django یا لاراول استفاده شده باشد. این سایت وابسته به یک یا چند دیتابیس مختلف مانند PostgreSQL و ... است. همینطور ممکن است از سرویس های مثل Elasticsearch برای نمایش محتواهای مرتبط با یک خبر استفاده کند.در اینجا تصور می کنیم که query های بهینه ای نوشته شده و توسعه دهندگان از سیاست های مناسبی برای Caching در لایه وب سرور و فریم ورک استفاده کرده اند. اما در هر صورت کدهای Back-end در حال اجرا هستند و ممکن است در شرایطی، ارتباطاتی نیز با دیتابیس برقرار شود.در صورتی که صفحات سایت مدام در حال بروز رسانی باشند، حتی فعال بودن الگوریتم فشرده سازی Brotli یا Gzip در وب سرور نیز، کمی به مدت زمان پاسخ سرور در اولین تقاضا، اضافه می کند! مخصوصا اگر قرار باشد فشرده سازی در سطح بالایی انجام شود. (قطعا فعال بودن فشرده سازی به کم شدن حجم صفحات و دانلود سریعتر آنها کمک می کند اما در اینجا بحث ما کاهش زمان پاسخ سرور است نه کاهش زمان receive کردن صفحه توسط مرورگر)همه اینها یعنی تضمینی وجود ندارد که این سایت برای همه کاربران، همیشه سریع باشد. طبق قانون مورفی، ممکن است یک کاربر جدید در بدترین و نامناسبترین زمان به یک صفحه از سایت مراجعه کند و تجربه سرعت پایین، باعث عدم بازگشت او به سایت ( یا مشاهده سایر صفحات سایت) شود.اما آیا در کنار این روش ها، راه حل کمال گراینه تری نیز وجود دارد؟حذف وابستگی به دیتابیس برای کاهش زمان Backend Duration در Server-side renderingبرای به حداقل رساندن زمان Backend Duration، می توانیم به دنبال راه حلی برای حذف کامل وابستگی به دیتابیس های پروژه به هنگام رندرینگ SSR صفحات سایت باشیم.اینکار ما را به یاد سایت های استاتیک می اندازد که سرور برای پاسخ به درخواست، فقط یک فایل HTML از قبل آماده شده را serve می کند. در ادامه به عنوان یک راه حل، نگاهی به SSG (Static Site Generator) خواهیم داشت و به بررسی مشکلات و چالش های آن برای یک سایت خبری با هزاران صفحه می پردازیم.ابزار SSG یا Static Site Generator چیست؟شاید به عنوان یک راه حل، ابزارهای (Static Site Generator) SSG برای کاهش زمان پاسخ سرور ایده آل باشند. در حقیقت، SSG در زمان build کدهای back-end را اجرا و با fetch کردن دیتاهای مورد نیاز، همه صفحات را به صورت استاتیک تولید می کند. حتی نیازی به پردازش وب سرور برای فشرده سازی صفحات HTML نخواهد بود، بطور مثال می توان در زمان build یک فشرده سازی سطح 11 با الگوریتم Brotli انجام داد تا صفحه HTML فشرده شده به مقدار 27% حجم کمتری نسبت به فشرده سازی gzip داشته باشد، اینکار مدت زمان پاسخ وب سرور را نیز کاهش خواهد داد، چون دیگر نیازی به پردازش در لایه وب سرور برای فشرده سازی ، وجود ندارد.حالا که به این نتیجه رسیده ایم SSG کمک کننده است، بنابراین ابتدا مشکلات استفاده از این ابزار را در یک نمونه سایت خبری بررسی می کنیم.مشکل استفاده از SSG برای سایت های خبری با هزاران صفحهسال 1389 یک سایت تعاملی-خبری در زمینه کنکور کارشناسی ارشد و دکتری راه اندازی شد که توانست در کمتر از یک سال، به 400 مین سایت پربازدید ایران تبدیل شود. بنابراین حفظ سرعت و عملکرد سایت در بازدید بالا (مثلا نیم میلیون بازدید در روز اعلام نتایج آزمون ها) همواره اولویت بالای داشت.این سایت با نام پی اچ دی آزمون، سال ها پیش تعطیل شد، اما در یک تصمیم دوباره، این بار سایتی با نام پی اچ دی نیوز و تقریبا با همان ظاهر قدیمی توسعه داده شد تا از تجربیات گذشته در آن استفاده شود. استفاده از ابزار SSG نه تنها در سایت های خبری، کمک کننده است بلکه با توجه به پتانسیل دریافت تعدادی بالای بازدیدکننده، می توان گفت ضروری نیز است. اما در این راه چالش های وجود دارد که قصد داریم با فناوری های جدید آنها را حل کنیم. سایت های خبری برخلاف سایت های شخصی، پس از مدت کوتاهی بیش از هزاران صفحه دارند، یعنی در صورت استفاده از SSG مجموع مدت زمان build برای همه صفحات سایت، بسیار طولانی خواهد شد. موضوع می تواند بدتر هم شود، مثلا اگر چند نویسنده دائما خبر تازه ای برای انتشار در سایت ثبت کنند. در این صورت قطعا برای یک سایت خبری، تاخیر در انتشار یک خبر مهم ( به دلیل زمان بر بودن build ) باعث دیرتر index شدن خبر توسط گوگل، خواهد شد و می تواند به جایگاه سایت در گوگل لطمه بزند.همچنین منابع پردازشی زیادی در زمان build نیاز خواهد بود، باوجود اینکه سرویس های پردازش ابری زیادی برای اینکار وجود دارند تا برای کاهش زمان build، نیازی به اجاره یک سرور اختصاصی قدرتمند نباشد (چراکه در صورت اجاره، بیشتر زمانش را بیکار خواهد بود) ، اما هزینه این سرویس ها برای build از هزاران صفحه، آن هم صدها مرتبه در یک روز، توجیح منطقی ندارد. در این وضعیت، راه حلی که می توان به آن چنگ زد، استفاده از DSG یا Deferred Static Generation است.روش رندرینگ بصورت DSG یا Deferred Static Generation چیست؟در روش DSG، همه صفحات در زمان build به صورت استاتیک تولید نمی شوند، بطور مثال در این روش نیازی نیست از خبرهای که خیلی قدیمی شده اند و یا صفحاتی که دیگر هیچ ترافیکی از گوگل ندارند، build گرفته شود.در این صورت مدت زمان build کاهش می یابد، خبر سریعتر در سایت منتشر می شود و هزینه کمتری برای build پرداخت خواهد شد.البته از این روش، در کنار CSR یا Client-side rendering استفاده می کنند. بنابراین از یک فریم ورک جاوا اسکریپتی در سمت مرورگر، مثل React.js ، vue.js یا ... استفاده می شود تا پیمایش کاربر در بین صفحات سایت، بدون refresh شدن مرورگر اتفاق بیفتد. بطور مثال ممکن است یک API صدا زده شود تا دیتای مورد نیاز گرفته شود و سپس فریم ورک react مسئول استفاده از این دیتا، برای رندر کردن صفحه و routing خواهد بود.رندرینگ صفحه Deferred شده، ممکن است به اندازه کافی سریع نباشد!تصور کنید اگر ناگهان یک خبر قدیمی که از build آن صرف نظر شده بود، یک شبه تبدیل به خبر مهمی شود، لینک آن در شبکه های اجتماعی بازنشر شود، یا کاربران برای مشاهده آن خبر قدیمی، از طریق گوگل وارد سایت شوند.در این شرایط CSR کاربردی ندارد چون کاربر از یک صفحه خارجی ( مثل صفحه نتایج گوگل، تایم لاین توئیتر، ...) تقاضای مشاهده صفحه را به سرور ارسال می کند، بنابراین سرور مجبور خواهد بود تا به دیتابیس کوئری بزند تا بتواند یکبار صفحه را بصورت SSR رندر و سپس cache کند.راه حل به حداقل رساندن زمان رندر صفحات Deferred شده چیست؟در نظر داشته باشید که هدف کلی ما حذف وابستگی به دیتابیس های مثل PostgreSQL و ... و عدم اجرای کدهای Back-end جنگو و .. در زمان تقاضای صفحه، برای کاهش زمان Backend Duration بود. راه حل این موضوع، می تواند ایجاد یک snapshot از تمام دیتاهای مورد نیاز، در زمان build باشد. در این صورت worker ی که بر روی کلاد قرار گرفته است و وظیفه رندر کردن صفحات Deferred را دارد، نیازی به برقراری ارتباط از طریق API و یا هر نوع ارتباط با دیتابیس های پروژه را نخواهد داشت. بلکه می تواند دیتای مورد نظر را از همان snapshot تهیه کند. توضیح بیشتر: فرض کنید یک cloud worker به جای ارتباط مستقیم با دیتابیس (یا صدا زدن API) ، از یک فایل JSON استفاده کند که قبلا در زمان build تهیه شده است. خب حالا دیتای Snapshot را در کجا ذخیره کنیم که سرعت بیشتری داشته باشه؟الف) همینجوری کفِ دیسک در فایل سیستم ب) Redis ج) SQLite د) LMDBاز آنجایی که قصد داریم داده های schema-free را بصورت single-level ذخیره کنیم و با سرعت بالایی به آنها دسترسی داشته باشیم بدون اینکه منابع زیادی مصرف شود، می توانیم همه دیتایی که در زمان بیلد، Fetch شده بود را در LMDB ذخیره کنیم. طبق benchmark اول مقاله، LMDB قادر است نزدیک به 2 میلیون دیتا را در یک ثانیه به یک structured object (فرضا با 10 پراپرتی) با استفاده از فقط یک thread، دیکود کند.بنابراین صفحاتی که در روش DSG ازشون صرف نظر کرده بودیم، در اولین تقاضا با سرعت بالایی رندر می شوند و به جمع بقیه صفحات SSR شده می پیوندند.امیدوارم این مطلب مفید بوده باشه. در مقاله بعدی سعی می کنم در مورد تعدادی از چالش ها، راه حل ها و فناوری های بهینه سازی و فشرده سازی ویدیوها برای پخش استریم بنویسم.خوشحال می شویم سایت پی اچ دی نیوز را به دوستان خود که قصد ادامه تحصیل در مقطع دکتری دارند، معرفی کنید.از زمان اعلام نتایج دکتری 1401 و دریافت کارنامه اولیه آزمون دکتری برای انتخاب رشته، باخبر شوید.