Replica set membagi pekerjaan dengan tegas: satu anggota menjadi penulis tunggal, anggota lainnya menjadi penyalin. Pembagian ini terasa membatasi — kenapa tidak semua node boleh menulis? — tetapi justru itulah yang membuat data semua anggota bisa dijamin identik tanpa protokol konsensus yang rumit pada setiap write. Chapter ini membedah peran primary dan secondary, membuktikan peran lewat db.hello(), lalu menyusun kamus state anggota yang akan terus kita pakai saat membaca rs.status().
Primary: Satu-satunya Penerima Write #
Seluruh operasi tulis — insertOne, updateMany, deleteMany, hingga aggregation stage $merge — hanya diterima oleh primary. Saat write tiba, primary menerapkannya pada data lokal, menuliskan deskripsi perubahannya ke oplog, lalu mengembalikan hasil ke klien. Secondary kemudian menarik entri oplog itu dan menerapkannya pada salinan datanya masing-masing.
Kita buktikan perannya pada rs0 dengan data pesanan buku:
use latihan_replika
db.dropDatabase()
db.pesanan.insertMany([
{ kode: "PSN-001", pelanggan: "Budi", buku: "Laut Bercerita", jumlah: 2 },
{ kode: "PSN-002", pelanggan: "Siti", buku: "Bumi Mantra", jumlah: 1 }
])
db.hello().isWritablePrimaryOutput yang Dihasilkan:
switched to db latihan_replika
{ ok: 1, dropped: 'latihan_replika' }
{
acknowledged: true,
insertedIds: {
'0': ObjectId('6ad3d41514c358caabb070c7'),
'1': ObjectId('6ad3d41514c358caabb070c8')
}
}
trueUrutan kejadiannya: insertMany diterima karena node ini isWritablePrimary: true — baris terakhir membuktikannya. Mari kita bedah tiga baris pentingnya:
db.dropDatabase(): menghapus sisa latihan sebelumnya agar chapter ini selalu mulai dari keadaan kosong dan keluarannya dapat diprediksi.db.pesanan.insertMany([...]): dua pesanan Budi dan Siti diterapkan primary pada collectionpesanan; pada saat yang sama dua entri baru tertulis di oplog.db.hello().isWritablePrimary: field yang ditanyakan driver sebelum mengirim write —trueberarti node ini boleh menulis.
Bila klien terhubung ke node yang bukan primary, write ditolak dengan galat NotWritablePrimary. Driver mode replica set tidak akan pernah mengirim write ke secondary karena pemantauan topologinya selalu tahu alamat primary saat ini; node secondary menerima write hanya dari koneksi direct yang keliru sasaran — skenario itu kita bahas di Chapter Troubleshooting Replica Set.
Secondary: Menyalin Oplog, Melayani Baca #
Secondary menjalankan satu rutinitas terus-menerus: membaca entri oplog baru dari primary (atau dari secondary lain), menerapkannya pada salinan lokal dalam urutan yang sama, lalu melapor posisi terakhirnya. Karena hanya menerapkan entri oplog, secondary bersifat read-only dari sudut pandang klien — query boleh dilayani, write tidak.
Diagram di atas menunjukkan dua jalur yang berbeda: jalur write (aplikasi → primary → oplog) dan jalur replikasi (secondary menarik oplog). Secondary tidak menerima tulisan dari aplikasi — yang diterimanya adalah aliran entri oplog yang diterapkan ulang. Selisih waktu antara write di primary dan penerapan di secondary disebut replication lag, dan semakin kecil semakin baik — dibahas penuh di Chapter Replication Lag.
Klien boleh memanfaatkan secondary untuk membaca, tetapi keputusan itu tidak gratis: data di secondary bisa tertinggal beberapa milidetik hingga beberapa detik. Mekanisme read preference untuk mengarahkan baca dibahas di chapter khususnya.
Kamus State Anggota #
Field stateStr pada rs.status().members merangkum kondisi setiap anggota. State berubah sepanjang hidup cluster — node yang restart, tersinkronisasi ulang, atau sedang menggulung data akan melaporkan state yang berbeda:
| State | Arti | Menerima write? |
|---|---|---|
PRIMARY | Anggota penulis tunggal saat ini | Ya |
SECONDARY | Menyalin oplog, siap melayani baca (dengan read preference) | Tidak |
STARTUP2 | Sedang initial sync — menyalin seluruh data dari awal | Tidak |
RECOVERING | Sementara tidak siaga; mengejar ketertinggalan internal | Tidak |
ROLLBACK | Menggulung write yang tidak sempat direplikasi mayoritas | Tidak |
ARBITER | Anggota suara tanpa data | Tidak |
State ROLLBACK layak diperhatikan: node yang sempat menjadi primary lalu kehilangan mayoritas bisa memiliki write yang tidak diketahui cluster — write itu digulung dan disimpan agar administrator dapat memutuskan nasibnya. Pada rs0 kita hanya akan melihat satu state:
rs.status().members.map(m => ({ name: m.name, state: m.stateStr, health: m.health }))Output yang Dihasilkan:
[ { name: '127.0.0.1:27017', state: 'PRIMARY', health: 1 } ]Kombinasi state: 'PRIMARY' dan health: 1 (sehat) adalah kondisi ideal anggota tunggal kita. Di cluster produksi, bacaan yang sehat berbentuk satu PRIMARY plus beberapa SECONDARY dengan health: 1; kombinasi lain — misalnya RECOVERING berkepanjangan — adalah petunjuk untuk menyelidiki.
Failover: Ketika Primary Berhenti #
Primary bukan jabatan permanen. Ketika secondary-secondary tidak lagi menerima heartbeat dari primary dalam batas waktu tertentu, mereka menyadari posisi primary kosong lalu mengadakan election untuk memilih primary baru di antara mereka. Proses ini otomatis — tanpa intervensi operator — dan biasanya tuntas dalam hitungan detik; selama masa transisi, write ditahan sementara baca ke secondary tetap berjalan.
Mekanisme lengkapnya — kapan election dipicu, bagaimana suara dihitung, dan bagaimana priority memengaruhi hasil — dibedah di Chapter Elections dan Failover.
Rangkuman #
- Primary adalah satu-satunya anggota yang menerima write; perannya bisa diverifikasi dari
db.hello().isWritablePrimary. - Secondary menyalin oplog secara berkelanjutan dan bersifat read-only; klien boleh membaca darinya lewat read preference dengan konsekuensi data yang mungkin tertinggal.
stateStrpadars.status()merangkum kondisi anggota:PRIMARY,SECONDARY,STARTUP2,RECOVERING,ROLLBACK,ARBITER.- Saat primary hilang, secondary mengadakan election otomatis untuk memilih primary baru.
Tugas berikutnya adalah mengintip isi oplog itu sendiri — buku catatan perubahan yang menjadi mata rantai primary dan secondary.