Topik ini menjelaskan cara memantau progres tugas penambahan atau penghapusan node shard serta mengidentifikasi kondisi abnormal yang dapat menghambat tugas tersebut.
Informasi latar belakang
Setelah menambahkan atau menghapus node shard dari instans kluster sharded, tugas tersebut mungkin memerlukan waktu lama untuk selesai. Bagian berikut menjelaskan cara mengatasi masalah ini.
Sebelum memulai, pahami konsep-konsep berikut:
-
Pahami mode penyebaran instans set replika MongoDB dan instans kluster sharded, serta perbedaan antara arsitektur-arsitektur tersebut. Untuk informasi lebih lanjut, lihat Arsitektur set replika dan Arsitektur kluster sharded.
-
Pahami cara kerja MongoDB Balancer. Untuk informasi lebih lanjut, lihat Mengelola MongoDB Balancer.
-
Pahami cara MongoDB membagi data. MongoDB mempartisi data menjadi chunk.
-
Pahami perintah O&M umum untuk instans kluster sharded MongoDB, seperti
sh.status(). -
Pahami cara menggunakan mongo shell, mongosh, atau alat visualisasi lainnya.
Periksa progres tugas
Langkah 1: Periksa apakah Balancer diaktifkan
Migrasi chunk selama penambahan atau penghapusan shard bergantung pada Balancer. Jika Balancer dinonaktifkan, masalah berikut terjadi:
-
Saat menambahkan node shard: Data chunk tidak dapat dimigrasikan ke node shard baru, sehingga node tersebut tidak dapat menangani lalu lintas layanan.
-
Saat menghapus node shard: Chunk pada shard target tidak dapat dimigrasikan keluar, sehingga menghambat tugas penghapusan.
Aktifkan Balancer untuk memastikan migrasi chunk berjalan normal. Untuk instruksi, lihat Mengelola MongoDB Balancer.
Gunakan salah satu metode berikut untuk memeriksa apakah Balancer diaktifkan:
-
Metode 1: Jalankan perintah
sh.status().Jika Balancer diaktifkan, output-nya menyerupai contoh berikut.
... autosplit: Currently enabled: yes balancer: Currently enabled: yes Currently running: yes Balancer active window is set between 08:30 and 11:30 server local time ...Jika output menampilkan
“Currently enabled: no”, maka Balancer dinonaktifkan. -
Metode 2: Jalankan perintah
sh.getBalancerState().-
Jika perintah mengembalikan
true, Balancer diaktifkan. -
Jika perintah mengembalikan
false, Balancer dinonaktifkan.
-
Langkah 2: Periksa apakah Balancer window terlalu pendek
Balancer mengontrol kecepatan migrasi chunk dan hanya melakukan migrasi selama jendela aktifnya. Jika migrasi tidak selesai dalam jendela saat ini, proses tersebut akan dilanjutkan pada jendela berikutnya hingga selesai. Jendela yang terlalu singkat dapat memperlambat tugas penambahan atau penghapusan shard. Untuk menyesuaikan jendela Balancer, lihat Mengelola MongoDB Balancer.
Gunakan salah satu metode berikut untuk memeriksa jendela Balancer:
-
Metode 1: Jalankan perintah
sh.status().Contoh berikut menunjukkan jendela Balancer dari pukul 08:30 hingga 11:30 waktu lokal server (total 3 jam).
... autosplit: Currently enabled: yes balancer: Currently enabled: yes Currently running: yes Balancer active window is set between 08:30 and 11:30 server local time ... -
Metode 2: Jalankan perintah
sh.getBalancerWindow().Contoh berikut secara jelas menampilkan waktu jendela, terutama berguna ketika terdapat banyak koleksi sharded.
{ "start" : "08:30", "stop" : "11:30" }
Langkah 3: Kumpulkan informasi yang diperlukan untuk memperkirakan progres tugas
Untuk versi MongoDB sebelum 6.0
Bagian ini berlaku untuk versi berikut:
-
Instans MongoDB sebelum versi 6.0.
-
Instans MongoDB 6.0 dengan versi mesin minor sebelum 7.0.1 (versi baseline 6.0.3). Untuk memeriksa versi mesin minor Anda, lihat Panduan versi minor MongoDB.
Sebelum memperkirakan progres tugas, peroleh statistik eksekusi Balancer (jumlah keberhasilan dan kegagalan) serta informasi chunk untuk koleksi sharded yang menunggu migrasi.
Anda dapat memperoleh hasil eksekusi Balancer dan informasi tentang chunk dari tabel sharded yang menunggu migrasi menggunakan dua metode berikut:
-
Metode 1: Gunakan output dari perintah
sh.status().Fokus pada dua bagian dari output
sh.status(). Bagian pertama menunjukkan hasil Balancer terbaru, seperti pada contoh berikut.... balancer: Collections with active migrations: <db>.<collection> started at Wed Sep 27 2023 10:25:21 GMT+0800 (CST) Failed balancer rounds in last 5 attempts: 0 Migration Results for the last 24 hours: 300 : Success databases: ...Bagian kedua menunjukkan detail chunk untuk koleksi sharded, seperti pada contoh berikut.
... databases: ... { "_id" : "<db>", "primary" : "d-xxxxxxxxxxxxxxx3", "partitioned" : true, "version" : { "uuid" : UUID("3409a337-c370-4425-ad72-8b8c6b0abd52"), "lastMod" : 1 } } <db>.<collection> shard key: { "<shard_key>" : "hashed" } unique: false balancing: true chunks: d-xxxxxxxxxxxxxxx1 13630 d-xxxxxxxxxxxxxxx2 13629 d-xxxxxxxxxxxxxxx3 13652 d-xxxxxxxxxxxxxxx4 13630 d-xxxxxxxxxxxxxxx5 3719 too many chunks to print, use verbose if you want to force print ...Dalam contoh ini, “d-xxxxxxxxxxxxxxx5” adalah node shard yang baru ditambahkan. Anda juga dapat menjalankan perintah
getShardDistributiondi database yang berisi koleksi sharded untuk memperoleh detail distribusi chunk, seperti yang ditunjukkan di bawah ini.use <db> db.<collection>.getShardDistribution() -
Metode 2: Baca data terkait langsung dari database config.
Lihat statistik chunk yang dikelompokkan berdasarkan shard sebagai berikut.
db.getSiblingDB("config").chunks.aggregate([{$group: {_id: "$shard", count: {$sum: 1}}}])Untuk melihat chunk pada shard tertentu yang dikelompokkan berdasarkan namespace, jalankan perintah berikut.
db.getSiblingDB("config").chunks.aggregate([{$match: {shard: "d-xxxxxxxxxxxxxx"}},{$group: {_id: "$ns", count: {$sum: 1}}}])Untuk menghitung jumlah chunk yang berhasil dimigrasikan ke node shard tertentu dalam 24 jam terakhir, jalankan perintah berikut.
// details.to menentukan shard tujuan untuk migrasi chunk // Gunakan ISODate untuk menentukan rentang waktu pada bidang time db.getSiblingDB("config").changelog.find({"what" : "moveChunk.commit", "details.to" : "d-xxxxxxxxxxxxx","time" : {"$gte": ISODate("2023-09-26T00:00:00")}}).count()
Untuk versi MongoDB 6.0 dan seterusnya
Bagian ini berlaku untuk versi berikut:
-
Instans MongoDB versi 6.0 dan seterusnya.
-
Instans MongoDB 6.0 dengan versi mesin minor 7.0.1 (versi baseline 6.0.3) atau lebih baru. Untuk memeriksa versi mesin minor Anda, lihat Panduan versi minor MongoDB.
Sebelum memperkirakan progres tugas, fokuslah pada distribusi data di seluruh shard. Anda masih dapat menggunakan output sh.status() sebagai referensi, tetapi alihkan perhatian dari jumlah chunk yang tidak merata ke distribusi volume data aktual.
-
Peroleh informasi distribusi dan keseimbangan data koleksi sharded.
Gunakan perintah
getShardDistributionuntuk memperoleh detail distribusi dan fokus pada keseimbangan data. Contoh:mongos> db.xxx.getShardDistribution() Shard d-xxx at xxx data : 379.26MiB docs : 8277367 chunks : 1 estimated data per chunk : 379.26MiB estimated docs per chunk : 8277367 Shard d-xxx at xxx data : 379.11MiB docs : 8272852 chunks : 1 estimated data per chunk : 379.11MiB estimated docs per chunk : 8272852 Shard d-xxx at xxx data : 379.18MiB docs : 8275108 chunks : 1 estimated data per chunk : 379.18MiB estimated docs per chunk : 8275108 Totals data : 1.11GiB docs : 24825327 chunks : 3 Shard d-xxx contains 33.34% data, 33.34% docs in cluster, avg obj size on shard : 48B Shard d-xxx contains 33.32% data, 33.32% docs in cluster, avg obj size on shard : 48B Shard d-xxx contains 33.33% data, 33.33% docs in cluster, avg obj size on shard : 48BAnda juga dapat menjalankan perintah berikut untuk informasi distribusi yang lebih rinci (termasuk jumlah dokumen, ukuran total, jumlah dokumen yatim, dan ukuran yatim):
db.getSiblingDB("admin").aggregate( [{ $shardedDataDistribution: { } },{ $match: { "ns": "<db>.<collection>" } }] ).pretty()Output contoh berikut menunjukkan ketidakseimbangan data yang signifikan di seluruh shard.
{ "ns" : "<db>.<collection>", "shards" : [ { "shardName" : "d-xxxxxxxxxxxxxxx1", "numOrphanedDocs" : 0, "numOwnedDocuments" : 504298920, "ownedSizeBytes" : NumberLong("833101815840"), "orphanedSizeBytes" : 0 }, { "shardName" : "d-xxxxxxxxxxxxxxx2", "numOrphanedDocs" : 0, "numOwnedDocuments" : 250283901, "ownedSizeBytes" : NumberLong("409714745937"), "orphanedSizeBytes" : 0 }, { "shardName" : "d-xxxxxxxxxxxxxxx3", "numOrphanedDocs" : 0, "numOwnedDocuments" : 109098088, "ownedSizeBytes" : NumberLong("178157177704"), "orphanedSizeBytes" : 0 }, { "shardName" : "d-xxxxxxxxxxxxxxx4", "numOrphanedDocs" : 0, "numOwnedDocuments" : 382018055, "ownedSizeBytes" : NumberLong("630329790750"), "orphanedSizeBytes" : 0 } ] }Dari output ini, Anda dapat menentukan bahwa instans memiliki 4 node shard dan volume data total untuk koleksi sharded
<db>.<collection>kira-kira 2.051.303.530.231 byte (833.101.815.840 + 409.714.745.937 + 178.157.177.704 + 630.329.790.750 = 2.051.303.530.231), atau sekitar 1.910,4 GB. -
Lihat volume data yang berhasil dimigrasikan selama sehari terakhir.
Jalankan kueri berikut:
pipeline = [ { '$match': { 'what': 'moveChunk.commit', } }, { '$group': { '_id': { 'date': { '$dateToString': { 'format': '%Y-%m-%d', 'date': '$time'} }, }, 'chunks_moved': { '$sum': 1 }, 'docs_moved': { '$sum': '$details.counts.cloned' }, 'bytes_moved': { '$sum': '$details.counts.clonedBytes' }, } }, { '$sort': { '_id.date': -1} }, ] db.getSiblingDB("config").changelog.aggregate(pipeline)Contoh output:
mongos> db.getSiblingDB("config").changelog.aggregate(pipeline) { "_id" : { "date" : "2024-09-24" }, "chunks_moved" : 91, "docs_moved" : NumberLong(33071040), "bytes_moved" : NumberLong("11532786734") } { "_id" : { "date" : "2024-09-23" }, "chunks_moved" : 294, "docs_moved" : NumberLong(109806635), "bytes_moved" : NumberLong("38294757573") } { "_id" : { "date" : "2024-09-22" }, "chunks_moved" : 737, "docs_moved" : NumberLong(266800041), "bytes_moved" : NumberLong("93047288531") } { "_id" : { "date" : "2024-09-21" }, "chunks_moved" : 1448, "docs_moved" : NumberLong(525308393), "bytes_moved" : NumberLong("183117965820") } { "_id" : { "date" : "2024-09-20" }, "chunks_moved" : 1459, "docs_moved" : NumberLong(530020503), "bytes_moved" : NumberLong("184390749022") } { "_id" : { "date" : "2024-09-19" }, "chunks_moved" : 1478, "docs_moved" : NumberLong(557833705), "bytes_moved" : NumberLong("186910196651") } { "_id" : { "date" : "2024-09-18" }, "chunks_moved" : 1360, "docs_moved" : NumberLong(508484825), "bytes_moved" : NumberLong("173486932689") }Output ini menunjukkan bahwa pada
2024-09-21, sebanyak 183.117.965.820 byte (sekitar 170,5 GB) telah dimigrasikan.
Langkah 4: Perkirakan progres tugas dan waktu penyelesaian
Untuk versi MongoDB sebelum 6.0
Bagian ini berlaku untuk versi berikut:
-
Instans MongoDB sebelum versi 6.0.
-
Instans MongoDB 6.0 dengan versi mesin minor sebelum 7.0.1 (versi baseline 6.0.3). Untuk memeriksa versi mesin minor Anda, lihat Panduan versi minor MongoDB.
Setelah memperoleh jumlah chunk yang berhasil dimigrasikan dan distribusi data saat ini, perkirakan progres keseluruhan tugas dan waktu penyelesaian yang diharapkan.
Mengasumsikan kondisi ideal berikut selama penambahan shard: jumlah total chunk tetap konstan, jumlah shard tetap (tidak ada penambahan atau penghapusan shard bersamaan), beban layanan tetap stabil, dan parameter Balancer menggunakan nilai default. Menggunakan contoh dari Langkah 3 di bawah Untuk versi MongoDB sebelum 6.0, Anda mengetahui:
-
Terdapat 5 node shard.
-
300 chunk berhasil dimigrasikan selama jendela Balancer.
-
Koleksi sharded
<db>.<collection>memiliki total 58.260 chunk (13.630 + 13.629 + 13.652 + 13.630 + 3.719 = 58.260).
Oleh karena itu, hal berikut dapat dihitung:
-
Pada kondisi seimbang, setiap shard seharusnya menyimpan 11.652 chunk (58.260 ÷ 5 = 11.652).
-
Pada laju migrasi saat ini, penyelesaian tugas memerlukan waktu tambahan sekitar 26,4 hari ((11.652 – 3.719) ÷ 300 ≈ 26,4).
-
Tugas penambahan shard telah mencapai 32% (3.719 ÷ 11.652 = 32%).
Dalam skenario dunia nyata, jumlah total chunk meningkat akibat operasi write yang berkelanjutan dan pemisahan chunk. Perhitungan ini mengasumsikan kondisi ideal; waktu penyelesaian aktual mungkin lebih lama.
Untuk versi MongoDB 6.0 dan seterusnya
Bagian ini berlaku untuk versi berikut:
-
Instans MongoDB versi 6.0 dan seterusnya.
-
Instans MongoDB 6.0 dengan versi mesin minor 7.0.1 (versi baseline 6.0.3) atau lebih baru. Untuk memeriksa versi mesin minor Anda, lihat Panduan versi minor MongoDB.
Mengasumsikan instans kluster sharded hanya memiliki satu koleksi yang memerlukan penyeimbangan. Menggunakan contoh dari Langkah 3 di bawah Untuk versi MongoDB 6.0 dan seterusnya, Anda mengetahui:
-
Terdapat 4 node shard.
-
Pada
2024-09-21, sekitar 170,5 GB (183.117.965.820 byte) telah dimigrasikan. -
Koleksi sharded
<db>.<collection>memiliki volume data total sekitar 1.910,4 GB (2.051.303.530.231 byte).
Oleh karena itu, hal berikut dapat dihitung:
-
Pada kondisi seimbang, setiap shard seharusnya menyimpan sekitar 477,6 GB (512.825.882.557,75 byte).
-
Total volume data yang perlu dimigrasikan untuk mencapai keseimbangan adalah 875.559.682.949 byte (815,4 GB), diuraikan sebagai berikut:
Shard1 perlu memigrasikan 320.275.933.282,25 byte (833.101.815.840 – 512.825.882.557,75).
Shard2 perlu memigrasikan 103.111.136.620,75 byte (409.714.745.937 – 512.825.882.557,75).
Shard3 perlu memigrasikan 334.668.704.853,75 byte (178.157.177.704 – 512.825.882.557,75).
Shard4 perlu memigrasikan 117.503.908.192,25 byte (630.329.790.750 – 512.825.882.557,75).
(320.275.933.282,25 + 103.111.136.620,75 + 334.668.704.853,75 + 117.503.908.192,25 = 875.559.682.949)
-
Pada laju migrasi saat ini, keseimbangan akan tercapai dalam waktu sekitar 4,8 hari (815,4 GB ÷ 170,5 GB/hari ≈ 4,8 hari).
Langkah 5: Konfirmasi apakah alur tugas terblokir (penghapusan shard)
Jika tugas penghapusan shard terblokir, menjalankan sh.status() menunjukkan tidak ada migrasi chunk yang berhasil dalam riwayat terbaru, dan shard target masih menyimpan chunk yang belum dimigrasikan. Hal ini mencegah penyelesaian tugas dan menghambat operasi O&M lainnya di Konsol ApsaraDB for MongoDB.
Contoh berikut menunjukkan output khas sh.status() untuk skenario ini.
autosplit:
Currently enabled: yes
balancer:
Currently enabled: yes
Currently running: no
Balancer lock taken at Wed Sep 30 2020 02:03:11 GMT+0800 (CST) by ConfigServer:Balancer
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
No recent migrations
databases:
{ "_id" : "report", "primary" : "d-0xixxx", "partitioned" : true }
report.report
shard key: { "GsId" : "hashed" }
unique: false
balancing: true
chunks:
d-0xixxx 9
d-0xixxx 2133
d-0xixxx 2152
d-0xixxx 2116
d-0xixxx 2133
too many chunks to print, use verbose if you want to force print
Masalah ini sering terjadi karena chunk jumbo menghambat penghapusan shard. Konfirmasi hal ini dengan menjalankan perintah berikut.
db.getSiblingDB("config").chunks.aggregate([{$match: {shard: "d-xxxxxxxxxxxxxx", jumbo:true}},{$group: {_id: "$ns", count: {$sum: 1}}}])
Chunk jumbo biasanya disebabkan oleh desain kunci shard yang buruk (seperti kunci panas). Coba solusi berikut:
-
Jika versi utama MongoDB Anda adalah 4.4, gunakan perintah refineCollectionShardKey untuk meningkatkan desain kunci shard Anda dengan menambahkan sufiks guna meningkatkan kardinalitas dan menyelesaikan masalah chunk jumbo.
-
Jika versi utama MongoDB Anda adalah 5.0 atau lebih baru, gunakan perintah reshardCollection untuk melakukan sharding ulang koleksi dengan kunci shard baru. Untuk informasi lebih lanjut, lihat Reshard a Collection.
-
Jika Anda dapat menghapus beberapa data bisnis secara aman, hapus data dari chunk jumbo tersebut. Hal ini mengurangi ukurannya, sehingga berpotensi mengubahnya menjadi chunk biasa yang dapat dimigrasikan oleh Balancer.
-
Tingkatkan parameter
chunkSizeuntuk mengubah kriteria deteksi chunk jumbo. Lakukan penyesuaian ini hanya dengan bantuan insinyur dukungan teknis Alibaba Cloud.
Jika metode-metode tersebut tidak berhasil, submit a ticket untuk menghubungi dukungan teknis.
Mempercepat proses tugas penambahan atau penghapusan
Untuk menyelesaikan penambahan atau penghapusan shard lebih cepat, coba metode percepatan berikut:
-
Tingkatkan durasi jendela Balancer. Perhatikan bahwa migrasi chunk menambahkan beban tambahan yang dapat memengaruhi layanan Anda. Evaluasi risiko sebelum melakukan penyesuaian. Untuk instruksi, lihat Mengelola MongoDB Balancer.
-
Sesuaikan parameter setParameter.chunkMigrationConcurrency untuk mengubah konkurensi migrasi chunk. Untuk detailnya, lihat Rekomendasi penyetelan parameter.
-
Jalankan secara manual operasi
moveChunkselama jam sepi. Untuk informasi lebih lanjut, lihat sh.moveChunk(). Contoh:sh.moveChunk("<db>.<collection>", {"<shard_key>": <value>}, "d-xxxxxxxxxxxxx") // example: sh.moveChunk("records.people", { zipcode: "53187" }, "shard0019") -
submit a ticket untuk meminta dukungan teknis guna penyesuaian parameter kernel.