مهندس ارشد توسعه نرم افزار مجموعه صباایده، فیلیمو، آپارات | Staff Engineer @Sabaidea,
معرفی سیستم های Caching و استفاده آنها در آپارات
در این پست می خواهیم درباره اینکه سیستم های caching چی هستند و ما چطور از آنها در طراحی سیستم های نرم افزاری استفاده می کنیم صحبت کنیم و در انتهای این مطلب می تونیم انتظار داشته باشیم که بدونیمcache چی هست و در چه شرایطی از اون میشه استفاده کرد.

معماری های سه لایه مدلی است که توسط بسیاری از توسعه دهنده های برای تولید نرم افزارهای قابل انعطاف و قابل گسترش استفاده می شوند این معماری شامل ۳ لایه ی زیر هستند :
- Presentation Tier (User Interface)
لایه ای که کاربر با اون در حال تعامل هست این لایه دستورات و نتایج اون رو از سرور به چیزی که کاربر متوجه میشه ترجمه می کنه
- Application Tier (Business Logic)
این لایه هماهنگ کننده نرم افزار هست، به عبارت دیگه این لایه دستورات و درخواست های کاربر رو بررسی میکنه و تصمیمات منطقی رو میگیره و داده رو بین لایه User Interface و بانک اطلاعاتی منتقل می کنه.
- Data Tier (Database and File Storage)
این لایه هم جایی هست که همه اطلاعات در ذخیره می شوند.
این لایه های معمولا به صورت مستقل از هم کار میکنند و به صورت مستقل از هم نیز نگهداری میشوند و در بیشتر موارد هر کدوم از این لایه ها بروی یک ماشین (Host) مجزا قرار دارند. پس هر بار که لایه Application درخواستی برای دریافت اطلاعات میفرسته سرعت این عملیات به عملکرد شبکه بین این ماشین ها محدود خواهد شد و البته میدونیم که مدت زمان مورد نیاز برای دریافت اطلاعات و نمایش اون نقش مهمی در تجربه کاربر از یک سرویس رو داره و عموماً جزو نیازهای اساسی هر کسب و کار آنلاینی هست.
کَش و دلایل استفاده از اون چیه ؟
برای اینکه مثال ما مصداقی تر باشه یک مثال از این پروسه رو روی آپارات بررسی می کنیم. فرض کنید یک کاربر به صفحه اول آپارات در حالتی که Recommendation خاموش هست مراجعه میکنه و برای نمایش اطلاعات صفحه اول لایه Application نیازمند تعداد انجام تعدادمشخصی از query ها به بانک اطلاعاتی برای دریافت این اطلاعات هست و این یعنی به ازای هر بارگذاری این صفحه (که تقریبا چندصد بار در ثانیه از سوی افراد در حال بارگذاری هست) باید یک Query یکسان به بانک اطلاعاتی ارسال بشه و این یعنی حجم عظیمی از I/O روی بانک اطلاعاتی و شبکه مربوط به اون رو مطلبه.
Cache کردن یه تکنیک بافرینگه که داده هایی که به دفعات از بانک اطلاعاتی دریافت می شوند رو در یک حافظه موقتی ذخیره می کنه و این کار فشار ایجاد شدو روی بانک اطلاعاتی و مدت زمان دریافت این اطلاعات رو کاهش میده. در مثال بالا وقتی برای اولین بار این اطلاعات درخواست میشه، نتیجه این Query از بانک اطلاعاتی دریافت میشه در جایی کنار لایه Application یا خیلی نزدیکتر از جایی که لایه Data قرارداره ذخیره میشه و در درخواست های بعدی این اطلاعات از اون حافظه موقتی یا Cache به لایه Application ارسال می شوند.
به طور کلی مزایایی استفاده از Cache شامل موارد ذیل هستند:
بهبود عملکرد : وقتی داده مورد نیاز لایه Application از طریق Cache راحتتر قابل دسترس باشه فشار روی بانک اطلاعاتی کاهش پیدا میکنه و به این شکل عملکرد نرم افزار بهبود پیدا میکنه
مقیاس پذیری: با تقسیم کردن بار درخواستهای داده بروی یک سیستم کشینگ توزیع شده با هزینه پایین تر و انعطاف پذیری بیشتر مقیاس پذیری سیستم افزایش پیدا می کنه.
بهبود دسترسی: به واسطه وجود Cache در سیستم حتی هنگامی که سرور بانکهای اطلاعاتی در دسترس نباشند، Cache می تواند سرویس پیوسته سیستم را تا زمانی که سرورها به مدار بازگردانده شوند رو فراهم کنند و این ترتیب سیستم نسبت به خرابی مقاوم تر خواهد بود.
خب الان که با مزیت های Cache آشنا شدید شاید با خودتون بگید خوبه همه چیز رو روی اون نگهداری کنیم تا سرعت اجرای سایت بالاتر بره ! خوب این تا حدی درست هست اما چند مورد هست که استفاده از کش رو محدود میکنه.
- سخت افزارهایی که برای لایه Cache استفاده می شوند معمولا نسبت به سخت افزارهای مورد استفاده در بانک های اطلاعاتی گرون تر هستند
- اگر اطلاعات خیلی زیادی رو روی Cache ذخیره کنید بسته به نوع بستری که برای Cache استفاده می کنید مدت زمان مورد نیاز برای جستجوی اون کلید افزایش پیدا میکنه و به مرور ممکنه به جایی برسید که بانک اطلاعاتی از لایه Cache سریعتر عمل کنه و عملا نقض غرض کنه.
خوب با در نظر گرفتن محدودیت های فوق زمانی که می خواهیم انتخاب کنیم که از Cache چطور استفاده کنیم باید به دو سوال اساسی پاسخ بدهیم
- کی می خواهم اطلاعاتی رو وارد cache کنم ؟
- کی می خواهم اطلاعاتی رو از cache خارج کنم ؟
به مجموع این دو سوال به اصطلاح Cache Policy گفته می شود و Policy های استاندارد مختلفی در اینباره وجود دارند که از آنها می توان به LRU و LIFO اشاره کرد. در این لینک می توانید درباره این Policy های مختلف بیشتر مطالعه کنید.
معایب استفاده از Cache یا بهتر بگیم Cache Policy اشتباه !
تا اینجا درباره محاسن استفاده از cache در سیستم صحبت کردیم ولی پیاده سازی اشتباه اون و یا بهتر بگیم انتخاب قواعد اشتباه برای کش کردن می تونن باعث ایجاد مشکلات زیر بشوند :
- عملیات اضافه (Extra Call):
فرض کنید به خاطر مدل پیاده سازی غیر صحیح cache هر بار که به اون مراجعه کنید فاقد اطلاعات لازم باشه و در این حالت باید دوباره به سراغ بانک اطلاعاتی بروید. در این حالت cache فقط یک مرحله به روال عادی شما اضافه میکنه و کار رو برای شما طولانی تر خواهد کرد. - تله Trashing:
فرض کنید یک کاربر از شما می خواهد اطلاعات پروفایل خودش رو دریافت کنه و شما به اشتباه اطلاعات اون رو همیشه به یک نام ثابت و در یک محل ثابت از cache ذخیره کنید. کاربر A از شما می خواهد اطلاعات کاربری رو بهش بدید شما اون اطلاعات رو از بانک میگیرد و در cache ذخیره میکنید، به دنبال اون کاربر B میاد و از شما اطلاعات پروفایلش رو درخواست میکنه و شما دوباره اون رو در همون محل به جای اطلاعات نفر A ! در این حالت در درخواست بعدی نفر A یا اطلاعات اشتباه دریافت می کنه و یا اینکه اطلاعات رو باید دوباره از بانک دریافت کنه ! - مشکل Consistency یا ثبات اطلاعات:
این شاید واضحترین مشکل caching باشه، وقتی اطلاعات رو از بانک اطلاعاتی می خونید و داخل cache قرار بدیم و اون اطلاعات در بانک اطلاعاتی به هر ترتیب تغییر کنند یا حذف شوند cache به نسخه قدیمی اون اطلاعات اشاره دارد، در نتیجه موارد مهم در تعیین استراتژی کشینگ تعیین رویه بروز رسانی اطلاعات در cache خواهد بود.
استراتژی های Caching
استراتژی caching به معنی تعیین ارتباط بین منبع اطلاعات ( بانک اطلاعاتی ) و سیستم caching و اینکه اطلاعات کش به چه شکل قابل دسترسی هستند، می باشد. استراتژی های مختلفی در مورد نحوه کش کردن وجود دارند و انتخاب هریک از آنها تاثیر متفاوتی بر طراحی سیستم و کارآیی آن دارند. پس همیشه قبل از طراحی معماری بهتر است یکبار مسیر دریافت اطلاعات در نرم افزار خود را بررسی کنید با بتوانید انتخاب کنید کدامیک از این استراتژی ها بهتر برای شما کار میکند در ادامه برخی از معروفترین و پر استفاده ترین استراتژی ها رو با هم بررسی می کنیم.
استراتژی Cache Aside
در این استراتژی کش در کنار بانک اطلاعاتی قرار میگیرد، در نتیجه Application اول درخواست دریافت اطلاعات رو برای کش ارسال میکند (Cache hit) و اگر این اطلاعات در کش وجود داشته باشد، نرم افزار مستقیما این اطلاعات رو دریافت خواهد کرد، در غیر این صورت (cache miss) برنامه دریافت اطلاعات رو برای بانک اطلاعاتی فرستاده و نتیجه رو برای cache هم ذخیره خواهد کرد تا در دفعات بعدی از این اطلاعات استفاده شود.

استراتژی Read Through
در این روش بر خلاف روش پیش، کش بین Application و Database قرار خواهد گرفت و نرم افزار همیشه فقط اطلاعات رو از کش درخواست خواهد کرد، در نتیجه هنگامی که یک cache miss اتفاق بیافتد، cache مسوؤل دریافت اطلاعات از بانک اطلاعاتی بروز رسانی اطلاعات خود و ارسال آن برای Application خواهد بود

استراتژی Write Through
مشابه روش Read Through در این روش نیز کش بین Application و بانک اطلاعاتی قرار میگیرد و هر درخواست نوشتن اطلاعات بروی بانک باید از طریق cache به سمت بانک اطلاعاتی ارسال شود به عبارت دیگر کش اول اطلاعات را بروی خود بروز رسانی کرده و در ادامه این اطلاعات را بروی بانک اطلاعاتی می نویسد.

استراتژی Write Back
این روش تنظیماتی مشابه با روش Write through دارد، دراین روش Application اطلاعات رو بروی cache ذخیره سازی می کند، اما یک وقفه زمانی بین نوشتن اطلاعات از cache به بانک اطلاعاتی وجود دارد. بطور مثال cache در بازه های زمانی ثابت یا متغیر اقدام به نوشتن اطلاعات بروی بانک اطلاعاتی خواهد کرد.

استراتژی Write Around
این استراتژی به طور معمول با روش cache aside یا read through به صورت ترکیب شده استفاده می شود در این روش Application همیشه اطلاعات را بروی بانک اطلاعاتی به صورت مستقیم می نویسد ولی اطلاعات فقط در زمان خوانده شدن از بانک اطلاعاتی بروی کش نوشته می شوند.

مقایسه مزایا و معایب استراتژی های مختلف
محاسن روش Cache Aside
- هنگامی که بانک اطلاعاتی در دسترس نباشد می تواند به عملیات خود ادامه دهد
- پیاده سازی ساده ای دارد
- مدل داده (Data Model) بین لایه دیتابیس و کش می تواند با هم متفاوت باشند
- این مدل در فشارهای بالای خواندن اطلاعات بهترین عملکرد را دارد
معایب روش Cache Aside
- عدم تطابق اطلاعات بین بانک اطلاعاتی و کش وجود خواهد داشت
- همیشه برای اولین بار با Cache miss مواجه خواهیم شد و باعث ایجاد latency خواهد شد.
محاسن روش Read Through
- به دلیل عدم ارتباط مستقیم Application با بانک اطلاعات کد آن ساده تر و قابل خواندن تر است.
- بهترین روش برای حالتیست که یه مجموع از اطلاعات به صورت مداوم درخواست می شود.
معایب روش Read Through
- نیاز به برنامه نویسی پلاگین های cache پیچیده تری برای دریافت اطلاعات از Database.
- همیشه برای اولین بار با Cache miss مواجه خواهیم شد و باعث ایجاد latency خواهد شد.
محاسن روش Write Through
- اطلاعات همیشه در cache وجود دارند و با نتیجه cache miss مواجه نخواهیم شد.
- اگر با استراتژی Read Through به صورت همزمان استفاده شود می تواند تضمین کند که همیشه اطلاعات کش با بانک اطلاعاتی بروز هستند
معایب روش Write Through
- باعث افزایش مدت زمان عملیات نوشتن در بانک اطلاعاتی خواهد شد.
محاسن روش Write Back
- مناسب برای نوشتن اطلاعات با نرخ بالا
- سازگاری نسبی با خطاهای دسترسی بانک اطلاعاتی
- کاهش فشار روی بانک با کاهش تعداد عملیات های نوشتن بروی بانک اطلاعاتی
معایب روش Write Back
- ریسک از بین رفتن اطلاعات در صورت از دست رفتن (پایین رفتن) سرویس cache
گزارشی از ورکشاپِ UX Writing در تیم آپارات(قسمت اول)
11 نوع ویدیویی که هر کسبوکاری در مورد خود باید بسازد
تست NPS چیست و چطور آن را اندازهگیری کنیم؟