Todos los productos
Search
Centro de documentos

ApsaraDB for MongoDB:Cómo consultar el progreso de la adición o eliminación de nodos shard

Última actualización: Sep 03, 2026

Este tema describe cómo supervisar el progreso de las tareas que agregan o eliminan nodos shard y cómo identificar condiciones anómalas que podrían bloquear dichas tareas.

Contexto

Después de agregar o eliminar nodos shard de una instancia de clúster fragmentado, es posible que la tarea permanezca incompleta durante un periodo prolongado. Las siguientes secciones explican cómo solucionar este problema.

Antes de empezar, comprenda los siguientes conceptos:

  • Comprenda los modos de despliegue de las instancias de conjunto de réplicas y de clúster fragmentado de MongoDB, así como las diferencias entre estas arquitecturas. Para obtener más información, consulte Replica set architecture y Sharded cluster architecture.

  • Comprenda cómo funciona el Balancer de MongoDB. Para obtener más información, consulte Manage the MongoDB Balancer.

  • Comprenda cómo divide los datos MongoDB. MongoDB particiona los datos en chunks.

  • Conozca los comandos comunes de operación y mantenimiento para instancias de clúster fragmentado de MongoDB, como sh.status().

  • Sepa utilizar mongo shell, mongosh u otras herramientas de visualización.

Consultar el progreso de la tarea

Paso 1: Comprobar si el Balancer está habilitado

La migración de chunks durante la adición o eliminación de shards depende del Balancer. Si el Balancer está deshabilitado, ocurren los siguientes problemas:

  • Al agregar un nodo shard: Los datos de los chunks no pueden migrar al nuevo nodo shard y el nodo no puede gestionar el tráfico del servicio.

  • Al eliminar un nodo shard: Los chunks del shard objetivo no pueden migrarse, lo que bloquea la tarea de eliminación.

Habilite el Balancer para garantizar una migración normal de chunks. Para obtener instrucciones, consulte Manage the MongoDB Balancer.

Utilice uno de los siguientes métodos para comprobar si el Balancer está habilitado:

  • Método 1: Ejecute el comando sh.status().

    Si el Balancer está habilitado, la salida será similar al siguiente ejemplo.

    ...
      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
    ...

    Si la salida muestra “Currently enabled: no”, el Balancer está deshabilitado.

  • Método 2: Ejecute el comando sh.getBalancerState().

    • Si el comando devuelve true, el Balancer está habilitado.

    • Si el comando devuelve false, el Balancer está deshabilitado.

Paso 2: Comprobar si la ventana del Balancer es demasiado corta

El Balancer controla la velocidad de migración de chunks y solo migra chunks durante su ventana activa. Si la migración no finaliza dentro de la ventana actual, se reanuda en la siguiente hasta completarse. Una ventana corta puede ralentizar las tareas de adición o eliminación de shards. Para ajustar la ventana del Balancer, consulte Manage the MongoDB Balancer.

Utilice uno de los siguientes métodos para comprobar la ventana del Balancer:

  • Método 1: Ejecute el comando sh.status().

    El siguiente ejemplo muestra una ventana del Balancer de 08:30 a 11:30 hora local del servidor (3 horas en total).

    ...
      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
    ...
  • Método 2: Ejecute el comando sh.getBalancerWindow().

    El siguiente ejemplo muestra claramente la hora de la ventana, lo cual resulta especialmente útil cuando existen muchas colecciones fragmentadas.

    { "start" : "08:30", "stop" : "11:30" }

Paso 3: Recopilar la información necesaria para estimar el progreso de la tarea

Para versiones de MongoDB anteriores a la 6.0

Nota

Esta sección aplica a las siguientes versiones:

  • Instancias de MongoDB anteriores a la versión 6.0.

  • Instancias de MongoDB 6.0 con una versión menor del motor anterior a la 7.0.1 (versión base 6.0.3). Para consultar la versión menor de su motor, consulte MongoDB minor version guide.

Antes de estimar el progreso de la tarea, obtenga estadísticas de ejecución del Balancer (recuentos de éxitos y fallos) e información de chunks para las colecciones fragmentadas pendientes de migración.

Puede obtener los resultados de ejecución del Balancer y la información sobre los chunks de las tablas fragmentadas pendientes de migración mediante los dos métodos siguientes:

  • Método 1: Utilice la salida del comando sh.status().

    Céntrese en dos partes de la salida de sh.status(). La primera parte muestra los resultados recientes del Balancer, como en este ejemplo.

    ...
      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:
    ...

    La segunda parte muestra detalles de los chunks para las colecciones fragmentadas, como en este ejemplo.

    ...
    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
    ...

    En este ejemplo, “d-xxxxxxxxxxxxxxx5” es el nodo shard recién agregado. También puede ejecutar el comando getShardDistribution en la base de datos que contiene la colección fragmentada para obtener detalles de la distribución de chunks, como se muestra a continuación.

    use <db>
    db.<collection>.getShardDistribution()
  • Método 2: Lea los datos relevantes directamente desde la base de datos config.

    Consulte las estadísticas de chunks agregadas por shard de la siguiente manera.

    db.getSiblingDB("config").chunks.aggregate([{$group: {_id: "$shard", count: {$sum: 1}}}])

    Para ver los chunks en un shard específico agrupados por namespace, ejecute el siguiente comando.

    db.getSiblingDB("config").chunks.aggregate([{$match: {shard: "d-xxxxxxxxxxxxxx"}},{$group: {_id: "$ns", count: {$sum: 1}}}])

    Para contar los chunks migrados correctamente a un nodo shard específico en las últimas 24 horas, ejecute el siguiente comando.

    // details.to specifies the destination shard for chunk migration
    // Use ISODate to define the time range in the time field
    db.getSiblingDB("config").changelog.find({"what" : "moveChunk.commit", "details.to" : "d-xxxxxxxxxxxxx","time" : {"$gte": ISODate("2023-09-26T00:00:00")}}).count()

Para versiones de MongoDB 6.0 y posteriores

Nota

Esta sección aplica a las siguientes versiones:

  • Instancias de MongoDB versión 6.0 y posteriores.

  • Instancias de MongoDB 6.0 con una versión menor del motor 7.0.1 (versión base 6.0.3) o posterior. Para consultar la versión menor de su motor, consulte MongoDB minor version guide.

Antes de estimar el progreso de la tarea, céntrese en la distribución de datos entre los shards. Aún puede usar la salida de sh.status() como referencia, pero cambie el enfoque del recuento desigual de chunks a la distribución real del volumen de datos.

  • Obtenga información sobre la distribución de colecciones fragmentadas y el equilibrio de datos.

    Use el comando getShardDistribution para obtener detalles de la distribución y centrarse en el equilibrio de datos. Ejemplo:

    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 : 48B

    También puede ejecutar el siguiente comando para obtener información de distribución más detallada (incluido el recuento de documentos, el tamaño total, el recuento de documentos huérfanos y el tamaño de huérfanos):

    db.getSiblingDB("admin").aggregate( [{ $shardedDataDistribution: { } },{ $match: { "ns": "<db>.<collection>" } }] ).pretty()

    El siguiente ejemplo de salida muestra un desequilibrio notable de datos entre los shards.

    {
            "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
                    }
              ]
    }

    A partir de esta salida, puede determinar que la instancia tiene 4 nodos shard y que el volumen total de datos para la colección fragmentada <db>.<collection> es de aproximadamente 2051303530231 bytes (833101815840 + 409714745937 + 178157177704 + 630329790750 = 2051303530231), o alrededor de 1910.4 GB.

  • Consulte el volumen de datos migrados correctamente durante el último día.

    Ejecute la siguiente consulta:

    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)

    Salida de ejemplo:

    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") }

    Esta salida muestra que el 2024-09-21 se migraron 183117965820 bytes (aproximadamente 170.5 GB).

Paso 4: Estimar el progreso de la tarea y el tiempo de finalización

Para versiones de MongoDB anteriores a la 6.0

Nota

Esta sección aplica a las siguientes versiones:

  • Instancias de MongoDB anteriores a la versión 6.0.

  • Instancias de MongoDB 6.0 con una versión menor del motor anterior a la 7.0.1 (versión base 6.0.3). Para consultar la versión menor de su motor, consulte MongoDB minor version guide.

Después de obtener el número de chunks migrados correctamente y la distribución actual de datos, estime el progreso general de la tarea y el tiempo esperado de finalización.

Suponga las siguientes condiciones ideales durante la adición de shards: el recuento total de chunks permanece constante, el recuento de shards se mantiene fijo (sin adiciones ni eliminaciones concurrentes de shards), la carga del servicio permanece estable y los parámetros del Balancer usan valores predeterminados. Con el ejemplo de Step 3 en Para versiones de MongoDB anteriores a la 6.0, se sabe que:

  • Hay 5 nodos shard.

  • Se migraron 300 chunks correctamente durante la ventana del Balancer.

  • La colección fragmentada <db>.<collection> tiene 58260 chunks en total (13630 + 13629 + 13652 + 13630 + 3719 = 58260).

Por lo tanto, se puede calcular lo siguiente:

  • En equilibrio, cada shard debería contener 11652 chunks (58260 ÷ 5 = 11652).

  • A la tasa de migración actual, la finalización de la tarea requiere otros 26.4 días ((11652 – 3719) ÷ 300 ≈ 26.4).

  • La tarea de adición de shards tiene un 32 % de avance (3719 ÷ 11652 = 32 %).

Nota

En escenarios reales, el recuento total de chunks aumenta debido a escrituras continuas y divisiones de chunks. Este cálculo asume condiciones ideales; el tiempo real de finalización podría ser mayor.

Para versiones de MongoDB 6.0 y posteriores

Nota

Esta sección aplica a las siguientes versiones:

  • Instancias de MongoDB versión 6.0 y posteriores.

  • Instancias de MongoDB 6.0 con una versión menor del motor 7.0.1 (versión base 6.0.3) o posterior. Para consultar la versión menor de su motor, consulte MongoDB minor version guide.

Suponga que la instancia de clúster fragmentado tiene solo una colección que requiere balanceo. Con el ejemplo de Step 3 en Para versiones de MongoDB 6.0 y posteriores, se sabe que:

  • Hay 4 nodos shard.

  • El 2024-09-21, se migraron aproximadamente 170.5 GB (183117965820 bytes).

  • La colección fragmentada <db>.<collection> tiene un volumen total de datos de aproximadamente 1910.4 GB (2051303530231 bytes).

Por lo tanto, se puede calcular lo siguiente:

  • En equilibrio, cada shard debería contener aproximadamente 477.6 GB (512825882557.75 bytes).

  • El volumen total de datos que necesita migrarse para alcanzar el equilibrio es de 875559682949 bytes (815.4 GB), desglosado de la siguiente manera:

    Shard1 necesita migrar 320275933282.25 bytes (833101815840 – 512825882557.75).

    Shard2 necesita migrar 103111136620.75 bytes (409714745937 – 512825882557.75).

    Shard3 necesita migrar 334668704853.75 bytes (178157177704 – 512825882557.75).

    Shard4 necesita migrar 117503908192.25 bytes (630329790750 – 512825882557.75).

    (320275933282.25 + 103111136620.75 + 334668704853.75 + 117503908192.25 = 875559682949)

  • A la tasa de migración actual, el equilibrio se alcanzará en aproximadamente 4.8 días (815.4 GB ÷ 170.5 GB/día ≈ 4.8 días).

Paso 5: Comprobar si el flujo de la tarea está bloqueado (eliminación de shard)

Si la tarea de eliminación de shard está bloqueada, la salida de sh.status() no muestra migraciones de chunks exitosas en periodos recientes, y el shard que se está eliminando todavía tiene chunks que no han migrado. En este caso, la tarea de eliminación de shard no puede completarse y otras operaciones de administración y mantenimiento en la instancia desde la consola de ApsaraDB for MongoDB también se ven afectadas.

El siguiente ejemplo muestra la salida de sh.status() en este escenario.

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

Es probable que este problema sea causado por chunks jumbo que bloquean el proceso de eliminación del shard. Ejecute el siguiente comando para buscar chunks jumbo.

db.getSiblingDB("config").chunks.aggregate([{$match: {shard: "d-xxxxxxxxxxxxxx", jumbo:true}},{$group: {_id: "$ns", count: {$sum: 1}}}])

Los chunks jumbo suelen ser causados por un diseño inadecuado de clave de shard, como claves calientes. Antes de continuar, clasifique los chunks jumbo en una de las siguientes categorías:

  • Divisible: El tamaño del chunk supera chunkSize, pero el chunk aún puede dividirse en chunks más pequeños según la clave de shard. No se requiere manejo especial. El Balancer migra el chunk después de dividirlo.

  • No divisible: La mayoría de los datos en el chunk comparten el mismo valor de clave de shard (clave caliente). El tamaño de los datos supera chunkSize y el chunk no puede dividirse. Utilice uno de los siguientes métodos para manejar este tipo.

Pruebe los siguientes métodos según sus requisitos empresariales:

  • Método 1: Optimizar el diseño de la clave de shard (solución raíz para problemas de claves calientes)

    • Para MongoDB 4.4 o posterior, utilice el comando refineCollectionShardKey para agregar campos de sufijo a la clave de shard existente. Esto aumenta la cardinalidad de la clave de shard y hace que los chunks jumbo previamente indivisibles sean divisibles.

    • Para MongoDB 5.0 o posterior, también puede utilizar el comando reshardCollection para volver a fragmentar la colección con una nueva clave de shard. Para obtener más información, consulte Reshard a Collection.

  • Método 2: Migrar el chunk jumbo (para MongoDB 4.4 o posterior, por ejemplo, cuando un chunk jumbo no puede migrarse durante la eliminación de un shard)

    • Opción 1 (recomendada): Ejecute el comando clearJumboFlag para borrar la marca jumbo del chunk y luego establezca el parámetro del Balancer attemptToBalanceJumboChunks en true para permitir que el Balancer migre automáticamente el chunk. Este método no bloquea las escrituras durante la copia de datos. Las escrituras se bloquean solo brevemente durante la etapa final de la migración.

      Importante
      • Si el volumen de escritura en el chunk es alto, la migración puede fallar debido al desbordamiento de la caché incremental. Después del fallo, el chunk se vuelve a marcar como jumbo. Borre la marca nuevamente y reintente.

      • Una vez que la migración tenga éxito, establezca inmediatamente attemptToBalanceJumboChunks de nuevo en false. Para MongoDB 6.0 o posterior, el Balancer equilibra basándose en las diferencias de volumen de datos entre shards. Después de que el chunk sobredimensionado se migra a cualquier shard, ese shard se convierte en el valor atípico del volumen de datos. Si no restaura la configuración, el Balancer migrará el chunk de ida y vuelta entre shards, causando transferencia continua de datos y sobrecarga por limpieza de documentos huérfanos. Después de restaurar la configuración, el chunk se vuelve a marcar como jumbo cuando falla el siguiente intento de migración regular y ya no se mueve. Esto es esperado y no requiere borrar la marca nuevamente.

    • Opción 2: Ejecute el comando moveChunk con la opción forceJumbo: true. Este método bloquea todas las escrituras en la colección del shard origen durante la copia de datos, lo cual puede durar horas para chunks grandes. Utilice este método solo fuera de horas pico o cuando las escrituras puedan pausarse. Se recomienda realizar esta operación con asistencia del soporte técnico de Alibaba Cloud.

  • Método 3: Eliminar datos. Si algunos datos empresariales pueden eliminarse, quite datos del chunk jumbo para reducir su tamaño. Nota: Después de que el chunk se vuelve más pequeño, la marca jumbo no se borra automáticamente. Todavía debe ejecutar el comando clearJumboFlag (o esperar hasta que el chunk se divida correctamente) antes de que el Balancer pueda migrarlo.

  • Método 4: Aumentar el parámetro chunkSize. Aumente el parámetro chunkSize para cambiar el umbral de chunk jumbo. Este método es efectivo solo cuando el tamaño real del chunk excede ligeramente el umbral actual. No ayuda con chunks sobredimensionados causados por claves calientes. Se recomienda realizar esta operación con asistencia del soporte técnico de Alibaba Cloud.

Si ninguno de los métodos anteriores resuelve el problema, envíe un ticket para contactar al soporte técnico.

Acelerar los procesos de tareas de adición o eliminación

Para completar la adición o eliminación de shards más rápido, pruebe estos métodos de aceleración:

  • Aumente la duración de la ventana del Balancer. Tenga en cuenta que la migración de chunks agrega carga adicional que puede afectar su servicio. Evalúe los riesgos antes de ajustar. Para obtener instrucciones, consulte Manage the MongoDB Balancer.

  • Ajuste el parámetro setParameter.chunkMigrationConcurrency para cambiar la concurrencia de migración de chunks. Para obtener detalles, consulte Parameter tuning recommendations.

  • Ejecute manualmente operaciones moveChunk fuera de horas pico. Para obtener más información, consulte sh.moveChunk(). Ejemplo:

    sh.moveChunk("<db>.<collection>", {"<shard_key>": <value>}, "d-xxxxxxxxxxxxx")
    // example: 
    sh.moveChunk("records.people", { zipcode: "53187" }, "shard0019")
  • envíe un ticket para solicitar ajustes de parámetros del kernel al soporte técnico.

Referencias