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