Menambahkan shard baru ke kluster sharded MongoDB merupakan operasi skalabilitas horizontal umum untuk mengatasi pertumbuhan bisnis. Namun, terkadang data dan beban tidak secara otomatis seimbang setelah penambahan shard baru, sehingga shard baru hampir tidak digunakan sementara shard lama tetap berada di bawah tekanan. Akibatnya, operasi penskalaan tersebut tidak mencapai hasil yang diharapkan. Topik ini menyediakan proses diagnostik sistematis untuk membantu Anda mengidentifikasi penyebab ketidakseimbangan data dengan memeriksa status balancer dan karakteristik distribusi data, serta memberikan solusi untuk mengembalikan kluster ke kondisi seimbang.
Pendekatan diagnostik
Kemampuan data untuk diseimbangkan antara shard lama dan baru bergantung pada balancer bawaan MongoDB, yang bekerja dengan melakukan migrasi chunk secara otomatis. Oleh karena itu, pemecahan masalah ketidakseimbangan data harus difokuskan pada status balancer dan faktor-faktor yang memengaruhi keputusan migrasinya.
Anda dapat menggunakan logika pemecahan masalah top-down berikut:
Periksa status balancer: Pastikan bahwa balancer—komponen inti untuk migrasi data—diaktifkan dan aktif.
Analisis kemigrasian data: Selidiki properti koleksi yang mungkin mencegah balancer melakukan migrasi data, seperti koleksi yang tidak di-shard, volume data di bawah ambang batas pemicu penyeimbangan, atau keberadaan chunk jumbo. Properti-properti ini merupakan penyebab langsung umum dari distribusi data yang tidak merata.
Langkah-langkah implementasi
Diagnosis status balancer
Tujuan: Pastikan bahwa balancer—komponen inti untuk migrasi data—diaktifkan, berjalan, dan memiliki jendela aktif yang dikonfigurasi secara wajar. Migrasi chunk sepenuhnya bergantung pada balancer; jika balancer tidak berfungsi dengan benar, data tidak dapat bermigrasi dari shard lama ke shard baru.
1. Periksa apakah balancer diaktifkan secara global
Metode pemeriksaan
Dalam
mongosh, jalankansh.getBalancerState(). Jika mengembalikanfalse, berarti balancer tidak diaktifkan.Solusi
Jika balancer tidak diaktifkan, lihat Mengelola balancer MongoDB untuk mengaktifkannya.
2. Periksa apakah balancer berada dalam jendela aktifnya
Balancer hanya melakukan migrasi chunk selama jendela aktif yang dikonfigurasi. Jika waktu saat ini berada di luar jendela aktif, balancer tidak akan berjalan.
Metode pemeriksaan
db.getSiblingDB("config").settings.find({_id:"balancer"})Contoh keluaran:
{ _id: 'balancer', activeWindow: { start: '02:00', stop: '04:00' } }Jika waktu saat ini berada di luar
activeWindow, balancer tidak akan berjalan.Solusi: Ubah jendela aktif
Jika jendela aktif tidak dikonfigurasi dengan benar—misalnya terlalu singkat atau tumpang tindih dengan jam sibuk bisnis—atur jendela tersebut menjadi periode yang cukup panjang selama jam non-sibuk.
Sebagai contoh, untuk mengatur jendela aktif dari pukul 02.00 hingga 06.00 setiap hari:
db.getSiblingDB("config").settings.updateOne( { _id: "balancer" }, { $set: { activeWindow : { start : "02:00", stop : "06:00" } } }, { upsert: true } )
3. Konfirmasi apakah penyeimbangan data awal sedang berlangsung
Setelah menambahkan shard, sistem memerlukan waktu untuk memigrasikan data historis dari shard lama ke yang baru. Ketidakseimbangan data merupakan hal normal selama periode ini, dan durasi penyeimbangan bergantung pada volume data.
Metode pemeriksaan
Periksa progres penyeimbangan dengan menjalankan
sh.isBalancerRunning().// Periksa apakah balancer sedang menjalankan tugas migrasi sh.isBalancerRunning()
Jika sh.isBalancerRunning() mengembalikan true, berarti penyeimbangan sedang berlangsung.
Solusi
Anda dapat menunggu hingga proses penyeimbangan selesai. Untuk informasi selengkapnya, lihat Cara memeriksa progres penambahan atau penghapusan node shard.
Analisis kemigrasian data
Periksa data yang tidak dapat dimigrasikan secara otomatis oleh balancer karena properti koleksinya.
1. Periksa adanya banyak koleksi yang tidak di-shard
Sebuah database dapat berisi koleksi yang di-shard maupun yang tidak di-shard. Data dalam koleksi yang tidak di-shard disimpan sepenuhnya pada shard utamanya, sehingga balancer tidak dapat memigrasikan data tersebut. Jika sebuah koleksi besar tidak di-shard, datanya tidak akan pernah didistribusikan ke shard baru.
Metode pemeriksaan
Gunakan skrip berikut untuk menghitung ruang penyimpanan yang digunakan oleh koleksi yang tidak di-shard dalam database tertentu. Skrip ini menemukan semua koleksi yang tidak di-shard dan menjumlahkan ukuran penyimpanannya.
CatatanSkrip ini melakukan traversal terhadap semua koleksi dalam database dan menjalankan perintah
stats(), yang dapat memengaruhi kinerja database. Untuk mengurangi risiko ini, skrip menyertakan penundaansleep(200). Jika database berisi banyak koleksi, tingkatkan durasi sleep menjadi 2000 atau lebih tinggi untuk menghindari dampak terhadap bisnis Anda.// Skrip: Hitung penyimpanan yang digunakan oleh koleksi yang tidak di-shard dalam database tertentu // Ganti "myDB" dengan nama database yang ingin diperiksa var dbName = "myDB"; var unshardSize = 0; var totalSize = 0; var unshardedCollections = [ ]; db.getSiblingDB(dbName).getCollectionNames().forEach(function(collName) { var stats = db.getSiblingDB(dbName).getCollection(collName).stats(); // Periksa bidang stats.sharded dan jumlahkan ukuran penyimpanan if (!stats.sharded) { unshardSize += (stats.storageSize || 0); unshardedCollections.push(dbName + "." + collName); } totalSize += (stats.storageSize || 0); // Tunda sejenak setelah setiap kueri untuk menghindari beban berlebih pada database sleep(200); }); print("--- " + dbName + " ---"); print("Jumlah Koleksi Tidak Di-shard: " + unshardedCollections.length); print("--------------------"); print("Ukuran Penyimpanan Tidak Di-shard (Byte): " + unshardSize); print("Ukuran Penyimpanan Total (Byte): " + totalSize); print("--------------------"); print("Daftar Koleksi Tidak Di-shard:"); printjson(unshardedCollections);Solusi: Untuk informasi lebih lanjut, lihat Menyiapkan sharding data untuk memanfaatkan performa shard secara optimal.
2. Periksa apakah volume data koleksi yang di-shard terlalu kecil (MongoDB 6.0+)
Mulai dari MongoDB 6.0.3, balancer hanya memulai migrasi ketika perbedaan volume data antar shard dalam suatu koleksi mencapai ambang batas tertentu. Ambang batas default adalah tiga kali ukuran chunk. Jika volume data total suatu koleksi yang di-shard lebih kecil daripada ambang batas penyeimbangan, balancer tidak akan memprosesnya, sehingga datanya terkonsentrasi pada satu shard saja.
Metode pemeriksaan
Gunakan
db.collection.getShardDistribution()untuk melihat distribusi koleksi di seluruh shard. Masalah ini mungkin menjadi penyebab jika sebagian besar data koleksi yang di-shard berada pada satu shard dan perbedaan maksimum data antar shard jauh lebih kecil daripada ambang batas pemicu penyeimbangan.Solusi
Untuk koleksi yang di-shard dengan volume data kecil, kurangi
chunkSize-nya agar memicu pemisahan dan migrasi chunk.// Contoh ini mengatur chunkSize koleksi test_db.test_coll menjadi 16 MB. Sesuaikan chunkSize berdasarkan distribusi data koleksi Anda. db.adminCommand({ configureCollectionBalancing: "test_db.test_coll", chunkSize: 16 // Satuannya MB. Nilai default untuk MongoDB 6.0 dan versi setelahnya adalah 128 MB. })Setelah migrasi selesai, jalankan
db.collection.getShardDistribution()untuk memeriksa apakah distribusi data sesuai harapan Anda.
Dampak dan risiko operasional
Beban kinerja penyeimbangan: Selama penyeimbangan data, migrasi chunk (
moveChunk) dan penghapusan rentang (RangeDeleter) mengonsumsi sumber daya CPU dan I/O pada shard sumber dan tujuan. Untuk menghindari dampak terhadap layanan online, atur jendela aktif balancer pada jam non-sibuk.Risiko Konfigurasi chunkSize: Pada versi MongoDB sebelum 6.0, mengatur chunkSize terlalu kecil dapat menghasilkan jumlah chunk yang berlebihan, sehingga meningkatkan beban overhead manajemen metadata dan memicu aktivitas penyeimbangan yang terlalu sering. Anda dapat menentukan nilai
chunkSizeberdasarkan volume total data dan laju pertumbuhan koleksi.