طراحی سیستم چیست؟
طراحی سیستم فرایندی است که در آن مشخص میکنیم یک سیستم نرمافزاری چگونه باید ساخته شود تا بتواند نیازهای مشخصی را برآورده کند. این نیازها میتوانند شامل تعداد کاربران، حجم درخواستها، سرعت پاسخگویی، میزان دسترسپذیری و نحوه مدیریت دادهها باشند.
در یک پروژه واقعی، مهندس نرمافزار باید بتواند تصمیم بگیرد چه زمانی از یک Database خاص استفاده کند، چه دادههایی را Cache کند، چگونه ترافیک را بین چند Server تقسیم کند و اگر یکی از سرویسها از کار افتاد، سیستم چگونه به کار خود ادامه دهد.
بنابراین System Design فقط کشیدن چند Diagram نیست؛ بلکه مجموعهای از تصمیمهای مهندسی برای ساخت سیستمی است که در شرایط واقعی بتواند عملکرد قابل قبولی داشته باشد.
چرا یادگیری این مهارت مهم است؟
هرچه یک برنامهنویس از پروژههای کوچک به سمت سیستمهای بزرگتر حرکت میکند، تصمیمهای معماری اهمیت بیشتری پیدا میکنند. ممکن است یک راهحل برای هزار کاربر کاملاً مناسب باشد، اما با رسیدن به میلیونها درخواست در روز دیگر جواب ندهد.
سیستم باید بتواند با افزایش کاربران و درخواستها رشد کند، بدون اینکه عملکرد آن به شکل جدی افت کند.
خرابی یک بخش نباید الزاماً باعث از کار افتادن کل سیستم شود.
معماری مناسب میتواند زمان پاسخگویی و مصرف منابع را به شکل قابل توجهی کاهش دهد.
ساختار مناسب باعث میشود اضافه کردن Featureهای جدید و تغییر بخشهای مختلف سادهتر شود.
اجزای اصلی در طراحی سیستم
برای درک System Design باید با اجزای اصلی یک سیستم نرمافزاری و نحوه ارتباط آنها با یکدیگر آشنا باشید.
Client و Server
Client بخشی است که کاربر با آن تعامل دارد و درخواست را به Server ارسال میکند. Server درخواست را دریافت کرده، منطق مورد نیاز را اجرا میکند و نتیجه را برمیگرداند.
API
API رابطی است که به بخشهای مختلف سیستم اجازه میدهد با یکدیگر ارتباط برقرار کنند. در بسیاری از سیستمهای وب، این ارتباط از طریق HTTP انجام میشود.
برای آشنایی بیشتر با نحوه کار HTTP میتوانید راهنمای MDN درباره HTTP را مطالعه کنید.
Database
Database محل ذخیره و مدیریت دادههای سیستم است. انتخاب بین SQL و NoSQL، نحوه طراحی Schema، Indexها و روش دسترسی به دادهها میتواند تأثیر مستقیمی روی عملکرد سیستم داشته باشد.
Cache
Cache برای نگهداری موقت دادههایی استفاده میشود که دسترسی به آنها زیاد است. استفاده درست از Cache میتواند تعداد درخواستها به Database را کاهش داده و سرعت پاسخگویی را افزایش دهد.
برای مطالعه بیشتر درباره Cache در وب میتوانید به راهنمای HTTP Caching در MDN مراجعه کنید.
Load Balancer
زمانی که یک Server به تنهایی پاسخگوی ترافیک سیستم نیست، میتوان چند Server را در اختیار داشت و درخواستها را بین آنها توزیع کرد. Load Balancer مسئول مدیریت این توزیع است.
Message Queue
در بسیاری از سیستمهای بزرگ، همه کارها لازم نیست به صورت مستقیم و همزمان انجام شوند. Message Queue اجازه میدهد بعضی عملیاتها به شکل Asynchronous پردازش شوند و وابستگی مستقیم بین سرویسها کاهش پیدا کند.
مقیاسپذیری چیست؟
یکی از مهمترین موضوعات در System Design، مقیاسپذیری یا Scalability است. یک سیستم مقیاسپذیر باید بتواند با افزایش بار کاری، کاربران یا دادهها همچنان عملکرد قابل قبولی داشته باشد.
| روش | توضیح |
|---|---|
| Vertical Scaling | افزایش منابع یک Server مانند CPU، RAM یا Storage |
| Horizontal Scaling | اضافه کردن Serverهای بیشتر و توزیع بار بین آنها |
در سیستمهای بزرگ معمولاً Horizontal Scaling اهمیت بیشتری پیدا میکند، چون اضافه کردن Nodeهای جدید میتواند ظرفیت سیستم را افزایش دهد و وابستگی به یک Server را کاهش دهد.
High Availability و Fault Tolerance
یک سیستم واقعی ممکن است هر لحظه با خطا مواجه شود. Server ممکن است از کار بیفتد، Network دچار مشکل شود یا یک Database در دسترس نباشد.
High Availability به این موضوع میپردازد که سیستم تا حد ممکن در دسترس باقی بماند. Fault Tolerance نیز به توانایی سیستم برای ادامه کار در صورت خرابی بخشی از آن مربوط میشود.
برای رسیدن به این اهداف میتوان از تکنیکهایی مانند Replication، Redundancy، Health Check، Failover و طراحی بدون Single Point of Failure استفاده کرد.
فرایند طراحی یک سیستم چگونه است؟
طراحی یک سیستم معمولاً با یک فرایند مشخص انجام میشود. هدف این نیست که از ابتدا تمام جزئیات را مشخص کنیم؛ بلکه باید ابتدا تصویر کلی سیستم را بسازیم و سپس به تدریج جزئیات مهم را بررسی کنیم.
ابتدا باید بدانیم سیستم قرار است چه کاری انجام دهد و کاربران چه انتظاراتی از آن دارند.
تعداد کاربران، تعداد درخواستها، حجم داده و رشد احتمالی سیستم را تخمین میزنیم.
اجزای اصلی مانند Client، API، Server، Database، Cache و Queue را مشخص کرده و نحوه ارتباط آنها را طراحی میکنیم.
بررسی میکنیم کدام بخشها ممکن است در شرایط بار بالا به گلوگاه تبدیل شوند و برای آنها راهحل پیدا میکنیم.
در نهایت بررسی میکنیم اگر هر بخش از سیستم دچار مشکل شد، چه اتفاقی برای سایر قسمتها خواهد افتاد.
یک مثال ساده از طراحی سیستم
فرض کنید قرار است سیستمی طراحی کنیم که کاربران بتوانند فایلهای خود را Upload و با دیگران Share کنند.
در یک معماری ساده، درخواست کاربر ابتدا به Load Balancer میرسد و سپس به یکی از Application Serverها منتقل میشود. اطلاعات مربوط به فایلها میتواند در Database ذخیره شود و خود فایلها در یک Object Storage قرار بگیرند.
اگر سیستم رشد کند، میتوان Cache، CDN، چند Application Server و پردازش Asynchronous برای عملیاتهایی مانند ساخت Thumbnail اضافه کرد.
طراحی سیستم در مصاحبههای شغلی
System Design یکی از موضوعات مهم در مصاحبههای فنی شرکتهای بزرگ، مخصوصاً برای موقعیتهای Senior Software Engineer و نقشهای با تجربهتر است.
در این نوع مصاحبه معمولاً از شما خواسته میشود یک سیستم واقعی را طراحی کنید؛ برای مثال یک سیستم پیامرسان، سرویس اشتراک ویدیو، سیستم پرداخت یا موتور جستوجو.
هدف مصاحبهکننده فقط رسیدن به یک Architecture مشخص نیست. نحوه تحلیل مسئله، پرسیدن سؤالهای درست، تخمین منابع، توضیح Trade-offها و تصمیمگیری در شرایط مختلف اهمیت زیادی دارد.
برای یادگیری طراحی سیستم از کجا شروع کنیم؟
اگر تاکنون با System Design کار نکردهاید، بهتر است به جای حفظ کردن Architectureهای آماده، مفاهیم پایه را به صورت مرحلهای یاد بگیرید.
ابتدا نحوه ارتباط Client و Server، HTTP، DNS و مفاهیم پایه Network را یاد بگیرید.
مفاهیم SQL، NoSQL، Index، Replication و Partitioning را بشناسید.
یاد بگیرید چه زمانی Cache یا Message Queue میتواند به حل یک مشکل معماری کمک کند.
مفاهیمی مانند Load Balancing، Replication، Fault Tolerance و High Availability را بررسی کنید.
در نهایت چند سیستم واقعی را از ابتدا طراحی کنید و برای هر تصمیم معماری، دلیل مشخصی داشته باشید.
تفاوت طراحی سیستم و معماری نرمافزار چیست؟
این دو مفهوم به یکدیگر نزدیک هستند اما دقیقاً یکسان نیستند. Software Architecture بیشتر روی ساختار کلی نرمافزار، مرزبندی اجزا و ارتباط بین بخشهای کد تمرکز دارد؛ در حالی که System Design معمولاً دید وسیعتری نسبت به کل سیستم دارد.
| Software Architecture | System Design |
|---|---|
| تمرکز بیشتر روی ساختار نرمافزار | تمرکز روی کل سیستم و زیرساخت آن |
| Modules و Components | Services، Database، Cache و Network |
| Design Patterns و Code Structure | Scalability، Availability و Reliability |
آیا این مهارت فقط برای برنامهنویسهای Senior است؟
نه. اگرچه System Design در سطوح Senior اهمیت بسیار بیشتری پیدا میکند، یادگیری اصول آن از سطح Junior نیز میتواند دید مهندسی برنامهنویس را بهتر کند.
دانستن اینکه چرا یک سیستم از Cache استفاده میکند، چرا Database باید Index داشته باشد یا چرا یک سرویس به چند Instance تقسیم شده است، باعث میشود برنامهنویس فقط به کد نگاه نکند و تصویر بزرگتر محصول را هم درک کند.
برای یادگیری بهتر چه منابعی وجود دارد؟
جمعبندی
System Design یکی از مهارتهایی است که تفاوت بین صرفاً پیادهسازی یک Feature و فکر کردن مانند یک مهندس نرمافزار را مشخص میکند.
با بزرگتر شدن محصولات، مسائلی مانند مقیاسپذیری، Performance، Availability، مدیریت داده و ارتباط بین سرویسها اهمیت بیشتری پیدا میکنند. یادگیری این مفاهیم به شما کمک میکند هنگام ساخت سیستمهای واقعی، تصمیمهای معماری آگاهانهتری بگیرید.
اگر هدف شما این است که از سطح پیادهسازی Featureها فراتر بروید و درک عمیقتری از نحوه ساخت سیستمهای بزرگ پیدا کنید، یادگیری System Design میتواند یکی از قدمهای مهم مسیر شما باشد.
در دوره طراحی سیستم ایوولرن، مفاهیم مورد نیاز برای تحلیل و طراحی سیستمهای واقعی را به شکل کاربردی یاد میگیرید و با چالشهایی که یک Software Engineer در پروژههای بزرگ با آنها مواجه میشود آشنا میشوید.
مشاهده دورههای ایوولرن