All Products
Search
Document Center

ApsaraDB for MongoDB:Jumlah chunk tidak seimbang di seluruh shard setelah upgrade MongoDB

Last Updated:Aug 25, 2026

Setelah Anda melakukan upgrade instans kluster sharded ApsaraDB for MongoDB ke MongoDB 6.0 (versi minor 7.0.1 atau lebih baru) atau versi utama yang lebih baru, menjalankan sh.status() mungkin menunjukkan bahwa jumlah chunk tidak merata di seluruh shard—terkadang hanya satu chunk per shard. Topik ini menjelaskan mengapa hal ini terjadi dan cara menilai dengan benar apakah data tetap seimbang.

Gejala

Beberapa pengguna melaporkan bahwa setelah melakukan upgrade instans kluster sharded ApsaraDB for MongoDB ke MongoDB 6.0 (versi minor 7.0.1 atau lebih baru), sh.status() menunjukkan bahwa jumlah chunk di seluruh shard tidak lagi kira-kira sama, berbeda dengan kondisi sebelum upgrade. Pengamatan umum meliputi:

  • MongoDB 6.0 (minor 7.0.1 dan seterusnya): Jumlah chunk sangat bervariasi antar shard.

  • MongoDB 7.0 dan seterusnya: Setiap shard mungkin hanya menyimpan satu chunk.

Anda mungkin bertanya-tanya:

  • Apakah data tidak lagi terdistribusi secara merata?

  • Apakah balancer rusak?

  • Apakah proses upgrade gagal?

Catatan

Ini adalah perilaku yang diharapkan setelah upgrade. Data Anda tetap terdistribusi secara merata, dan tidak diperlukan tindakan apa pun. Balancer baru tidak lagi menggunakan jumlah chunk sebagai kriteria penyeimbangan, melainkan menggunakan ukuran data aktual.

Mengapa hal ini terjadi

Perilaku sebelum MongoDB 6.0 minor 7.0.1

Sebelum ApsaraDB for MongoDB 6.0 minor 7.0.1, kluster sharded menyeimbangkan data sebagai berikut:

  1. Ukuran chunk default adalah 64 MB.

  2. Ketika sebuah chunk melebihi 64 MB, chunk tersebut akan secara otomatis dipisah (AutoSplit) menjadi chunk yang lebih kecil.

  3. Balancer secara berkala memeriksa jumlah chunk pada setiap shard dan memigrasikan chunk (moveChunk) begitu perbedaan melebihi ambang batas migrasi.

  4. Akhirnya, setiap shard menyimpan banyak chunk dengan jumlah yang kira-kira sama.

Dalam model ini, sh.status() menampilkan beberapa chunk per shard, sehingga memberikan kesan intuitif bahwa data terdistribusi secara merata.

Perubahan dalam MongoDB 6.0 mulai dari minor 7.0.1 (community 6.0.3)

Mulai dari ApsaraDB for MongoDB 6.0 minor 7.0.1, yang sesuai dengan MongoDB community 6.0.3, balancer memperkenalkan perubahan berikut:

  • AutoSplit dihapus: Chunk tidak lagi dipisah secara otomatis saat penuh. Pemisahan hanya terjadi jika diperlukan sebelum migrasi.

  • Kriteria penyeimbangan baru: Dari jumlah chunk menjadi ukuran data aktual.

  • Ambang batas migrasi disesuaikan: Migrasi dipicu ketika ukuran koleksi yang sama berbeda lebih dari tiga kali ukuran chunk di seluruh shard. (Ukuran chunk default mulai dari ApsaraDB for MongoDB 6.0 adalah 128 MB, artinya ambang batasnya adalah 384 MB.)

  • Perubahan terminologi: Konsep chunk kurang ditekankan, digantikan oleh "range". moveChunk digantikan oleh moveRange.

  • Anda tidak perlu lagi menjalankan sh.enableSharding() sebelum melakukan sharding pada koleksi.

Efek: Karena AutoSplit dihapus dan jumlah chunk tidak lagi menjadi kriteria penyeimbangan, jumlah chunk di seluruh shard mungkin menjadi tidak merata, yang merupakan hal normal. Untuk informasi lebih lanjut, lihat sh.enableAutoSplit().

Baru di MongoDB 7.0: AutoMerger

MongoDB 7.0 memperkenalkan fitur AutoMerger:

  • Balancer secara otomatis menggabungkan chunk yang bersebelahan dan dapat digabung pada shard yang sama.

  • AutoMerger berjalan di latar belakang sebagai bagian dari operasi penyeimbangan dan diaktifkan secara default.

  • Fitur ini berjalan setiap autoMergerIntervalSecs detik.

  • Jika jendela penyeimbangan dikonfigurasi, AutoMerger hanya berjalan dalam jendela tersebut.

Efek: Di MongoDB 7.0 dan seterusnya, AutoMerger pada akhirnya dapat mengonsolidasi chunk pada setiap shard menjadi satu chunk tunggal. Hal ini juga normal. Untuk informasi lebih lanjut, lihat AutoMerger.

Mengapa perubahan ini dilakukan

Balancer berbasis jumlah chunk pada versi lama memiliki beberapa kelemahan:

Masalah

Deskripsi

Jumbo chunks

Ketika kunci shard memiliki kardinalitas rendah, semua dokumen dalam sebuah chunk memiliki nilai kunci yang sama, sehingga chunk tersebut tidak dapat dipisah. Shard mungkin memiliki jumlah chunk yang sama tetapi penggunaan disk yang sangat berbeda.

Write skew

Jika kunci shard range mengandung komponen yang meningkat secara monoton, tulisan baru terkonsentrasi pada satu shard saja.

Konsumsi resource

Operasi AutoSplit dan moveChunk yang sering mengonsumsi sumber daya CPU signifikan dan berdampak pada performa workload.

Menggunakan ukuran data aktual sebagai kriteria penyeimbangan memberikan gambaran distribusi data yang lebih akurat dan mengurangi pemisahan serta migrasi chunk yang tidak perlu.

Pemetaan versi

Versi ApsaraDB for MongoDB

Versi Community

Perilaku balancer

MongoDB 4.4

MongoDB 4.4

Lama: AutoSplit + penyeimbangan berbasis jumlah chunk

MongoDB 5.0

MongoDB 5.0

Lama: AutoSplit + penyeimbangan berbasis jumlah chunk

MongoDB 6.0 (minor 7.0.0)

MongoDB 6.0.0

Lama: AutoSplit + penyeimbangan berbasis jumlah chunk

MongoDB 6.0 (minor 7.0.1 dan seterusnya)

MongoDB 6.0.3

AutoSplit dihapus + penyeimbangan berbasis ukuran (jumlah chunk mungkin tidak merata)

MongoDB 7.0 dan seterusnya

MongoDB 7.0+

AutoSplit dihapus + penyeimbangan berbasis ukuran + AutoMerger mengonsolidasi chunk

Perbandingan lintas versi

Item

MongoDB 6.0 (sebelum minor 7.0.1)

MongoDB 6.0 (minor 7.0.1 dan seterusnya)

MongoDB 7.0 dan seterusnya

AutoSplit

Diaktifkan. Chunk dipisah secara otomatis saat penuh.

Dinonaktifkan

Dimatikan

AutoMerger

Tidak tersedia

Tidak tersedia

Diaktifkan. Chunk digabung secara otomatis.

Kriteria penyeimbangan

Jumlah chunk

Ukuran data aktual

Ukuran data aktual

Jumlah chunk per shard

Banyak, kira-kira sama

Tidak merata, mungkin berbeda antar shard

Mungkin konvergen menjadi satu

Ambang batas migrasi

Perbedaan jumlah chunk ≥ 1 (MongoDB 4.2 dan seterusnya)

Ukuran data berbeda lebih dari tiga kali ukuran chunk

Ukuran data berbeda lebih dari tiga kali ukuran chunk

enableSharding

Diperlukan sebelum sharding

Opsional di MongoDB 6.0 dan seterusnya

Opsional

Cara menilai keseimbangan

sh.status() jumlah chunk

getShardDistribution() ukuran data

getShardDistribution() ukuran data

Data uji

Hasil berikut diukur setelah tool YCSB memasukkan 50 juta record ke instans kluster sharded ApsaraDB for MongoDB yang menjalankan MongoDB 4.4, MongoDB 6.0, dan MongoDB 8.0.

MongoDB 4.4 (perilaku lama)

Jalankan sh.status(). Fokus pada bidang chunkMetadata dalam output. Setiap shard memiliki 435 chunk, dan jumlahnya sama. Ini adalah hasil dari mekanisme AutoSplit lama:

mongos> sh.status()
shardingVersion
{ _id: 1, clusterId: ObjectId('69fbfda6dec76b373f5eda81') }
---
shards
[
  {
    _id: 'd-uf6xxxx1',
    host: 'mgset-1xxxxx0/192.168.XX.2:3005,192.168.XX.11:3002',
    state: 1
  },
  {
    _id: 'd-uf6xxxx2',
    host: 'mgset-1xxxxx1/192.168.XX.4:3002,192.168.XX.5:3002',
    state: 1
  }
]
---
active mongoses
[ { '4.4.30': 2 } ]
---
autosplit
{ 'Currently enabled': 'yes' }
---
balancer
{
  'Currently enabled': 'yes',
  'Failed balancer rounds in last 5 attempts': 0,
  'Currently running': 'no',
  'Migration Results for the last 24 hours': { '947': 'Success' }
}
---
databases
[
  {
    database: {
      _id: 'ycsb',
      primary: 'd-uf6xxxx2',
      partitioned: true
    },
    collections: {
      'ycsb.test1': {
        shardKey: { _id: 'hashed' },
        unique: false,
        balancing: true,
        chunkMetadata: [
          { shard: 'd-uf6xxxx1', nChunks: 435 },
          { shard: 'd-uf6xxxx2', nChunks: 435 }
        ],
        chunks: [
          'too many chunks to print, use verbose if you want to force print'
        ],
        tags: []
      }
    }
  }
]

Jalankan db.test1.getShardDistribution(). Fokus pada bidang data (ukuran data) dan chunks (jumlah chunk) untuk setiap shard:

mongos> use ycsb
switched to db ycsb
mongos> db.test1.getShardDistribution()
Shard d-uf6xxxx1 at mgset-1xxxxx0/192.168.XX.2:3005,192.168.XX.11:3002
{
  data: '27.2GiB',
  docs: 25014674,
  chunks: 435,
  'estimated data per chunk': '64.04MiB',
  'estimated docs per chunk': 57504
}
---
Shard d-uf6xxxx2 at mgset-1xxxxx1/192.168.XX.4:3002,192.168.XX.5:3002
{
  data: '36.23GiB',
  docs: 33313293,
  chunks: 435,
  'estimated data per chunk': '85.29MiB',
  'estimated docs per chunk': 76582
}
---
Totals
{
  data: '63.44GiB',
  docs: 58327967,
  chunks: 870,
  'Shard d-uf6xxxx1': [
    '42.88 % data',
    '42.88 % docs in cluster',
    '1KiB avg obj size on shard'
  ],
  'Shard d-uf6xxxx2': [
    '57.11 % data',
    '57.11 % docs in cluster',
    '1KiB avg obj size on shard'
  ]
}

MongoDB 6.0 (minor 7.0.1 dan seterusnya)

Jalankan sh.status(). Fokus pada bidang chunkMetadata. Jumlah chunk terlihat sangat tidak merata di seluruh shard (216 vs. 1):

mongos> sh.status()
shardingVersion
{ _id: 1, clusterId: ObjectId('69fbfdc420578638757c1d06') }
---
shards
[
  {
    _id: 'd-uf6xxxx3',
    host: 'mgset-1xxxxx2/192.168.XX.7:3002,192.168.XX.8:3002',
    state: 1,
    topologyTime: Timestamp({ t: 1778122310, i: 2 })
  },
  {
    _id: 'd-uf6xxxx4',
    host: 'mgset-1xxxxx3/192.168.XX.9:3002,192.168.XX.10:3002',
    state: 1,
    topologyTime: Timestamp({ t: 1778122310, i: 9 })
  }
]
---
active mongoses
[ { '6.0.27': 2 } ]
---
autosplit
{ 'Currently enabled': 'yes' }
---
balancer
{
  'Currently running': 'no',
  'Currently enabled': 'yes',
  'Failed balancer rounds in last 5 attempts': 0,
  'Migration Results for the last 24 hours': { '216': 'Success' }
}
---
databases
[
  {
    database: {
      _id: 'ycsb',
      primary: 'd-uf6xxxx4',
      partitioned: false,
      version: {
        uuid: UUID('4ee45231-9585-4dba-8f34-f624860e1a79'),
        timestamp: Timestamp({ t: 1778122930, i: 1 }),
        lastMod: 1
      }
    },
    collections: {
      'ycsb.test2': {
        shardKey: { _id: 'hashed' },
        unique: false,
        balancing: true,
        allowMigrations: true,
        chunkMetadata: [
          { shard: 'd-uf6xxxx3', nChunks: 216 },
          { shard: 'd-uf6xxxx4', nChunks: 1 }
        ],
        chunks: [
          'too many chunks to print, use verbose if you want to force print'
        ],
        tags: []
      }
    }
  }
]

Jalankan db.test2.getShardDistribution(). Fokus pada persentase data untuk setiap shard. Meskipun terdapat perbedaan besar dalam jumlah chunk (216 vs. 1), data tetap terdistribusi secara merata (50,31% vs. 49,68%):

mongos> use ycsb
switched to db ycsb
mongos> db.test2.getShardDistribution()
Shard d-uf6xxxx4 at mgset-1xxxxx3/192.168.XX.9:3002,192.168.XX.10:3002
{
  data: '27.36GiB',
  docs: 32285618,
  chunks: 1,
  'estimated data per chunk': '27.36GiB',
  'estimated docs per chunk': 32285618
}
---
Shard d-uf6xxxx3 at mgset-1xxxxx2/192.168.XX.7:3002,192.168.XX.8:3002
{
  data: '27.01GiB',
  docs: 24841944,
  chunks: 216,
  'estimated data per chunk': '128.09MiB',
  'estimated docs per chunk': 115009
}
---
Totals
{
  data: '54.38GiB',
  docs: 57127562,
  chunks: 217,
  'Shard d-uf6xxxx4': [
    '50.31 % data',
    '56.51 % docs in cluster',
    '1KiB avg obj size on shard'
  ],
  'Shard d-uf6xxxx3': [
    '49.68 % data',
    '43.48 % docs in cluster',
    '1KiB avg obj size on shard'
  ]
}

MongoDB 8.0 (dengan AutoMerger)

Segera setelah migrasi selesai, jalankan sh.status(). Fokus pada bidang chunkMetadata. Setiap shard masih memiliki beberapa chunk (55 vs. 1):

mongos> sh.status()
shardingVersion
{ _id: 1, clusterId: ObjectId('69fbfdbdd7b0e3d9551dd833') }
---
shards
[
  {
    _id: 'd-uf6xxxx5',
    host: 'mgset-1xxxxx4/192.168.XX.1:3000,192.168.XX.3:3002',
    state: 1,
    topologyTime: Timestamp({ t: 1778122320, i: 8 }),
    replSetConfigVersion: Long('-1')
  },
  {
    _id: 'd-uf6xxxx6',
    host: 'mgset-1xxxxx5/192.168.XX.5:3003,192.168.XX.6:3003',
    state: 1,
    topologyTime: Timestamp({ t: 1778122319, i: 10 }),
    replSetConfigVersion: Long('-1')
  }
]
---
active mongoses
[ { '8.0.18': 2 } ]
---
autosplit
{ 'Currently enabled': 'yes' }
---
balancer
{
  'Currently enabled': 'yes',
  'Failed balancer rounds in last 5 attempts': 0,
  'Currently running': 'no',
  'Migration Results for the last 24 hours': { '216': 'Success' }
}
---
databases
[
  {
    database: {
      _id: 'ycsb',
      primary: 'd-uf6xxxx6',
      version: {
        uuid: UUID('98799357-048e-45bc-a472-387165e0fe74'),
        timestamp: Timestamp({ t: 1778122931, i: 2 }),
        lastMod: 1
      }
    },
    collections: {
      'ycsb.test2': {
        shardKey: { _id: 'hashed' },
        unique: false,
        balancing: true,
        allowMigrations: true,
        chunkMetadata: [
          { shard: 'd-uf6xxxx5', nChunks: 55 },
          { shard: 'd-uf6xxxx6', nChunks: 1 }
        ],
        chunks: [
          'too many chunks to print, use verbose if you want to force print'
        ],
        tags: []
      }
    }
  }
]

Setelah AutoMerger selesai, jalankan sh.status() lagi. Fokus pada bidang chunkMetadata. Setiap shard kini hanya memiliki satu chunk:

mongos> sh.status()
shardingVersion
{ _id: 1, clusterId: ObjectId('69fbfdbdd7b0e3d9551dd833') }
---
shards
[
  {
    _id: 'd-uf6xxxx5',
    host: 'mgset-1xxxxx4/192.168.XX.1:3000,192.168.XX.3:3002',
    state: 1,
    topologyTime: Timestamp({ t: 1778122320, i: 8 }),
    replSetConfigVersion: Long('-1')
  },
  {
    _id: 'd-uf6xxxx6',
    host: 'mgset-1xxxxx5/192.168.XX.5:3003,192.168.XX.6:3003',
    state: 1,
    topologyTime: Timestamp({ t: 1778122319, i: 10 }),
    replSetConfigVersion: Long('-1')
  }
]
---
active mongoses
[ { '8.0.18': 2 } ]
---
autosplit
{ 'Currently enabled': 'yes' }
---
balancer
{
  'Currently enabled': 'yes',
  'Failed balancer rounds in last 5 attempts': 0,
  'Currently running': 'no',
  'Migration Results for the last 24 hours': { '216': 'Success' }
}
---
databases
[
  {
    database: {
      _id: 'ycsb',
      primary: 'd-uf6xxxx6',
      version: {
        uuid: UUID('98799357-048e-45bc-a472-387165e0fe74'),
        timestamp: Timestamp({ t: 1778122931, i: 2 }),
        lastMod: 1
      }
    },
    collections: {
      'ycsb.test2': {
        shardKey: { _id: 'hashed' },
        unique: false,
        balancing: true,
        allowMigrations: true,
        chunkMetadata: [
          { shard: 'd-uf6xxxx5', nChunks: 1 },
          { shard: 'd-uf6xxxx6', nChunks: 1 }
        ],
        chunks: [
          { min: { _id: MinKey() }, max: { _id: Long('-58615400192952365') }, 'on shard': 'd-uf6xxxx5', 'last modified': Timestamp({ t: 217, i: 2 }) },
          { min: { _id: Long('-58615400192952365') }, max: { _id: MaxKey() }, 'on shard': 'd-uf6xxxx6', 'last modified': Timestamp({ t: 217, i: 1 }) }
        ],
        tags: []
      }
    }
  }
]

Jalankan db.test2.getShardDistribution(). Fokus pada persentase data. Meskipun setiap shard hanya memiliki satu chunk, data tetap terdistribusi secara merata (49,67% vs. 50,32%):

mongos> use ycsb
switched to db ycsb
mongos> db.test2.getShardDistribution()
Shard d-uf6xxxx5 at mgset-1xxxxx4/192.168.XX.1:3000,192.168.XX.3:3002
{
  data: '27.01GiB',
  docs: 24841944,
  chunks: 1,
  'estimated data per chunk': '27.01GiB',
  'estimated docs per chunk': 24841944
}
---
Shard d-uf6xxxx6 at mgset-1xxxxx5/192.168.XX.5:3003,192.168.XX.6:3003
{
  data: '27.37GiB',
  docs: 35898246,
  chunks: 1,
  'estimated data per chunk': '27.37GiB',
  'estimated docs per chunk': 35898246
}
---
Totals
{
  data: '54.39GiB',
  docs: 60740190,
  chunks: 2,
  'Shard d-uf6xxxx5': [
    '49.67 % data',
    '40.89 % docs in cluster',
    '1KiB avg obj size on shard'
  ],
  'Shard d-uf6xxxx6': [
    '50.32 % data',
    '59.1 % docs in cluster',
    '1KiB avg obj size on shard'
  ]
}

Kesimpulan: Data uji pada ketiga versi menunjukkan bahwa terlepas dari perubahan jumlah chunk (870 → 217 → 2), data tetap terdistribusi secara merata di seluruh shard. Perbedaan jumlah chunk semata-mata disebabkan oleh perubahan manajemen internal dan tidak memengaruhi distribusi data aktual atau workload Anda.

Cara menilai keseimbangan data dengan benar

Setelah Anda melakukan upgrade ke MongoDB 6.0 (minor 7.0.1) atau lebih baru, gunakan metode berikut untuk mengevaluasi keseimbangan:

Disarankan: getShardDistribution()

Sambungkan ke mongos dan jalankan:

use <your_database>
db.<your_collection>.getShardDistribution()

Perintah ini menampilkan ukuran data, jumlah dokumen, dan persentase koleksi pada setiap shard, memberikan gambaran akurat tentang distribusi.

Helper: db.stats()

use <your_database>
db.stats()

Mengembalikan penggunaan penyimpanan keseluruhan database di seluruh shard.

Tidak lagi disarankan: jumlah chunk pada sh.status()

sh.status() masih berfungsi, tetapi jumlah chunk tidak lagi mencerminkan keseimbangan data. Jumlah chunk yang tidak merata atau satu chunk per shard adalah hal normal dan tidak menunjukkan adanya masalah pada distribusi data.

FAQ

T: Apakah saya akan kehilangan data jika jumlah chunk menjadi tidak merata atau turun menjadi satu setelah upgrade?

J: Tidak. Chunk hanyalah unit logis internal yang digunakan MongoDB untuk mengelola data. Perubahan jumlah chunk tidak memengaruhi data aktual, yang tetap utuh pada setiap shard.

T: Apakah saya perlu menjalankan perintah split secara manual untuk memisah chunk?

J: Tidak. Balancer baru memisah data sesuai kebutuhan sebelum migrasi. Tidak diperlukan intervensi manual.

T: Apakah balancer masih berfungsi setelah upgrade?

J: Ya. Balancer terus beroperasi tetapi menggunakan ukuran data sebagai kriterianya, bukan jumlah chunk. Ketika perbedaan ukuran data antar shard melebihi ambang batas, balancer akan memigrasikan data secara otomatis.

T: Apa perbedaan perilaku chunk antara MongoDB 6.0 dan MongoDB 7.0 setelah upgrade?

J: MongoDB 6.0 (minor 7.0.1 dan seterusnya) menghapus AutoSplit dan menggunakan penyeimbangan berbasis ukuran, sehingga jumlah chunk di seluruh shard mungkin tidak merata. MongoDB 7.0 menambahkan AutoMerger di atasnya, yang mengonsolidasi chunk. Setiap shard pada akhirnya mungkin hanya menyimpan satu chunk. Dalam kedua kasus, data tetap terdistribusi secara merata.

T: Apakah wajar jika terdapat banyak chunk selama migrasi?

J: Ya. Balancer melakukan pemisahan yang diperlukan selama migrasi, sehingga beberapa chunk mungkin muncul sementara. Di MongoDB 7.0 dan seterusnya, AutoMerger akan mengonsolidasinya setelah migrasi selesai. Di MongoDB 6.0, chunk tersebut mungkin tetap ada, tetapi keseimbangan data tidak terpengaruh.

T: Apakah perubahan ini memengaruhi beban kerja saya?

J: Tidak. Perubahan ini transparan bagi aplikasi. Bahkan, perilaku baru ini mengurangi pemisahan dan migrasi yang tidak perlu, yang sering kali meningkatkan performa.

Referensi