مقیاسپذیری: از یک سرور تا بار اوج

«اگر ده برابر شویم چه میشود؟» سؤال خوبی است و معمولاً با جواب اشتباهی روبرو میشود: سرور بزرگتر بخریم.
گاهی همین کافی است. اغلب نه — چون گلوگاه جایی است که کسی اندازهاش نگرفته.
اول اندازه بگیرید، بعد بخرید
قبل از هر تصمیمی، بدانید امروز کجا وقت میرود. یک درخواست معمولی از چه مراحلی رد میشود و هر کدام چقدر طول میکشند؟
بدون این عدد، احتمال زیادی هست که سرور بزرگتر بخرید و هیچ فرقی نکند، چون گلوگاه یک کوئری بدون ایندکس بوده یا یک تماس کند به سرویس بیرونی.
و به میانگین اکتفا نکنید. میانگین زمان پاسخ میتواند خوب باشد در حالی که پنج درصد کاربران تجربهٔ افتضاحی دارند. صدکهای بالا — آن پنج درصد بدترین — چیزی را نشان میدهند که میانگین پنهان میکند.
دو راه بزرگشدن
عمودی: سرور قویتر. ساده، فوری، بدون تغییر کد. تا جایی که سختافزار اجازه میدهد و هزینهاش خطی نیست — سرور دو برابر قویتر معمولاً بیش از دو برابر قیمت دارد.
برای بیشتر سازمانهای ایرانی، این تا مدتها کافی است و باید هم اولین گزینه باشد. پیچیدگی توزیعشده را وقتی بخرید که واقعاً لازم شد.
افقی: سرورهای بیشتر. بیسقفتر و نیازمند اینکه برنامه برایش آماده باشد.
شرط مقیاس افقی: بدون وضعیت
اگر بخواهید چند نسخه از برنامه همزمان اجرا شود، هیچکدام نباید چیزی را فقط برای خودش نگه دارد.
سه چیزی که معمولاً این شرط را میشکنند:
نشست کاربر در حافظهٔ برنامه. کاربری که به سرور دوم میرسد، خارج شده. راهش نگهداشتن نشست در جای مشترک است — Redis یا پایگاه داده.
فایل آپلودشده روی دیسک محلی. فایلی که روی سرور یک ذخیره شده، از سرور دو دیده نمیشود. راهش فضای ذخیرهسازی مشترک است.
کار زمانبندیشده در خود برنامه. اگر سه نسخه بالا باشد، آن گزارش شبانه سه بار ساخته میشود. راهش قفل توزیعشده یا اجرای کار زمانبندی در یک نمونهٔ جدا.
هر سه را میشود از روز اول رعایت کرد و هزینهاش نزدیک صفر است. اصلاحشان بعد از اینکه سامانه در تولید است، خیلی گرانتر.
پایگاه داده، جایی که اول کم میآورد
میشود ده نسخه از برنامه بالا برد. پایگاه داده معمولاً یکی است، و همانجاست که سقف میخورید.
مسیر رایج، به ترتیب هزینه:
ایندکس درست. تقریباً همیشه اولین و مؤثرترین قدم. کوئری کندی که ماهانه هزار بار اجرا میشود، بعد از یک ایندکس درست ممکن است صد برابر سریعتر شود.
کش، برای چیزی که زیاد خوانده و کم عوض میشود. جزئیاتش در استراتژی کش.
نسخهٔ خواندنی. خواندنها به نسخهٔ کپی میروند، نوشتنها به اصلی. برای سامانههایی که خواندنشان از نوشتنشان خیلی بیشتر است — یعنی تقریباً همه — بازده خوبی دارد. قیدش این است که نسخهٔ خواندنی کمی عقب است و باید بدانید کدام پرسشها این عقببودن را تحمل میکنند.
جداکردن داده روی چند پایگاه داده. آخرین گزینه و بهمراتب پیچیدهتر. تا وقتی مجبور نشدهاید سراغش نروید.
بار اوج
بیشتر سامانهها بار یکنواخت ندارند. کمپین فروش، ساعت اوج سفارش غذا، شب پرداخت قبض.
سه ابزاری که کار میکنند:
صف بهعنوان ضربهگیر: درخواستها پذیرفته میشوند و با سرعت قابل تحمل پردازش میشوند. جزئیاتش در صف پیام.
محدودیت نرخ، تا یک مصرفکننده کل ظرفیت را نگیرد.
تنزل تدریجی: در بار اوج، بخشهای غیرحیاتی خاموش شوند. اگر باید انتخاب کنید بین «سایت بالا نمیآید» و «سایت بالاست ولی پیشنهادهای شخصیسازیشده نشان نمیدهد»، دومی را انتخاب کنید. این تصمیم باید از قبل گرفته و پیاده شده باشد، نه در لحظهٔ بحران.
در APT Rides که سامانهٔ تاکسی آنلاین است، همین الگوی بار نامتقارن مسئلهٔ اصلی معماری بود — ساعات اوج شهر با بقیهٔ روز قابل مقایسه نیست.
چقدر جلوتر بروید
بهینهسازی زودهنگام، هزینه و پیچیدگی میآورد بیآنکه چیزی حل کند. و آمادگی صفر، یعنی روزی که رشد آمد، بازنویسی لازم است.
خط میانهای که ما پیشنهاد میکنیم:
از روز اول: برنامه بدون وضعیت باشد، ایندکسها درست باشند، و بشود اندازه گرفت. این سه ارزاناند.
وقتی لازم شد: کش، نسخهٔ خواندنی، صف.
فقط اگر مجبور شدید: تقسیم داده، معماری توزیعشده.
و برای هر عددی که بهعنوان هدف میگیرید، بپرسید از کجا آمده. «باید ده هزار کاربر همزمان را جواب دهد» اگر از تخمین واقعی کسبوکار نیامده باشد، فقط یک هزینهٔ اضافه است که کسی هرگز ازش استفاده نمیکند.