امروز می‌خوام درباره‌ی موضوع بعدی وبلاگ صحبت کنم که اگر بخوام مستقیم بهش اشاره کنم، “مقیاس‌پذیری” یا Scalability هست. شاید در نگاه اول وقتی این پست‌ها رو می‌خونید، فکر کنید که دارم مقاله‌ای علمی می‌نویسم یا قراره از این نوشته‌ها به‌عنوان یک رفرنس تخصصی استفاده بشه. اما بهتره از همین ابتدا بگم که نه این یک مقاله‌ی کامله و نه من در حد نوشتن مقاله‌ی علمی هستم. پس راحت باشید و اگه دوست داشتید، نظرات من رو درباره‌ی موضوعات مختلف دنبال کنید.

مقیاس‌پذیری چیه؟

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

مقیاس‌پذیری فقط یک واژه‌ی ساده نیست که به هر چیزی نسبتش بدیم. همچنین هیچ‌وقت نمی‌تونیم بگیم که “سیستم من همیشه مقیاس‌پذیره و هیچ مشکلی در آینده نخواهد داشت.” بلکه همیشه باید این سؤال رو از خودمون بپرسیم:

“اگر سیستم من رشد کنه و کاربران جدیدی جذب کنه، چطور می‌تونم از خرابی جلوگیری کنم و سیستم رو در این فرایند سالم نگه دارم؟”

بهینه‌سازی سخت‌افزاری یا نرم‌افزاری؟

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

یک گروه از افراد ممکنه بگن: “بیایم سخت‌افزار رو ارتقا بدیم، میزان دیسک، پردازنده، حافظه‌ی اصلی و ثانویه رو افزایش بدیم تا در آینده دچار مشکل نشیم.” اما آیا این رویکرد درسته؟ 🤔 به نظر من نه! چون این افراد معمولاً هزینه‌های این نوع بهینه‌سازی رو در نظر نمی‌گیرن. علاوه بر هزینه‌ی سخت‌افزار، هزینه‌های نگهداری هم بالا میره. مخصوصاً وقتی خطاهای سخت‌افزاری رو هم در نظر بگیریم (که در پست قبلی درباره‌ش صحبت کردیم).

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

بهترین کار اینه که بدونیم دقیقاً در کجای مسیر مقیاس‌پذیری قرار داریم تا بتونیم قدم‌های بعدی رو منطقی برداریم.

چطور نقطه‌ی حضورمون رو مشخص کنیم؟

برای تحلیل مقیاس‌پذیری، اول باید بدونیم که سیستم ما الان کجاست. این موضوع به چندین فاکتور بستگی داره، مثل:

  • تعداد درخواست ها در ثانیه
  • نسبت خواندن به نوشتن در پایگاه داده
  • تعداد کاربران همزمان
  • نرخ هزینه‌ی نگهداری دیتا و کش

یک مثال واقعی از مقیاس‌پذیری: توییتر (X)

می‌خوام از کتاب Designing Data-Intensive Applications یک مثال بزنم. این کتاب در ابتدای خودش به مباحث دو پست آخر وبلاگم نزدیکه، پس اگه علاقه‌مند بودید، اون پست‌ها رو هم بخونید.

چالش توییتر چی بود؟

توییتر به‌صورت میانگین ۴۶۰۰ درخواست در ثانیه دریافت می‌کنه و این مقدار در اوج خودش می‌تونه به ۱۲ هزار درخواست در ثانیه برسه. اما چالش اصلی توییتر حجم توییت‌ها نبود! بلکه مفهومی به نام Fan-Out بود.

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

دو رویکرد مقیاس‌پذیری توییتر

توییتر دو روش رو برای حل این چالش بررسی کرد:

۱. روش اول: دریافت توییت‌ها در لحظه

در این روش، زمانی که یک کاربر تایم‌لاین خودش رو باز می‌کنه، توییتر به‌صورت لحظه‌ای تمام توییت‌های مرتبط رو از دیتابیس می‌خونه، مرتب می‌کنه و به کاربر نمایش می‌ده.

اما این روش، هزینه‌ی خواندن بالایی داره. تصور کنید که هر بار که تایم‌لاین شما به‌روز می‌شه، باید توییت‌های زیادی از پایگاه داده خوانده بشن. حالا این رو ضرب در تعداد کاربران توییتر کنید! 😵

۲. روش دوم: استفاده از کش برای کاهش هزینه‌ی خواندن

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

این روش، هزینه‌ی خواندن پایینی داره، اما هزینه‌ی نوشتن بالایی داره، چون توییتر باید هر توییت رو در کش هزاران یا حتی میلیون‌ها فالوئر ذخیره کنه.

توییتر چه راهکاری رو انتخاب کرد؟

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

اما اینجا یک مشکل وجود داشت!

روش دوم برای کاربران عادی بهینه بود، اما برای کاربرانی که میلیون‌ها فالوئر دارن، باعث افزایش شدید بار روی سیستم می‌شد. بنابراین، توییتر از ترکیب هر دو روش استفاده کرد تا بتونه بهترین عملکرد رو ارائه بده.

ادامه‌ی بحث رو برای بعد می‌ذارم. نمی‌دونم کی میاد، ولی میاد! 😃