
پایگاه داده MongoDB یکی از محبوبترین و قدرتمندترین دیتابیسهای داده NoSQL در دنیای امروز به شمار میرود که به دلیل انعطافپذیری، مقیاسپذیری و عملکرد بالای خود، به انتخابی ایدهآل برای توسعهدهندگان برنامههای کاربردی مدرن تبدیل شده است. این پایگاه داده که در دستهی پایگاههای داده سند-گرا (Document-Oriented) قرار میگیرد، به جای استفاده از ساختار جدولی سنتی و روابط ثابت که در پایگاههای داده رابطهای (SQL) مانند MySQL و PostgreSQL مرسوم است، از اسنادی با فرمت JSON-like به نام BSON (Binary JSON) برای ذخیرهسازی دادهها بهره میبرد. این رویکرد نوآورانه، محدودیتهای مدل رابطهای را از میان برداشته و به توسعهدهندگان اجازه میدهد تا دادهها را به شکلی طبیعیتر و نزدیکتر به ساختار اشیاء در کدنویسی، ذخیره و بازیابی کنند.
یکی از کلیدیترین مزایای MongoDB، شمای پویا (Dynamic Schema) آن است. در پایگاههای داده SQL، ساختار جداول و ستونها باید از پیش به طور دقیق تعریف شود و هرگونه تغییر در این ساختار میتواند فرآیندی پیچیده و زمانبر باشد. در مقابل، MongoDB به اسناد موجود در یک کالکشن (Collection) – که معادل جدول در دنیای SQL است – اجازه میدهد تا ساختارهای متفاوتی داشته باشند. این انعطافپذیری فوقالعاده به تیمهای توسعه این امکان را میدهد که به سرعت و به صورت چابک، ساختار دادههای خود را همگام با تکامل نیازمندیهای برنامه تغییر دهند، بدون آنکه نیاز به اعمال تغییرات ساختاری پیچیده در سطح پایگاه داده داشته باشند. این ویژگی به خصوص در مراحل اولیه توسعه و در پروژههایی که با نیازمندیهای نامشخص و در حال تغییر روبرو هستند، بسیار ارزشمند است.
مونگو دیبی از ابتدا با هدف مقیاسپذیری افقی (Horizontal Scaling) طراحی شده است. در حالی که پایگاههای داده رابطهای معمولاً به صورت عمودی (با افزایش منابع سختافزاری سرور) مقیاسپذیر میشوند، MongoDB از طریق فرآیندی به نام شاردینگ (Sharding)، دادهها را بر روی چندین سرور توزیع میکند. این معماری توزیعشده به MongoDB اجازه میدهد تا حجم عظیمی از دادهها و درخواستها را مدیریت کند و با افزودن سرورهای بیشتر به خوشه (Cluster)، به سادگی و به صورت خطی مقیاسپذیر شود. این قابلیت، آن را به گزینهای ایدهآل برای برنامههای کاربردی بزرگمقیاس، کلاندادهها (Big Data) و برنامههایی با نرخ رشد سریع تبدیل کرده است. علاوه بر شاردینگ، MongoDB با پشتیبانی از مجموعههای کپی (Replica Sets)، دسترسیپذیری بالا (High Availability) و پایداری دادهها را تضمین میکند. در یک مجموعه کپی، چندین نسخه از دادهها بر روی سرورهای مختلف نگهداری میشود و در صورت از کار افتادن سرور اصلی (Primary)، یکی از سرورهای پشتیبان (Secondary) به طور خودکار جایگزین آن شده و از توقف سرویس جلوگیری میکند.
انعطافپذیری و قدرت MongoDB آن را برای طیف گستردهای از کاربردها مناسب ساخته است. از جمله موارد استفاده رایج میتوان به مدیریت محتوا، کاتالوگ محصولات در فروشگاههای آنلاین، اینترنت اشیاء (IoT)، اپلیکیشنهای موبایل، بازیهای آنلاین، تحلیل دادههای حجیم و ذخیرهسازی اطلاعات پروفایل کاربران در شبکههای اجتماعی اشاره کرد. زبان پرسوجوی غنی و قدرتمند MongoDB (MongoDB Query Language – MQL)، به توسعهدهندگان اجازه میدهد تا پرسوجوهای پیچیده و جستجوهای متنی و جغرافیایی را به سادگی اجرا کنند.
علاوه بر این، MongoDB دارای یک اکوسیستم جامع و رو به رشد است که شامل درایورهای رسمی برای تمام زبانهای برنامهنویسی محبوب (مانند Python، Java، Node.js، C# و Go)، ابزارهای مدیریتی و نظارتی پیشرفته مانند MongoDB Compass (یک رابط کاربری گرافیکی) و MongoDB Atlas (سرویس پایگاه داده ابری کاملاً مدیریتشده) میشود. این اکوسیستم قدرتمند، فرآیند توسعه، استقرار و مدیریت برنامههای مبتنی بر مونگو دیبی را به مراتب سادهتر و کارآمدتر میسازد و به توسعهدهندگان کمک میکند تا با تمرکز بر منطق اصلی برنامه، محصولات نوآورانهای را در زمانی کوتاهتر به بازار عرضه کنند. در مجموع، مونگو دیبی با ارائه ترکیبی از انعطافپذیری مدل داده، مقیاسپذیری افقی و اکوسیستم غنی، خود را به عنوان یک تکنولوژی بنیادین در معماری نرمافزارهای مدرن تثبیت کرده است. در ادامه با ما در اکتوبیت همراه باشید تا به بررسی قابلیت Replica Sets در این دیتابیس محبوب بپردازیم و High Availability را برای آن تامین نماییم.
در زیر میتوانید پادکست صوتی این مقاله را به صورت خلاصه بشنوید:
فهرست مطالب
مفهوم Replica Sets در MongoDB و اهمیت آن در کلاسترینگ
یک Replica Set در MongoDB گروهی از فرآیندهای سرور mongod است که مجموعه داده یکسانی را نگهداری میکنند. هدف اصلی از ایجاد یک Replica Set، افزایش دسترسیپذیری (High Availability) و تضمین پایداری دادهها (Data Redundancy) است. در یک Replica Set، گرهها (Nodes) یا سرورهای مختلفی وجود دارند که به دو دسته اصلی تقسیم میشوند:
۱. گره اصلی (Primary): در هر لحظه، فقط یک گره اصلی در Replica Set وجود دارد. این گره تمام عملیات نوشتن (Write Operations) مانند insert ،update و delete را دریافت و پردازش میکند. گره اصلی تغییرات را در لاگ عملیات خود (oplog) ثبت کرده و سپس این تغییرات را به تمام گرههای دیگر ارسال میکند.
۲. گرههای ثانویه (Secondary): یک یا چند گره ثانویه در Replica Set وجود دارند. این گرهها به طور مداوم لاگ عملیات (oplog) را از گره اصلی کپی کرده و همان عملیات را بر روی مجموعه داده خود اعمال میکنند. به این ترتیب، آنها یک کپی بهروز و همگامسازی شده از دادههای گره اصلی را نگهداری میکنند. به طور پیشفرض، عملیات خواندن (Read Operations) نیز از گره اصلی انجام میشود، اما میتوان MongoDB را طوری پیکربندی کرد که خواندن دادهها از گرههای ثانویه نیز امکانپذیر باشد. این کار به توزیع بار خواندن و افزایش کارایی کمک میکند.
کلاسترینگ در MongoDB معمولاً با دو هدف اصلی انجام میشود: افزایش دسترسیپذیری و مقیاسپذیری افقی (Horizontal Scaling). Replica Sets ستون فقرات دسترسیپذیری بالا در یک کلاستر MongoDB هستند. اهمیت آنها در موارد زیر خلاصه میشود:
۱. دسترسیپذیری بالا و Failover خودکار (High Availability & Automatic Failover)
این مهمترین مزیت استفاده از Replica Sets است. اگر گره اصلی (Primary) به هر دلیلی از کار بیفتد (مثلاً به دلیل نقص سختافزاری، مشکل شبکه یا قطعی برق)، Replica Set به طور خودکار یک انتخابات (Election) برگزار میکند.
فرآیند انتخابات: گرههای ثانویه باقیمانده با یکدیگر ارتباط برقرار کرده و یکی از خودشان را که بهروزترین دادهها را دارد، به عنوان گره اصلی جدید انتخاب میکنند.
تداوم سرویس: این فرآیند Failover (جایگزینی خودکار) معمولاً در عرض چند ثانیه تکمیل میشود. در این مدت کوتاه، عملیات نوشتن ممکن است متوقف شود، اما پس از انتخاب گره اصلی جدید، کلاستر دوباره به طور کامل عملیاتی شده و برنامه میتواند به کار خود ادامه دهد.
نتیجه: به لطف این مکانیزم، سیستم شما در برابر خرابیهای نقطهای (Single Point of Failure) مقاوم میشود و برنامه شما تقریباً بدون وقفه به کار خود ادامه میدهد.
۲. پایداری و افزونگی دادهها (Data Redundancy & Durability)
از آنجایی که نسخههای متعددی از دادهها بر روی سرورهای مستقل و مجزا (که میتوانند در موقعیتهای جغرافیایی مختلفی باشند) نگهداری میشوند، خطر از دست رفتن دادهها به شدت کاهش مییابد. اگر یک سرور به طور کامل از بین برود، دادهها همچنان بر روی سرورهای دیگر امن و در دسترس هستند. این افزونگی، پایداری و اطمینان از حفظ دادهها را تضمین میکند.
۳. توزیع بار خواندن (Read Scaling)
در برنامههایی که حجم عملیات خواندن بسیار بالاست (Read-Heavy Applications)، میتوان با پیکربندی درایور MongoDB، بخشی یا تمام درخواستهای خواندن را به گرههای ثانویه هدایت کرد. این کار فشار را از روی گره اصلی برداشته و به بهبود عملکرد کلی و افزایش توان عملیاتی (Throughput) سیستم کمک شایانی میکند.
۴. پشتیبانگیری بدون توقف سرویس (Zero-Downtime Backups)
برای تهیه نسخه پشتیبان از دادهها، نیازی به متوقف کردن گره اصلی نیست. شما میتوانید به سادگی از یکی از گرههای ثانویه یک نسخه پشتیبان کامل تهیه کنید، در حالی که گره اصلی همچنان به درخواستهای نوشتن و خواندن برنامه سرویس میدهد. این کار تضمین میکند که فرآیند پشتیبانگیری هیچ تأثیری بر عملکرد زنده سیستم شما نخواهد داشت.
ارتباط Replica Sets با Sharding
در یک کلاستر MongoDB بزرگ و مقیاسپذیر، معمولاً از ترکیب Replica Sets و Sharding (شاردینگ) استفاده میشود. Sharding فرآیند توزیع دادهها بین چندین سرور یا کلاستر برای مقیاسپذیری افقی است. در چنین معماری، هر Shard (هر بخش از دادههای توزیعشده) خود یک Replica Set مجزا است.
این ترکیب قدرتمند به شما اجازه میدهد تا همزمان از مزایای هر دو بهرهمند شوید:
Sharding: مدیریت حجم عظیمی از دادهها و توزیع بار نوشتن.
Replica Sets: تضمین دسترسیپذیری بالا و پایداری برای هر بخش (Shard) از دادهها.
بررسی سناریوهای راه اندازی کلاسترینگ در MongoDB
این موضوع به یکی از مهمترین جنبههای عملیاتی و معماری در MongoDB میپردازد. انتخاب سناریوی مناسب برای راهاندازی Replica Set به فاکتورهایی مانند بودجه، میزان حساسیت به قطعی سرویس (Availability) و نیاز به پایداری دادهها (Data Redundancy) بستگی دارد.
اساس کار Replica Set بر مفهوم “اکثریت قاطع” (Strict Majority) برای برگزاری انتخابات و انتخاب گره اصلی (Primary) استوار است. یک کلاستر برای اینکه بتواند گره اصلی جدیدی انتخاب کند، باید اکثریت گرههایش فعال و در دسترس باشند. فرمول این است: `(N / 2) + 1` که `N` تعداد کل گرههای رأیدهنده در کلاستر است. این قانون، اساس تمام سناریوهای زیر است.
در ادامه، سناریوهای رایج برای راهاندازی Replica Sets بر اساس تعداد سرویسها (گرهها یا Nodes) توضیح داده میشود:
سناریو ۱: حداقل پیکربندی استاندارد و پیشنهادی (۳ عضو)
این رایجترین، سادهترین و در اکثر موارد، بهترین نقطه برای شروع است.
تعداد سرویسها: ۳ عدد سرویس mongod.
معماری:
۱ گره اصلی (Primary)
۲ گره ثانویه (Secondary)
نحوه عملکرد:
در حالت عادی، یک گره Primary است و دو گره دیگر Secondary هستند و دادهها را از آن کپی میکنند.
تحملپذیری خطا (Fault Tolerance): این پیکربندی میتواند خرابی ۱ گره را تحمل کند. اگر یکی از گرهها (چه Primary و چه Secondary) از کار بیفتد، دو گره باقیمانده همچنان “اکثریت” (۲ از ۳) را تشکیل میدهند و میتوانند یک گره اصلی جدید انتخاب کنند و کلاستر به کار خود ادامه دهد.
اگر ۲ گره همزمان از کار بیفتند، گره باقیمانده به حالت فقط-خواندنی (Read-Only) میرود زیرا نمیتواند اکثریت را برای انتخاب Primary جدید به دست آورد.
مزایا:
بهترین تعادل بین هزینه و دسترسیپذیری.
هم دسترسیپذیری بالا (High Availability) و هم پایداری دادهها (Data Redundancy) را فراهم میکند.
چه زمانی استفاده شود؟ این پیکربندی برای تقریبا تمام برنامههای کاربردی در محیط عملیاتی (Production) که به دسترسیپذیری بالا نیاز دارند، توصیه میشود.
سناریو ۲: پیکربندی با دو عضو داده و یک گره داور (Arbitrator)
این سناریو برای شرایطی است که محدودیت بودجه یا منابع سختافزاری وجود دارد.
تعداد سرویسها: ۳ عدد (۲ سرویس mongod کامل + ۱ سرویس mongod به عنوان داور).
معماری:
۱ گره اصلی (Primary)
۱ گره ثانویه (Secondary)
۱ گره داور (Arbitrator)
گره داور چیست؟ یک فرآیند بسیار سبک mongod است که هیچ دادهای را ذخیره نمیکند. تنها وظیفه آن شرکت در انتخابات برای شکستن رأی مساوی و کمک به رسیدن به اکثریت است.
نحوه عملکرد:
اگر گره اصلی از کار بیفتد، گره ثانویه و گره داور با هم “اکثریت” (۲ از ۳ رأی) را تشکیل میدهند و گره ثانویه به عنوان اصلی جدید انتخاب میشود.
تحملپذیری خطا: این پیکربندی همچنان میتواند خرابی ۱ گره داده را تحمل کند و سرویسدهی را ادامه دهد.
معایب بزرگ:
عدم پایداری داده (No Data Redundancy): اگر گره اصلی خراب شود و گره داور به گره ثانویه کمک کند تا اصلی شود، شما دیگر هیچ کپی پشتیبانی از دادههای خود ندارید تا زمانی که گره خراب شده به مدار بازگردد. اگر در این فاصله گره اصلی جدید هم خراب شود، تمام دادهها از دست میرود.
سناریو ۳: افزایش تحملپذیری خطا (۵ عضو یا بیشتر)
برای سیستمهای بسیار حیاتی که حتی خرابی همزمان چند گره نیز باید مدیریت شود.
تعداد سرویسها: ۵ عدد سرویس mongod (یا هر عدد فرد دیگر مانند ۷، ۹ و …).
معماری:
۱ گره اصلی (Primary)
۴ گره ثانویه (Secondary)
نحوه عملکرد:
برای انتخاب یک Primary جدید، حداقل ۳ گره از ۵ گره (`(۵/۲)+۱ = 3`) باید در دسترس باشند.
تحملپذیری خطا: این پیکربندی میتواند خرابی همزمان ۲ گره را تحمل کند.
مزایا:
سطح بسیار بالایی از دسترسیپذیری و پایداری دادهها.
ایدهآل برای توزیع جغرافیایی در چند مرکز داده (Data Center).
معایب:
هزینه سختافزاری و مدیریت بالاتر.
ترافیک شبکه بیشتر برای همگامسازی دادهها بین گرهها.
چه زمانی استفاده شود؟ برای برنامههای کاربردی بسیار بزرگ و حیاتی (Mission-Critical) مانند سیستمهای مالی، مخابراتی یا سرویسهایی که باید در سطح جهانی و در مقابل فجایع منطقهای (Disaster Recovery) مقاوم باشند.
سناریوهای خاص و پیشرفته
علاوه بر تعداد، نقش گرهها نیز میتواند سناریوهای مختلفی ایجاد کند:
۱. Replica Set توزیعشده جغرافیایی (Geo-Distributed):
هدف: مقاومت در برابر قطعی کامل یک مرکز داده.
مثال: یک کلاستر ۳ عضوی که ۱ عضو در مرکز داده A (مثلاً افرانت)، عضو دوم در مرکز داده B (مثلاً پیشگامان) و عضو سوم (که میتواند یک داور باشد) در مرکز داده C (مثلاً آسیاتک) قرار دارد. در صورت قطعی کامل مرکز داده A، دو عضو دیگر میتوانند به کار ادامه دهند.
۲. استفاده از گرههای مخفی (Hidden Members):
گرههایی که بخشی از Replica Set هستند و دادهها را کپی میکنند، اما برای برنامههای کاربردی قابل مشاهده نیستند و هرگز نمیتوانند Primary شوند.
کاربرد: برای کارهای تحلیلی (Analytics) یا گزارشگیری که نباید بار آنها بر عملکرد گرههای اصلی و ثانویه تأثیر بگذارد.
۳. استفاده از گرههای تاخیری (Delayed Members):
یک کپی از دادهها را با تأخیر عمدی (مثلاً ۱ ساعت) نگهداری میکنند.
کاربرد: برای بازیابی سریع از خطاهای انسانی، مانند حذف تصادفی یک دیتابیس یا کالکشن. میتوان قبل از اینکه حذف به این گره برسد، دادهها را از آن بازیابی کرد.
راه اندازی کلاستر MongoDB با ۳ عضو در سیستم عامل Ubuntu
در ادامه، راهنمای کامل و گامبهگام راهاندازی یک کلاستر MongoDB Replica Set سه عضوی در سیستمعامل Ubuntu ارائه میشود. این معماری شامل دو گره حامل داده (یک Primary و یک Secondary) و یک گره داور (Arbitrator) خواهد بود.
معماری و پیشنیازها
هدف: ساخت یک کلاستر با دسترسیپذیری بالا (High Availability) که در صورت از کار افتادن سرور اصلی، به صورت خودکار به کار خود ادامه دهد.
پیشنیازها:
۱. سه سرور مجزا با سیستمعامل Ubuntu: این سرورها میتوانند ماشینهای فیزیکی، ماشینهای مجازی (VMs) یا حتی کانتینرهای داکر باشند.
Node 1 (Data): سرور اول برای گره اصلی/ثانویه.
Node 2 (Data): سرور دوم برای گره اصلی/ثانویه.
Node 3 (Arbitrator): سرور سوم برای گره داور.
۲. دسترسی sudoدر هر سه سرور.
۳. آدرس IP ثابت و خصوصی برای هر سرور. فرض میکنیم آدرسها به شکل زیر هستند (شما باید آدرسهای IP واقعی خود را جایگزین کنید):
- ۱۹۲.۱۶۸.۱.۱۰۱ (Node 1)
- ۱۹۲.۱۶۸.۱.۱۰۲ (Node 2)
- ۱۹۲.۱۶۸.۱.۱۰۳ (Node 3 – Arbitrator)
۴. اتصال شبکه بین سه سرور برقرار باشد.
مرحله ۱: نصب MongoDB (در هر سه سرور)
این مرحله باید بر روی تمام سه سرور (Node 1, Node 2, و Node 3) انجام شود. برای اطمینان از نصب آخرین نسخه رسمی، از مخزن خود MongoDB استفاده میکنیم.
#apt-get update
#apt-get install -y gnupg curl
#curl -fsSL https://www.mongodb.org/static/pgp/server-8.0.asc | sudo gpg -o /usr/share/keyrings/mongodb-server-8.0.gpg --dearmor
ایجاد فایل لیست منابع برای MongoDB
#echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg ] https://repo.mongodb.org/apt/ubuntu $(lsb_release -cs)/mongodb-org/8.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list
بهروزرسانی پکیجها و نصب MongoDB
#apt update
#apt install -y mongodb-org
فعالسازی و اجرای سرویس MongoDB
#systemctl start mongod
#systemctl enable mongod
#systemctl status mongod
مرحله ۲: پیکربندی شبکه و فایروال (در هر سه سرور)
به طور پیشفرض، MongoDB فقط به اتصالات از localhost (127.0.0.1) گوش میدهد. ما باید این تنظیم را تغییر دهیم تا سرورها بتوانند با یکدیگر ارتباط برقرار کنند.
۱. ویرایش فایل پیکربندی MongoDB: فایل mongod.conf را با یک ویرایشگر متن مانند vim باز کنید.
#vim /etc/mongod.conf
۲. تغییر bindIp: بخش net را پیدا کرده و آدرس `ip` را از `۱۲۷.۰.۰.۱` به `۰.۰.۰.۰` تغییر دهید تا به تمام رابطهای شبکه گوش دهد.
# network interfaces
net:
port: 27017
bindIp: 0.0.0.0
نکته امنیتی: استفاده از `۰.۰.۰.۰` سرور شما را در دسترس تمام شبکهها قرار میدهد. در یک محیط عملیاتی واقعی، بهتر است لیستی از آدرسهای IP سرورهای کلاستر را وارد کنید (مثال: `bindIp: 127.0.0.1,192.168.1.101`).
۳. باز کردن پورت در فایروال (UFW): مطمئن شوید که پورت `۲۷۰۱۷` برای ارتباط بین سرورها باز است.
# اجازه دادن به ترافیک از طرف هر سرور دیگر در کلاستر
#ufw allow from 192.168.1.101 to any port 27017
#ufw allow from 192.168.1.102 to any port 27017
#ufw allow from 192.168.1.103 to any port 27017
فعالسازی فایروال در صورت غیرفعال بودن
#ufw enable
این دستورات را در هر سه سرور اجرا کنید.
مرحله ۳: فعالسازی و نامگذاری Replica Set (در هر سه سرور)
حالا باید به هر عضو بگوییم که بخشی از یک Replica Set است.
۱. ویرایش فایل mongod.conf:
دوباره فایل پیکربندی را باز کنید.
#vim /etc/mongod.conf
۲. افزودن بخش replication:
بخش replication را از حالت کامنت خارج کرده و یک نام برای Replica Set خود انتخاب کنید. این نام باید در هر سه سرور یکسان باشد. ما از نام `myReplicaSet` استفاده میکنیم.
replication:
replSetName: “myReplicaSet”
۳. راهاندازی مجدد سرویس MongoDB:
پس از ذخیره تغییرات، سرویس MongoDB را در هر سه سرور ریاستارت کنید تا با پیکربندی جدید اجرا شود.
#systemctl restart mongod
مرحله ۴: مقداردهی اولیه Replica Set و افزودن اعضا (فقط در یک سرور)
این مرحله حساسترین بخش کار است و فقط از طریق یکی از گرههای حامل داده (مثلاً Node 1) انجام میشود.
۱. اتصال به MongoDB:
در سرور Node 1 (192.168.1.101)، به شل MongoDB متصل شوید.
#mongosh
۲. ایجاد آبجکت پیکربندی:
یک آبجکت جاوااسکریپت برای مقداردهی اولیه Replica Set ایجاد کنید. در این مرحله فقط عضو اول را معرفی میکنیم.
rs.initiate({
_id: “myReplicaSet”,
members: [
{ _id: 0, host: “192.168.1.101:27017” }
] })
اگر همه چیز درست باشد، خروجی `{“ok”: 1}` را مشاهده خواهید کرد و پرامپت شل شما به گزینه زیر تغییر میکند.
myReplicaSet:PRIMARY>
۳. افزودن گره دوم (Data Node):
حالا گره دوم (سرور `۱۹۲.۱۶۸.۱.۱۰۲`) را به عنوان یک عضو حامل داده به مجموعه اضافه کنید.
rs.add("192.168.1.102:27017")
۴. افزودن گره سوم به عنوان داور (Arbitrator):
در نهایت، گره سوم (سرور `۱۹۲.۱۶۸.۱.۱۰۳`) را با استفاده از دستور `rs.addArb()` به عنوان داور اضافه کنید.
rs.addArb("192.168.1.103:27017")
اگر در مرحله چهار خطای NewReplicaSetConfigurationIncompatible را دریافت کردید نگران نباشید، این یک مکانیزم ایمنی است تا اطمینان حاصل شود که شما از رفتار توپولوژی جدید کلاستر خود آگاه هستید. از آنجایی که این تغییر به طور قابل توجهی رفتار کلاستر را عوض میکند، MongoDB شما را ملزم میکند که قبل از اعمال این تغییر، یک سیاست تایید نوشتن (Write Concern) پیشفرض برای کل کلاستر تعیین کنید. دستور زیر را بزنید و سپس دستور قبلی را مجدد اجرا کنید:
db.adminCommand({
setDefaultRWConcern: 1,
defaultWriteConcern: { w: "majority" },
writeConcern: { w: "majority", wtimeout: 60000 }
})
مرحله ۵: بررسی و تأیید وضعیت کلاستر
برای اطمینان از اینکه کلاستر به درستی پیکربندی شده است، دستور زیر را در شل MongoDB اجرا کنید:
rs.status()
شما باید یک خروجی طولانی دریافت کنید که وضعیت هر سه عضو را نشان میدهد. به بخش `members` دقت کنید، باید چیزی شبیه به این باشد:
{
“members”: [
{
“_id”: 0,
“host”: “192.168.1.101:27017”,
// …
“stateStr”: “PRIMARY”,
// …
},
{
“_id”: 1,
“host”: “192.168.1.102:27017”,
// …
“stateStr”: “SECONDARY”,
// …
},
{
“_id”: 2,
“host”: “192.168.1.103:27017”,
// …
“stateStr”: “ARBITRATOR”,
// …
}
],
// …
}
اگر `stateStr` برای گرهها به ترتیب `PRIMARY`، `SECONDARY` و `ARBITRATOR` باشد، کلاستر شما با موفقیت راهاندازی شده است.
در صورتی که دیتابیس اصلی شما دیتا دارد و باید با بقیه sync کند، میتوانید از دستور زیر برای بررسی روند sync استفاده کنید:
rs.printSecondaryReplicationInfo()
تست Failover (اختیاری ولی پیشنهادی)
برای تست عملکرد Failover، سرویس MongoDB را در گره `PRIMARY` (Node 1) متوقف کنید:
# در ترمینال سرور ۱۹۲.۱۶۸.۱.۱۰۱ اجرا کنید
#systemctl stop mongod
چند ثانیه صبر کنید. سپس به شل MongoDB در Node 2 (`192.168.1.102`) متصل شوید و دستور `rs.status()` را اجرا کنید. خواهید دید که Node 2 اکنون به `PRIMARY` تبدیل شده است. این نشان میدهد که فرآیند Failover خودکار به درستی کار میکند.
امنیت MongoDB در کلاستر
اعضای Replica Set (گرههای Primary, Secondary, Arbiter) باید بتوانند پس از فعالسازی امنیت، با یکدیگر ارتباط برقرار کرده و یکدیگر را احراز هویت کنند. این کار با یک Keyfile انجام میشود.
ایجاد Keyfile برای ارتباط داخلی کلاستر (فقط در یک سرور)
Keyfile یک فایل حاوی یک رمز مشترک است که تمام اعضای کلاستر از آن برای اعتماد به یکدیگر استفاده میکنند. در یکی از سرورها (مثلاً سرور Primary)، دستور زیر را برای ایجاد یک Keyfile با محتوای تصادفی اجرا کنید.
#mkdir -p /opt/mongo
#openssl rand -base64 756 > /opt/mongo/mongodb.key
#chmod 400 /opt/mongo/mongodb.key
#chown mongodb:mongodb /opt/mongo/mongodb.key
فایل کلیدی که در مرحله قبل ساختید، باید دقیقا با همان محتوا، در همان مسیر و با همان دسترسیها در دو سرور دیگر نیز وجود داشته باشد.
حالا باید به MongoDB بگویید که امنیت را فعال کرده و از Keyfile استفاده کند. این تغییر را باید در فایل /etc/mongod.conf بر روی هر سه سرور اعمال کنید.
security:
authorization: “enabled”
keyFile: /opt/mongo/mongodb.key
این بخش به MongoDB میگوید که هم احراز هویت کاربر (authorization) را فعال کند و هم برای ارتباط داخلی اعضا از Keyfile مشخص شده استفاده نماید.
سرویس MongoDB را ریست کنید. هرگز تمام اعضای کلاستر را همزمان ریاستارت نکنید! این کار باعث قطعی سرویس میشود. باید اعضا را به ترتیب و با حوصله ریاستارت کنید.
اتصال اپلیکیشن به کلاستر MongoDB
این یک مرحله بسیار مهم و کلیدی است. اتصال به یک کلاستر Replica Set با اتصال به یک سرور تکی متفاوت است و به شما قابلیت High Availability (دسترسیپذیری بالا) را میدهد. اگر سرور اصلی از کار بیفتد، اپلیکیشن شما به طور خودکار و بدون نیاز به تغییر، به سرور اصلی جدید متصل میشود.
روش اتصال از طریق فایل .env قدیمی دیگر مناسب نیست، زیرا فقط آدرس یک سرور را در خود دارد. برای اتصال به کلاستر جدید، باید از یک رشته اتصال (Connection String URI) استاندارد MongoDB استفاده کنید.
دو روش اصلی برای این کار وجود دارد:
روش ۱: روش پیشنهادی و مدرن (استفاده از یک متغیر `MONGO_URI` جامع)
این روش بهترین و استانداردترین راه برای اتصال به کلاسترهای MongoDB است. شما تمام متغیرهای اتصال قدیمی را با یک متغیر واحد و قدرتمند جایگزین میکنید.
مرحله ۱: ساخت رشته اتصال (Connection String)
فرمت کلی رشته اتصال به شکل زیر است:
mongodb://[username:password@]host1[:port1],host2[:port2],…/[database]?options
با توجه به اطلاعات کلاستر جدید و اطلاعات کاربری شما، رشته اتصال به این شکل خواهد بود:
mongodb://<username>:<password>@192.168.1.101:27017,192.168.1.102:27017/<database>?replicaSet=myReplicaSet
`۱۹۲.۱۶۸.۱.۱۰۱:۲۷۰۱۷,۱۹۲.۱۶۸.۱.۱۰۲:۲۷۰۱۷`: لیست آدرسهای گرههای حامل داده. درایور MongoDB ابتدا سعی میکند به اولین آدرس متصل شود و اگر موفق نشد، سراغ بعدی میرود.
`?replicaSet=myReplicaSet`: مهمترین بخش! این پارامتر به درایور میگوید که شما در حال اتصال به یک Replica Set با نام `myReplicaSet` هستید. درایور پس از اتصال، لیست کامل اعضا (حتی داور) را شناسایی کرده و وضعیت کلاستر را زیر نظر میگیرد تا در صورت نیاز (Failover)، به صورت خودکار به سرور اصلی جدید متصل شود.
نکته بسیار مهم: نیازی به وارد کردن آدرس IP گره داور (Arbitrator) در رشته اتصال نیست. درایور به اندازه کافی هوشمند است که پس از اتصال به یکی از گرههای داده و شناسایی `replicaSet`، خودش گره داور را پیدا کند.
مرحله ۲: بهروزرسانی فایل .env
فایل `.env` خود را به شکل زیر تغییر دهید. متغیرهای قدیمی را حذف یا کامنت کرده و متغیر جدید را اضافه کنید.
متغیر جدید و جامع برای اتصال به کلاستر
MONGO_URI=mongodb://myusername:mypassword@192.168.1.101:27017,192.168.1.102:27017/mydatabase?replicaSet=myReplicaSet
مرحله ۳: بهروزرسانی کد اپلیکیشن
با توجه به اینکه از چه زبان برنامه نویسی و چه کتابخانهای برای اپلیکیشن خود استفاده میکنید، میبایست تعاریف مشخصی برای شناساندن آدرس uri جدید به آن بکنید.
روش ۲: روش ترکیبی (سازگاری با متغیرهای قدیمی)
اگر به هر دلیلی نمیخواهید ساختار فایل `.env` را به طور کامل تغییر دهید، میتوانید متغیرهای موجود را اصلاح کرده و رشته اتصال را در داخل کد اپلیکیشن بسازید. این روش کمتر توصیه میشود زیرا کد را پیچیدهتر و مستعد خطا میکند.



