اعدادی که برای مصاحبههای طراحی سیستم باید بدانید
مرور اعداد و محدودیتهای سختافزار مدرن برای کش، پایگاه داده، سرور اپلیکیشن و صف پیام، همراه با زمان مناسب Sharding و اشتباهات رایج در برآورد ظرفیت
اعدادی که باید بدانید
در این فصل اعدادی را مرور میکنیم که برای مصاحبههای طراحی سیستم باید بدانید.
صنعت ما خیلی سریع حرکت میکند. سختافزاری که سیستمها را روی آن میسازیم مدام پیشرفت میکند. برای همین حتی کتابهای درسی چند سال پیش هم زود قدیمی میشوند. کتابی که همین چند سال پیش منتشر شده ممکن است الگوهایی را آموزش بدهد که هنوز درستاند، اما اعدادی را نقل کند که از نظر مرتبه بزرگی با امروز فرق دارند.
یکی از نشانههای بارز کاندیدایی که دانش کتابی دارد اما تجربه عملی ندارد، تکیه بر محدودیتهای قدیمی سختافزار در مصاحبه است. چنین کاندیدایی محاسباتی را با اعداد سال ۲۰۱۵ (یا حتی ۲۰۲۰) انجام میدهد که توان سیستمهای مدرن را بهشدت دستکم میگیرد. نگرانیهایی درباره حجم پایگاه داده، محدودیت حافظه و هزینه ذخیرهسازی میشنوید که در آن زمان منطقی بودند، اما امروز باعث میشوند سیستم بیش از حد مهندسی شود.
این تقصیر کاندیدا نیست. او با مطالعه کار درست را انجام میدهد. اما فهمیدن تواناییهای سختافزار مدرن برای تصمیمهای خوب در طراحی سیستم بسیار مهم است. اینکه کی Sharding کنیم، آیا کش را تهاجمی استفاده کنیم، با اشیای بزرگ چطور کار کنیم، همه به درک دقیق از توان سختافزار امروز بستگی دارد.
بیایید اعدادی را ببینیم که در سال ۲۰۲۵ اهمیت دارند.
محدودیتهای سختافزار مدرن
سرورهای مدرن قدرت پردازشی جدی دارند. یک AWS M6i.32xlarge با ۵۱۲ گیگابایت حافظه و ۱۲۸ vCPU برای بارهای کاری عمومی عرضه میشود. نمونههای بهینه برای حافظه از این هم فراتر میروند. X1e.32xlarge چهار ترابایت RAM دارد و U-24tb1.metal به ۲۴ ترابایت RAM میرسد. این تغییر اهمیت دارد، چون خیلی از برنامههایی که قبلاً به سیستم توزیعشده نیاز داشتند، حالا روی یک ماشین واحد اجرا میشوند.
ظرفیت ذخیرهسازی هم به همین ترتیب رشد کرده است. نمونههای مدرن مثل i3en.24xlarge در AWS تا ۶۰ ترابایت SSD محلی دارند. اگر بیشتر لازم دارید، D3en.12xlarge برای بارهای کاری سنگین ۳۳۶ ترابایت HDD در اختیار میگذارد. ذخیرهسازی شیء (object storage) مثل S3 عملاً نامحدود است و استقرار در مقیاس پتابایت در آن امری معمول است. دوران ذخیرهسازی بهعنوان محدودیت اصلی تقریباً تمام شده است.
قابلیتهای شبکه هم ثابت نماندهاند. در یک دیتاسنتر، ۱۰ گیگابیت بر ثانیه استاندارد است و نمونههای پرکارایی تا ۲۰ گیگابیت بر ثانیه را پشتیبانی میکنند. پهنای باند بین ریجنها معمولاً بین ۱۰۰ مگابیت و ۱ گیگابیت بر ثانیه است. تأخیر قابلپیشبینی میماند، یعنی ۱ تا ۲ میلیثانیه داخل یک ریجن و ۵۰ تا ۱۵۰ میلیثانیه بین ریجنها. این عملکرد ثابت طراحی سیستم توزیعشده قابلاعتماد را ممکن میکند.
اینها فقط بهبود تدریجی نیستند. نشاندهنده جهشی در آنچه ممکن است هستند. وقتی کتابهای درسی از Sharding پایگاه داده در ۱۰۰ گیگابایت یا پرهیز از اشیای بزرگ در حافظه حرف میزنند، بر پایه محدودیتهای قدیمی صحبت میکنند. سختافزاری که امروز سیستمهای ما را اجرا میکند یک دهه پیش قابلتصور نبود و این تواناییها نحوه رویکرد ما به طراحی سیستم را اساساً تغییر میدهد.
استفاده از این اعداد در مصاحبه
ببینیم این اعداد چطور روی اجزای مشخص و تصمیمهایی که هنگام طراحی سیستم در مصاحبه میگیریم اثر میگذارند.
کش و ذخیرهسازی
کشهای درونحافظهای هم در اندازه و هم در توانایی رشد نمایی داشتهاند. دوران Redis با ۳۲ تا ۶۴ گیگابایت، که مدیریت دقیق حافظه و کش کردن بخشی از داده را لازم داشت، گذشته است. کشهای امروزی معمولاً مجموعه دادههای در مقیاس ترابایت را با تأخیر تکرقمی میلیثانیه مدیریت میکنند و یک نمونه میتواند صدها هزار عملیات در ثانیه پردازش کند. این تغییر مقیاس، کل رویکرد به استراتژی کش را عوض میکند.
اعدادی که باید بدانید:
- حافظه: تا ۱ ترابایت در نمونههای بهینه برای حافظه، و در بعضی تنظیمات تخصصی بیشتر.
- تأخیر خواندن: کمتر از ۱ میلیثانیه داخل یک ریجن.
- تأخیر نوشتن: میانگین ۱ تا ۲ میلیثانیه بین ریجنها برای سیستمهای بهینه.
- Throughput خواندن: بیش از ۱۰۰ هزار درخواست در ثانیه برای هر نمونه، در کشهای درونحافظهای مثل ElastiCache Redis روی گرههای مدرن مبتنی بر Graviton.
- Throughput نوشتن: صدها هزار درخواست در ثانیه بهصورت پایدار.
چه زمانی به Sharding فکر کنیم:
- اندازه مجموعه داده: نزدیک به ۱ ترابایت.
- Throughput: بیش از ۱۰۰ هزار عملیات در ثانیه بهصورت پایدار.
- تأخیر خواندن: الزام پایدار کمتر از ۰٫۵ میلیثانیه (اگر از آن فراتر رفت، به Sharding توجه کنید).
این تواناییها استراتژی کش را اساساً تغییر میدهند. میتوانید کل پایگاه داده را حتی در صدها گیگابایت در حافظه کش کنید. یعنی اغلب میتوانید بهطور کامل از طرحهای پیچیده کش جزئی پرهیز کنید. این رویکرد «همهچیز در کش»، با اینکه ظاهراً زور بیظرافت است، معمولاً از هزینه زمان مهندسی که صرف منطق کش انتخابی میشود ارزانتر تمام میشود. وقتی باید مقیاس بگیرید، گلوگاه معمولاً عملیات در ثانیه یا پهنای باند شبکه است، نه اندازه حافظه. این تغییر چند سال پیش قابلتصور نبود.
پایگاههای داده
قدرت خام پایگاههای داده مدرن حتی مهندسان باتجربه را شگفتزده میکند. نمونههای تکی PostgreSQL یا MySQL امروز معمولاً دهها ترابایت داده را با زمان پاسخ در سطح میلیثانیه نگه میدارند. موضوع فقط ذخیرهسازی نیست. پایگاههای داده مدرن دهها هزار تراکنش در ثانیه را روی یک نمونه اصلی (primary) بهخوبی مدیریت میکنند و گلوگاه اغلب نگرانیهای عملیاتی است، نه محدودیت کارایی.
اعدادی که باید بدانید:
- ذخیرهسازی: نمونههای تکی برای بیشتر موتورهای پایگاه داده تا ۶۴ TiB را تحمل میکنند و Aurora در بعضی تنظیمات تا ۱۲۸ TiB را پشتیبانی میکند.
- تأخیر خواندن: ۱ تا ۵ میلیثانیه برای دادههای کششده و ۵ تا ۳۰ میلیثانیه برای داده روی دیسک (در پیکربندیهای بهینه RDS و Aurora).
- تأخیر نوشتن: ۵ تا ۱۵ میلیثانیه برای تأخیر commit (در تنظیمات تکگرهای پرکارایی).
- Throughput خواندن: تا ۵۰ هزار TPS در پیکربندیهای تکگرهای Aurora و RDS.
- Throughput نوشتن: ۱۰ تا ۲۰ هزار TPS در پیکربندیهای تکگرهای Aurora و RDS.
- اتصالها: ۵ تا ۲۰ هزار اتصال همزمان، بسته به پایگاه داده و نوع نمونه.
چه زمانی به Sharding فکر کنیم:
- اندازه مجموعه داده: رسیدن به ۵۰ TiB یا بیشتر ممکن است به راهحلهای Sharding یا توزیعشده نیاز داشته باشد.
- نرخ نوشتن: بیش از ۱۰ هزار TPS پایدار نشانه ملاحظات مقیاسدهی است.
- تأخیر خواندن: نیاز به تأخیر کمتر از ۵ میلیثانیه برای دادههای کشنشده ممکن است به بهینهسازی نیاز داشته باشد.
- توزیع جغرافیایی: نیاز به replication یا توزیع بین ریجنها.
- پشتیبانگیری و بازیابی: پنجرههای پشتیبانگیری که چند ساعت طول میکشند یا از نظر عملیاتی غیرعملی میشوند.
بزرگترین سیستمهای دنیا (شبکههای اجتماعی، غولهای تجارت الکترونیک و مانند آن) برای مدیریت مقیاسشان حتماً به Sharding نیاز دارند، اما بسیاری از کاندیداها خیلی زود سراغ راهحلهای توزیعشده میروند. برای سیستمهایی که میلیونها یا حتی دهها میلیون کاربر دارند، یک پایگاه داده تکی که خوب تنظیم شده باشد اغلب بار را تحمل میکند. وقتی باید مقیاس بگیرید، دقت کنید چه چیزی این تصمیم را پیش میبرد. حجم خالص داده؟ نگرانیهای عملیاتی مثل پنجره پشتیبانگیری؟ یا نیاز به توزیع جغرافیایی؟ فهمیدن این مصالحهها به تصمیمهای بهتر در مقیاسدهی میانجامد.
بیشتر اوقات کاندیداهایی را میبینم که خیلی زود سراغ مقیاسدهی میروند. ۵۰۰ گیگابایت یا چند ترابایت داده دارند و شروع میکنند به توضیح اینکه پایگاه داده را چطور Shard میکنند. سرعتتان را کم کنید، محاسبه را انجام دهید و قبل از توضیح اینکه Sharding را چطور انجام میدهید، مطمئن شوید واقعاً لازم است.
سرورهای اپلیکیشن
سرورهای اپلیکیشن مدرن از محدودیتهای منابعی که بسیاری از الگوهای طراحی سنتی را شکل داده بودند فراتر رفتهاند. سرورهای امروزی معمولاً هزاران اتصال همزمان را با مصرف اندک منابع مدیریت میکنند و پلتفرمهای ابری در پاسخ به بار، مقیاسدهی تقریباً فوری ممکن میکنند. توانایی سرور شما را معمولاً قدرت پردازش CPU تعیین میکند، نه محدودیت حافظه یا اتصال.
اعدادی که باید بدانید:
- اتصالها: بیش از ۱۰۰ هزار اتصال همزمان برای هر نمونه در تنظیمات بهینه.
- CPU: ۸ تا ۶۴ هسته.
- حافظه: استاندارد ۶۴ تا ۵۱۲ گیگابایت و حداکثر تا ۲ ترابایت برای نمونههای پرحافظه.
- شبکه: حداکثر پهنای باند ۲۵ گیگابیت بر ثانیه در تنظیمات سرور مدرن.
- زمان راهاندازی: ۳۰ تا ۶۰ ثانیه برای برنامههای کانتینری.
چه زمانی به Scale کردن فکر کنیم:
- استفاده از CPU: بهطور پایدار بالای ۷۰ تا ۸۰٪.
- تأخیر پاسخ: فراتر از SLA یا آستانه بحرانی.
- مصرف حافظه: روند بالای ۷۰ تا ۸۰٪.
- پهنای باند شبکه: نزدیک به ۲۰ گیگابیت بر ثانیه.
پیامدهای طراحی مهم است. گرایش به سرویسهای stateless برای مقیاسدهی ارزشمند است، اما فراموش نکنید که هر سرور حافظه قابلتوجهی در اختیار دارد. کش محلی، محاسبات درونحافظهای و مدیریت نشست همگی میتوانند از این حافظه برای بهبود چشمگیر کارایی استفاده کنند. CPU تقریباً همیشه اولین گلوگاه شماست، نه حافظه. پس وقتی منطقی است از بهینهسازیهای پرمصرف حافظه پرهیز نکنید. وقتی باید مقیاس بگیرید، پلتفرمهای ابری میتوانند نمونه جدید را در چند ثانیه بسازند و auto-scaling تهاجمی را جایگزین مناسبی برای provision بیش از حد میکنند. ترکیب نمونههای قدرتمند و مقیاسدهی سریع یعنی اغلب میتوانید با معماریهای ساده به کارایی بالا برسید.
صف پیام
صفهای پیام از سیستمهای ساده واگذاری کار به بزرگراههای داده پرکارایی تبدیل شدهاند. سیستمهای مدرنی مثل Kafka میلیونها پیام در ثانیه را با تأخیر تکرقمی میلیثانیه پردازش میکنند و همزمان داده را برای هفتهها یا ماهها نگه میدارند. این ترکیب سرعت و دوام نقش آنها را خیلی فراتر از پردازش ناهمزمان سنتی برده است.
اعدادی که باید بدانید:
- Throughput: حداکثر ۱ میلیون پیام در ثانیه برای هر broker در تنظیمات مدرن.
- تأخیر: ۱ تا ۵ میلیثانیه سرتاسری (end-to-end) داخل یک ریجن در تنظیمات بهینه.
- اندازه پیام: از ۱ کیلوبایت تا ۱۰ مگابایت بهخوبی مدیریت میشود.
- ذخیرهسازی: حداکثر ۵۰ ترابایت برای هر broker در تنظیمات پیشرفته.
- نگهداری (retention): هفتهها تا ماهها داده، بسته به ظرفیت و پیکربندی دیسک.
چه زمانی به Sharding فکر کنیم:
- Throughput: نزدیک به ۸۰۰ هزار پیام در ثانیه برای هر broker.
- تعداد پارتیشن: نزدیک به ۲۰۰ هزار در هر خوشه.
- تأخیر مصرفکننده (consumer lag): رشد مداوم که روی پردازش بلادرنگ اثر میگذارد.
- replication بین ریجنها: اگر افزونگی جغرافیایی لازم باشد.
ویژگیهای کارایی صفهای مدرن مفروضات سنتی طراحی سیستم را به چالش میکشد. با تأخیر ثابت زیر ۵ میلیثانیه، حالا میتوانید از صفها در مسیر درخواستهای همزمان (synchronous) استفاده کنید. مزایای تحویل قابلاعتماد و جداسازی را میگیرید، بدون اینکه APIها را مجبور به ناهمزمان شدن کنید. این سرعت، همراه با ذخیرهسازی تقریباً نامحدود، یعنی صفها میتوانند ستون فقرات الگوهای Event Sourcing، تحلیل بلادرنگ و یکپارچهسازی داده باشند که قبلاً سیستمهای تخصصی میخواستند.
برگه تقلب
این اعداد مرجع سریعی از اعدادی است که در سال ۲۰۲۵ باید بدانید. این مقادیر نمونههای معمول برای سیستمهای خوب تنظیمشده با بار کاری مشخص هستند. نیازهای شما ممکن است بسته به بار کاری، سختافزار و پیکربندی فرق کند. از آنها بهعنوان نقطه شروع برای برنامهریزی ظرفیت و بحثهای طراحی استفاده کنید، نه بهعنوان محدودیت سخت. به یاد داشته باشید که ارائهدهندگان ابری مرتب پیشنهادهایشان را بهروز میکنند. من سعی میکنم این اعداد را بهروز نگه دارم، اما آنها را بیشتر نقطه شروع بدانید تا محدودیت سخت.
| مؤلفه | معیارهای کلیدی | نشانههای نیاز به مقیاسدهی |
|---|---|---|
| کش | تأخیر حدود ۱ میلیثانیه؛ بیش از ۱۰۰ هزار عملیات در ثانیه؛ محدود به حافظه (تا ۱ ترابایت) | نرخ ضربه (hit rate) کمتر از ۸۰٪؛ تأخیر بیش از ۱ میلیثانیه؛ مصرف حافظه بیش از ۸۰٪؛ cache thrashing |
| پایگاه داده | تا ۵۰ هزار TPS؛ تأخیر خواندن کمتر از ۵ میلیثانیه (کششده)؛ ظرفیت تا ۶۴ TiB؛ نوشتن ۱۰ تا ۲۰ هزار TPS | نوشتن بیش از ۱۰ هزار TPS؛ تأخیر خواندن کشنشده بیش از ۵ میلیثانیه؛ نیاز به توزیع جغرافیایی |
| سرور اپلیکیشن | بیش از ۱۰۰ هزار اتصال همزمان؛ ۸ تا ۶۴ هسته؛ ۶۴ تا ۵۱۲ گیگابایت RAM استاندارد و تا ۲ ترابایت | مصرف CPU بیش از ۷۰٪؛ تأخیر پاسخ بیش از SLA؛ اتصالها نزدیک به ۸۰٪ ظرفیت (حدود ۱۰۰ هزار برای هر نمونه) |
| صف پیام | تا ۱ میلیون پیام در ثانیه برای هر broker؛ تأخیر سرتاسری کمتر از ۵ میلیثانیه | نزدیک شدن به ۸۰۰ هزار پیام در ثانیه؛ حدود ۲۰۰ هزار پارتیشن در هر خوشه؛ رشد consumer lag |
اشتباهات رایج در مصاحبه
Sharding زودهنگام
بزرگترین اشتباهی که کاندیداها میکنند این است که فکر میکنند Sharding همیشه لازم است. یک مدل داده معرفی میکنند و بلافاصله توضیح میدهند روی کدام ستون Shard میکنند. این اشتباه تقریباً هر بار در طراحی Yelp ظاهر میشود. آنجا ۱۰ میلیون کسبوکار داریم که هرکدام حدود ۱ کیلوبایت داده دارند. یعنی ۱۰ میلیون × ۱ کیلوبایت = ۱۰ گیگابایت داده! حتی اگر نقدها را هم حساب کنیم و ۱۰ برابرش کنیم، میشود ۱۰۰ گیگابایت که در یک پایگاه داده جا میشود. پس چرا باید Shard کنید؟
همین اشتباه درباره کش هم زیاد پیش میآید. لیدربورد LeetCode را در نظر بگیرید که ۱۰۰ هزار مسابقه دارد و در هر مسابقه حداکثر ۱۰۰ هزار کاربر. محاسبه میشود ۱۰۰ هزار × ۱۰۰ هزار × (۳۶ بایت شناسه + ۴ بایت عدد اعشاری برای امتیاز) = ۴۰۰ گیگابایت. این از چیزی که در Yelp روی دیسک ذخیره میکنیم هم بیشتر است، اما باز هم در یک کش بزرگ جا میشود و نیازی به Sharding نیست.
بیشبرآورد تأخیر
این را بیشتر درباره SSD میبینم. کاندیداها تأخیر اضافهای را که برای جستجوی کلید یا سطر ساده در SSD (پایگاه داده) لازم است بیش از حد برآورد میکنند. حدود ۱۰ میلیثانیه یا بیشتر. این سریع است! وقتی جستجوی ساده سطر بهاندازه کافی سریع است، لازم نیست زیرساخت اضافه بگذارید.
توجه کنید که این فقط درباره جستجوی سطر ساده با ایندکس صدق میکند. هنوز هم کش کردن کوئریهای سنگین عاقلانه است.
مهندسی بیش از حد برای نوشتن زیاد
مثل مورد بالا، برآورد نادرست معمولاً به مهندسی بیش از حد میانجامد. سیستمی با ۵ هزار نوشتن در ثانیه را تصور کنید. کاندیداها اغلب فوراً یک Message Queue اضافه میکنند تا این ظرفیت نوشتن «بالا» را بافر کنند. ولی لازم نیست!
بیایید این را در مقیاس درست ببینیم. یک نمونه Postgres که خوب تنظیم شده باشد میتواند با نوشتنهای ساده بیش از ۲۰ هزار نوشتن در ثانیه را مدیریت کند. چیزی که واقعاً ظرفیت نوشتن را محدود میکند، مواردی مثل اینهاست.
- تراکنشهای پیچیده که چند جدول را درگیر میکنند.
- write amplification ناشی از ایندکسهای زیاد.
- نوشتنهایی که بهروزرسانیهای آبشاری پرهزینه راه میاندازند.
- خواندن همزمان سنگین که با نوشتن رقابت میکند.
اگر فقط سطر درج میکنید یا بهروزرسانی ساده با ایندکس مناسب انجام میدهید، در ۵ هزار نوشتن در ثانیه دیگر نیازی به سیستمهای صف پیچیده نیست.
صفهای پیام وقتی ارزشمند میشوند که به تحویل تضمینشده در برابر خرابی سرویسهای پاییندست نیاز دارید، الگوهای Event Sourcing دارید، موجهای نوشتن بالاتر از ۵۰ هزار نوشتن در ثانیه را مدیریت میکنید، یا میخواهید تولیدکنندهها را از مصرفکنندهها جدا کنید. اما پیچیدگی اضافه میکنند و باید با الزامات واقعی توجیه شوند. قبل از رفتن سراغ Message Queue، بهینهسازیهای سادهتر را در نظر بگیرید، مثل نوشتن دستهای (batch)، بهینهسازی schema و ایندکسها، استفاده مؤثر از connection pooling، یا استفاده از commit ناهمزمان برای نوشتنهای غیر بحرانی.
نکته اصلی این است که قبل از اضافه کردن پیچیدگی به زیرساخت، الگوها و الزامات واقعی نوشتن را بفهمید. پایگاههای داده مدرن فوقالعاده توانمندند و راهحلهای ساده اغلب بهتر از انتظار شما جواب میدهند.
جمعبندی
تواناییهای سختافزار مدرن محاسبات طراحی سیستم را اساساً عوض کرده است. سیستمهای توزیعشده و مقیاس افقی برای بزرگترین کاربردهای دنیا ضروریاند، اما بسیاری از سیستمها میتوانند بسیار سادهتر از چیزی باشند که حکمت سنتی پیشنهاد میکند.
فهمیدن این اعداد به شما کمک میکند تصمیمهای مقیاسدهی بهتری بگیرید.
- پایگاههای داده تکی میتوانند ترابایتها داده را مدیریت کنند.
- کشها میتوانند کل مجموعه داده را در حافظه نگه دارند.
- صفهای پیام برای جریانهای همزمان بهاندازه کافی سریعاند (تا وقتی که backlog ندارند!).
- سرورهای اپلیکیشن حافظه کافی برای بهینهسازی محلی قابلتوجه دارند.
بینش کلیدی این نیست که مقیاس عمودی همیشه راهحل است، بلکه این است که محدودیتهای واقعی را بدانید. این دانش کمک میکند از بهینهسازی زودهنگام پرهیز کنید و سیستمهای سادهتری بسازید که بتوانند با نیازهای شما رشد کنند. در مصاحبههای طراحی سیستم، نشان دادن این درک نشان میدهد که میتوانید دانش نظری را با تجربه عملی متعادل کنید. این مهارت بهویژه برای سطوح بالاتر بسیار مهم است.