Chunk menyebar ke shard saat data ditulis, tetapi kemerataan tidak terjadi dengan sendirinya: shard baru selalu kosong, beban tulis bisa timpang, dan zone bisa menahan chunk di tempat tertentu. Tugas menjaga keseimbangan dipegang balancer — proses background yang aktif secara bawaan pada setiap sharded cluster. Chapter ini membahas cara kerjanya, biaya perjalanannya, dan cara kita memagari eksekusinya agar tidak mengganggu jam sibuk.
Cara Kerja Balancer #
Balancer berjalan di primary config server (CSRS), bukan di mongos dan bukan di shard. Ia memantau jumlah data setiap collection ter-shard pada setiap shard, lalu memicu migrasi bila ketimpangan melewati ambang: selisih ukuran data antara shard terberat dan terringan untuk collection yang sama harus mencapai tiga kali ukuran range. Dengan ukuran bawaan 128 MB, migrasi baru terjadi ketika selisihnya menyentuh 384 MB — ketimpangan kecil memang sengaja dibiarkan agar cluster tidak sibuk memindahkan data terus-menerus.
Pembatasan lain menjaga dampak migrasi tetap terkendali: satu shard hanya boleh ikut satu migrasi pada satu waktu, sehingga cluster dengan n shard paling banyak menjalankan n/2 migrasi paralel (tiap migrasi menyita dua shard: sumber dan tujuan).
Perjalanan Satu Migrasi #
Prosedur migrasi satu chunk, dirangkum dari dokumentasi resmi:
- Balancer mengirim perintah
moveRangeke shard sumber. - Shard tujuan membangun index yang dimiliki sumber namun belum ada di dirinya.
- Shard tujuan menyalin document pada rentang chunk, lalu menyinkronkan perubahan yang terjadi selama penyalinan berlangsung — selama fase ini, tulis tetap dilayani shard sumber.
- Setelah sinkron, sumber memperbarui metadata di config server: chunk kini milik shard tujuan.
- Sumber menghapus salinan lamanya secara asinkron di latar belakang.
Dua konsekuensi praktis dari alur ini. Pertama, migrasi memakan bandwidth jaringan dan I/O disk kedua shard — pada dataset besar, fase penyalinan dan penghapusan terasa di metrik. Kedua, tepat sebelum commit metadata, operasi CRUD pada collection terkait di shard sumber dijeda sesaat; semakin besar routing table, semakin lama jeda pembaruan metadata, dan inilah alasan chunk berukuran raksasa (yang jarang berpindah) justru lebih disukai daripada banyak chunk kecil yang rajin pindah.
Mengendalikan Balancer #
Status balancer diperiksa dengan sh.getBalancerState(). Kita coba di server latihan:
sh.getBalancerState()Output yang Dihasilkan:
Warning: MongoshWarning: [SHAPI-10003] You are not connected to a mongos. This command may not work as expected.
trueWarning dari mongosh mengingatkan bahwa perintah ini penuh artinya lewat mongos; di server biasa kita hanya melihat nilai true — memang bawaannya balancer dianggap aktif. Perintah kendali lengkapnya:
// mdtest: skip
// Dijalankan lewat mongos pada sharded cluster sungguhan:
sh.stopBalancer() // matikan untuk maintenance singkat
sh.startBalancer() // nyalakan kembali
sh.isBalancerRunning() // apakah sedang ada putaran balancing
Bila dampak migrasi terasa di jam produksi, batasi balancer pada jendela waktu tertentu. Konfigurasinya tersimpan di config.settings:
// mdtest: skip
// Dijalankan lewat mongos pada sharded cluster sungguhan:
use config
db.settings.updateOne(
{ _id: "balancer" },
{ $set: { activeWindow: { start: "23:00", stop: "05:00" } } },
{ upsert: true }
)Dengan jendela ini, balancer hanya memindahkan chunk antara pukul 23:00 dan 05:00 — zona waktunya mengikuti jam lokal primary CSRS. Menghapus jendela berarti mengembalikan balancer berjalan kapan pun perlu:
// mdtest: skip
use config
db.settings.updateOne( { _id: "balancer" }, { $unset: { activeWindow: true } } )Versi terbaru juga menyediakan activeWindowDOW untuk jendela yang berbeda tiap hari pekan.
Event yang Menggoyang Keseimbangan #
Tiga peristiwa paling sering memicu gelombang migrasi: menambah shard (shard baru kosong, balancer langsung mengisinya), menghapus shard (datanya didrain ke shard lain), dan sharding collection besar yang sudah terisi. Sejak MongoDB 8.0 terdapat jalan pintas resmi untuk dua skenario terakhir: sh.shardAndDistributeCollection() meng-shard lalu langsung mendistribusikan ulang collection dengan resharding ke kunci yang sama — lebih cepat daripada menunggu balancer memindahkan chunk satu per satu.
Rangkuman #
- Balancer hidup di primary config server, aktif secara bawaan, dan memigrasi data berdasarkan selisih ukuran — ambangnya tiga kali ukuran range (384 MB pada bawaan 128 MB).
- Satu shard hanya terlibat satu migrasi pada satu waktu; maksimal n/2 migrasi paralel di cluster n shard.
- Migrasi berbiaya I/O dan jeda CRUD sesaat saat commit metadata; jendela
activeWindowmemagari eksekusinya di jam sepi. - Menambah dan menghapus shard selalu memicu rebalancing; sejak 8.0,
sh.shardAndDistributeCollection()mempercepat distribusi awal.
Bagaimana query berperilaku di atas data yang tersebar begini — itulah pokok chapter berikutnya.