Replication bekerja asinkron — dan asinkron selalu berarti ada jeda. Replication lag adalah ukuran jeda itu: berapa lama sebuah write menetap di primary sebelum diterapkan di secondary. Lag beberapa milidetik tidak terasa; lag yang membesar perlahan adalah cerita berbeda — baca mulai basi, secondary tertinggal makin jauh, dan pada kasus terburuk oplog meluber sehingga secondary harus menyalin ulang seluruh data. Chapter ini mengukur lag dari rs.status(), membedah penyebabnya, lalu menyusun strategi menekannya.

Mendefinisikan Lag dengan Optime #

Setiap anggota replica set melaporkan posisi replikasinya lewat field optime — timestamp entri oplog terakhir yang diterapkan. Lag sebuah secondary adalah selisih antara optimeDate primary dan optimeDate secondary itu. Kita ukur pada rs0, langsung setelah menulis satu pesanan:

js
use latihan_replika
db.pesanan.insertOne({ kode: "PSN-001", pelanggan: "Budi", buku: "Laut Bercerita", jumlah: 2 })

const st = rs.status()
st.members.map(m => ({ name: m.name, state: m.stateStr, optimeDate: m.optimeDate, lagMs: st.date - m.optimeDate }))

Output yang Dihasilkan:

text
switched to db latihan_replika
{
  acknowledged: true,
  insertedId: ObjectId('6ad3d76edb152affeac50952')
}

[
  {
    name: '127.0.0.1:27017',
    state: 'PRIMARY',
    optimeDate: ISODate('2026-10-17T20:15:42.000Z'),
    lagMs: 110
  }
]

Nilai lagMs: 110 di sini bukan lag replikasi sesungguhnya — anggota tunggal kita adalah primary itu sendiri, sehingga selisih yang terbaca hanyalah jeda antara snapshot st.date dan penulisan oplog terakhirnya (termasuk no-op berkala). Pada cluster nyata, cara membacanya berbeda: cari entri PRIMARY di members, jadikan optimeDate-nya patokan, lalu hitung selisih tiap SECONDARY terhadap patokan itu. Rumus umumnya: lag = optimeDate(primary) - optimeDate(secondary).

Tiga Posisi Replikasi pada MongoDB 9.0 #

optime sebenarnya keluarga field. Keluaran rs.status() pada 9.0 melaporkan tiga posisi berbeda per anggota:

js
const m = rs.status().members[0]
({
  optime: m.optime,
  optimeWritten: m.optimeWritten,
  lastAppliedWallTime: m.lastAppliedWallTime,
  lastDurableWallTime: m.lastDurableWallTime,
  lastWrittenWallTime: m.lastWrittenWallTime
})

Output yang Dihasilkan:

text
{
  optime: { ts: Timestamp({ t: 1792268142, i: 1 }), t: Long('8') },
  optimeWritten: { ts: Timestamp({ t: 1792268142, i: 1 }), t: Long('8') },
  lastAppliedWallTime: ISODate('2026-10-17T20:15:42.050Z'),
  lastDurableWallTime: ISODate('2026-10-17T20:15:42.050Z'),
  lastWrittenWallTime: ISODate('2026-10-17T20:15:42.050Z')
}

Ketiganya berimpit pada rs0 — wajar, karena primary tunggal menerapkan, menuliskan ke disk, dan mengakui mayoritas dalam satu gerakan. Di cluster nyata ketiganya bisa berselisih:

FieldMakna
optime / lastAppliedWallTimeEntri oplog terakhir yang diterapkan pada data anggota
optimeWritten / lastWrittenWallTimeEntri terakhir yang sudah tertulis ke journal di disk
lastDurableWallTimeEntri terakhir yang diakui mayoritas set

Pemisahan ini penting saat diagnosis: secondary yang applied-nya maju tetapi written-nya tertinggal sedang dibatasi kecepatan disk, bukan jaringan.

Penyebab Lag Membesarkan Diri #

Lag selalu bermula dari satu bottleneck di jalur primary → jaringan → disk secondary:

PenyebabMekanisme
Jaringan antar anggota lambatEntri oplog tiba terlambat; throughput batas atas bandwidth
Disk secondary pelanMenerapkan entri menulis ke disk; IOPS menjadi batas
Write besar atau batch raksasaSedikit entri tapi berat — satu entri bisa memuat ribuan document
Index build di secondaryMembangun index memperebutkan I/O dengan penerapan oplog
Chained replication berlapisSetiap lompatan menambah lag, bukan membagi rata
Secondary dengan spesifikasi rendahCPU dan cache lebih kecil daripada primary

Pola diagnosisnya mengikuti tabel di atas: periksa kesehatan jaringan antar anggota, lalu bandingkan metrik disk secondary dengan primary, lalu periksa apakah ada pekerjaan berat (index build, migrasi) yang berjalan bersamaan.

Dampak: Baca Basah dan Jendela Oplog #

Lag yang membesar menggerus dua hal sekaligus. Pertama, kualitas baca dari secondary: semakin besar lag, semakin basi data yang dikembalikan read preference secondary — inilah alasan maxStalenessSeconds ada sebagai penyaring di Chapter Read Preference. Kedua, keselamatan secondary itu sendiri: secondary yang tertinggal lebih lama daripada jendela oplog kehilangan jejak perubahan dan harus initial sync ulang — biaya pemulihan penuh yang jauh lebih mahal daripada mengejar ketertinggalan, seperti dihitung di Chapter Oplog.

Mitigasi #

Strategi menekan lag tersusun dari murah ke mahal:

  • Write concern majority untuk data penting — lag tidak hilang, tetapi aplikasi tidak pernah melihat data yang belum diakui mayoritas; baca readConcern: "majority" menutup celah di sisi pembaca.
  • Secondary sepadan dengan primary — disk dan jaringan yang lebih pelan di secondary menjamin lag permanen; replikasi hanya secepat anggota terlamat yang dihitung.
  • Working set muat di cache — secondary yang page fault terus-menerus menerapkan oplog lambat; kecocokan kapasitas cache dijaga seperti di primary.
  • chainingAllowed: false bila rantai secondary membuat lag berlapis.
  • Jadwalkan pekerjaan berat — index build dan backfill besar di luar jam puncak, atau bertahap lewat anggota satu per satu.
  • maxStalenessSeconds pada klien — bukan mengecilkan lag, tetapi memastikan pembaca tidak pernah dilayani anggota yang tertinggal parah.

Untuk pemantauan berkelanjutan, Atlas menyediakan metrik Replication Lag dan Oplog Window per anggota dalam bentuk grafik — angka yang sama dengan yang kita hitung manual di atas, tinggal dipantau sebagai deret waktu dengan ambang peringatan.

Rangkuman #

  • Lag = selisih optimeDate primary dan secondary; pada rs0 pengukurannya menunjukkan angka kecil karena satu-satunya anggota adalah primary itu sendiri.
  • MongoDB 9.0 memisahkan tiga posisi per anggota: applied (optime), written (optimeWritten), dan durable (lastDurableWallTime) — pemisahan yang mempercepat diagnosis.
  • Lag membesar karena bottle neck jaringan, disk, write berat, index build, atau chaining; dampaknya baca basi hingga initial sync paksa.
  • Mitigasi inti: write/read concern majority, secondary sepadan, working set di cache, dan penjadwalan pekerjaan berat.

Lag adalah gejala; kadang gejalanya lebih seram daripada sekadar jeda. Chapter penutup section ini merangkai gejala-gejala itu menjadi panduan pemulihan: Troubleshooting Replica Set.