Membangun high availability dengan replica set: memahami arsitektur primary, secondary, dan arbiter, mekanisme failover otomatis lewat election, read preference untuk menskalakan pembacaan, serta konfigurasi lengkap replica set tiga anggota.

Sejauh ini kalian menjalankan MongoDB sebagai satu instance tunggal. Itu menyenangkan untuk belajar, tapi tidak cukup untuk produksi: jika instance mati — server crash, network down, proses tewas — aplikasi kalian ikut mati, dan data bisa hilang. Di sinilah Replica Set menjadi tulang punggung deployment MongoDB yang serius.
Episode 15 membangun pemahaman high availability. Roadmap-nya: pertama konsep dan arsitektur replica set — primary, secondary, dan arbiter, kedua mekanisme failover otomatis lewat election, ketiga read preference untuk read scaling, dan keempat langkah praktis mengonfigurasi replica set tiga anggota. Mari mulai.
Replica Set adalah sekumpulan instance mongod yang menyimpan dataset yang sama. Data di-primary direplikasi ke semua secondary secara kontinu. Fungsinya ganda: redundansi (data aman jika satu server hilang) dan failover otomatis (jika primary mati, secondary terpilih menggantikan tanpa campur tangan manusia).
Replica set adalah komponen fundamental MongoDB — bahkan satu instance pun sebenarnya bisa dijalankan sebagai replica set satu anggota. Sharding di episode 16 juga dibangun di atas replica set sebagai unit shard-nya.
Setiap replica set terdiri dari tiga peran:
+----------------+
| Clients |
+----------------+
|
v
+--------------------+
| PRIMARY mongod | <- tulis + baca default
+--------------------+
| |
replicate| |replicate
v v
+----------------+ +----------------+
| SECONDARY 1 | | SECONDARY 2 |
+----------------+ +----------------+Setiap perubahan di primary dicatat ke oplog (operations log) — log tulis berurutan. Secondary menarik oplog ini dan menerapkan perubahannya ke data mereka sendiri. Inilah mekanisme replikasi yang berjalan terus-menerus. Kecepatan "mengejar" secondary mengukur seberapa cepat ia mereplikasi; jika ketinggalan terlalu jauh, muncul masalah replication lag yang kita bahas di episode 19.
Saat primary mati (crash, network terputus), anggota lain mendeteksi tidak ada detak jantung dari primary, lalu mengadakan election untuk memilih primary baru. Election memakai protokol mayoritas — dibutuhkan suara mayoritas anggota agar sebuah election sah.
Inilah mengapa jumlah anggota yang ganjil sangat penting. Dengan tiga anggota, mayoritas adalah 2 — satu secondary mati, dua sisanya masih bisa membentuk mayoritas dan memilih primary baru. Dengan dua anggota saja, satu mati berarti hanya tersisa satu suara, tidak cukup mayoritas, dan cluster menjadi read-only.
rs.status()rs.status() menampilkan setiap anggota, perannya, dan kondisi health-nya. Setelah failover, kalian akan melihat nama anggota yang menggantikan primary — dan seluruh proses terjadi otomatis dalam hitungan detik.
Secara default, semua read (dan write) menuju primary. Untuk menskalakan pembacaan — memanfaatkan secondary yang menganggur — aplikasi bisa mengatur read preference. Ada lima mode:
| Mode | Perilaku |
|---|---|
primary | Selalu baca dari primary (default) |
primaryPreferred | Baca dari primary; fallback ke secondary jika primary down |
secondary | Selalu baca dari secondary |
secondaryPreferred | Baca dari secondary; fallback ke primary jika tak ada secondary |
nearest | Baca dari node dengan latensi terendah |
const collection = db.collection("orders");
const cursor = collection.find({ userId: userId }).readPref("secondary");Baca dari secondary punya konsekuensi penting: data secondary bisa sedikit tertinggal dari primary (replication lag). Untuk data yang harus selalu terkini — saldo, stok — tetap pakai primary. Mode secondary cocok untuk laporan dan data yang toleran terhadap keterlambatan. Ini adalah keputusan trade-off antara performa dan konsistensi.
Sekarang mari membangun replica set lengkap. Cara tercepat mempraktikkannya di mesin sendiri adalah dengan Docker, menjalankan tiga instance mongod dalam satu network:
docker network create mongors
docker run -d --name mongo1 --network mongors -p 27017:27017 mongo:7 mongod --replSet rs0
docker run -d --name mongo2 --network mongors -p 27018:27017 mongo:7 mongod --replSet rs0
docker run -d --name mongo3 --network mongors -p 27019:27017 mongo:7 mongod --replSet rs0Ketiga kontainer berjalan dengan flag --replSet rs0, menandakan mereka anggota dari replica set bernama rs0. Sekarang inisiasi replica set dan daftarkan ketiganya:
mongosh "mongodb://localhost:27017" --eval '
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "mongo1:27017" },
{ _id: 1, host: "mongo2:27017" },
{ _id: 2, host: "mongo3:27017" }
]
})
'Setelah inisiasi, verifikasi status dan health:
rs.status()
rs.isMaster()rs.isMaster() menunjukkan siapa primary saat ini. Setiap anggota punya stateStr yang jelas: PRIMARY, SECONDARY, atau ARBITER. Untuk menguji failover, matikan primary (docker stop mongo1) dan perhatikan — dalam hitungan detik, salah satu secondary terpilih menjadi primary baru. Data tidak hilang, dan aplikasi bisa terus berjalan.
Info
Berlatih failover di environment Docker adalah cara teraman memahami election. Coba tiga skenario: matikan primary dan amati election, matikan secondary dan perhatikan tidak ada gangguan, lalu tambahkan kembali node dan lihat ia mengejar data via oplog. Semua pengalaman ini menanamkan intuisi yang akan menyelamatkan kalian saat incident produksi.
Warning
Jangan pernah mengonfigurasi satu primary dan dua arbiter. Arbiter tidak menyimpan data — dengan dua arbiter, mayoritas bisa memilih primary sementara hanya satu data node yang tersisa. Ini menciptakan ilusi keamanan: cluster "berjalan" tapi tidak benar-benar aman karena satu-satunya node data bisa hilang. Gunakan arbiter hanya untuk meredakan jumlah genap pada satu node voting tanpa data.
Pada episode 15 ini kalian telah memahami konsep replica set sebagai fondasi high availability: sekumpulan mongod dengan dataset sama yang menyediakan redundansi dan failover otomatis. Kalian mengenal peran primary yang menerima write, secondary yang mereplikasi data dan melayani read, serta arbiter yang hanya voting. Kalian memahami mekanisme election berbasis mayoritas, memanfaatkan read preference untuk menskalakan pembacaan, dan mempraktikkan konfigurasi replica set tiga anggota penuh di Docker beserta uji failover.
Inti yang harus dibawa pulang:
Di episode 16 berikutnya kita melangkah lebih jauh: Sharding (Horizontal Scalability). Kalian akan memahami kapan dataset perlu di-sharding, arsitektur sharded cluster yang terdiri dari shard, config servers, dan mongos, serta memilih shard key yang tepat antara ranged dan hashed sharding. Sampai jumpa di episode 16!