El balanceador de MongoDB es un proceso en segundo plano que supervisa la cantidad de datos en cada partición para cada colección particionada. Cuando la cantidad de datos para una colección particionada en una partición dada alcanza niveles específicos Umbrales de migración: el balanceador intenta migrar automáticamente los datos entre fragmentos y alcanzar una cantidad uniforme de datos por fragmento, respetando las zonas. De forma predeterminada, el proceso del balanceador siempre está habilitado.
El procedimiento de equilibrio para clústeres fragmentados es completamente transparente para la capa de usuario y de aplicación, aunque puede haber algún impacto en el rendimiento mientras se lleva a cabo el procedimiento.
El balanceador se ejecuta en el primario del set de réplicas del servidor de configuración (CSRS).
Para configurar el balanceo de la colección para una sola colección, consulta
configureCollectionBalancing.
Para administrar el balanceador de clústeres, consulta Gestión del balanceador de clústeres.
Internos del Balanceador
Las migraciones de rangos conllevan cierta sobrecarga en términos de ancho de banda y carga de trabajo, lo cual puede afectar el rendimiento de la base de datos. El balanceador intenta minimizar el impacto mediante:
Restringir una partición a, como máximo, una migración en un momento dado. Específicamente, una partición no puede participar en múltiples migraciones de datos al mismo tiempo. El balanceador migra los rangos uno a la vez.
MongoDB puede realizar migraciones de datos en paralelo, pero cada fragmento puede participar en una sola migración a la vez. Para un clúster fragmentado con n fragmentos, MongoDB puede realizar un máximo de n/2 migraciones simultáneas (redondeado hacia abajo).
Consultetambién Limpieza de migración de rango asincrónica.
Iniciar una ronda de equilibrado solamente cuando la diferencia en la cantidad de datos entre la partición con más datos para una colección particionada y la partición con menos datos para esa colección alcance el umbral de migración.
Puede deshabilitar el balanceador temporalmente para realizar tareas de mantenimiento, pero dejarlo deshabilitado durante períodos prolongados puede reducir el rendimiento del clúster. Para obtener más información, consulte Deshabilitar el balanceador.
También puede limitar el periodo de ejecución del balanceador para evitar que afecte al tráfico de producción.Consulte "Programar el periodo de balanceo" para obtener más información.
Nota
La especificación de la ventana de equilibrio es relativa a la zona horaria local del servidor principal del conjunto de réplicas del servidor de configuración.
Agregar y remover particiones del clúster
Añadir un fragmento a un clúster crea un desequilibrio, ya que el nuevo fragmento no contiene datos. Aunque MongoDB comienza a migrar datos al nuevo fragmento inmediatamente, el clúster puede tardar un tiempo en equilibrarse. Consulta el tutorial "Añadir fragmentos a un clúster" para obtener instrucciones sobre cómo añadir un fragmento a un clúster.
Tip
A partir de MongoDB 8.0, puedes redistribuir usando la misma clave para mover datos. Si su aplicación cumple con los requisitos de redistribución de particiones, puede utilizar el comando reshardCollection para redistribuir los datos en todo el clúster y agregar los nuevos fragmentos. Para más información, consulta Reshard a la misma clave de partición. Este proceso es mucho más rápido que la alternativa Procedimiento de migración por rango.
Eliminar un fragmento de un clúster crea un desequilibrio similar, ya que los datos que residen en él deben redistribuirse por todo el clúster. Si bien MongoDB comienza a drenar un fragmento eliminado inmediatamente, el clúster puede tardar un tiempo en equilibrarse. No apague los servidores asociados al fragmento eliminado durante este proceso.
Cuando se elimina una partición en un clúster con una distribución desigual de fragmentos, el balanceador primero elimina los fragmentos de la partición en proceso de drenaje y luego equilibra la distribución desigual de fragmentos restante.
Consulta el tutorial Eliminar fragmentos de un clúster para obtener instrucciones sobre cómo eliminar de forma segura un fragmento de un clúster.
Procedimiento de migración de rango
Todas las migraciones de rangos utilizan el siguiente procedimiento:
El proceso de balanceador envía el comando
moveRangea la partición de origen.La fuente inicia el movimiento cuando recibe un comando interno
moveRange. Durante el proceso de migración, las operaciones al rango se envían a la partición de origen. La partición de origen es responsable de las operaciones de guardado entrantes para el rango.El fragmento de destino crea cualquier índice requerido por el origen que no exista en el destino.
La partición de destino comienza solicitando documentos en el rango y empieza a recibir copias de los datos. Consulta también Migración y replicación de rango.
Después de recibir el documento final en el rango, la partición de destino inicia un proceso de sincronización para asegurarse de que tiene los cambios en los documentos migrados que ocurrieron durante la migración.
Cuando está completamente sincronizado, el fragmento de origen se conecta a la base de datos de configuración y actualiza los metadatos del clúster con la nueva ubicación del rango.
Una vez que el fragmento de origen completa la actualización de los metadatos, y una vez que no hay cursores abiertos en el rango, el fragmento de origen elimina su copia de los documentos.
Nota
Si el balanceador necesita realizar migraciones adicionales de fragmentos desde el shard de origen, el balanceador puede iniciar la siguiente migración de fragmentos sin esperar a que el proceso de migración actual termine este paso de eliminación. Ver Limpieza de migración de rango asíncrona.
Advertencia
A partir de la versión 8.2 de MongoDB, las lecturas secundarias de larga duración en un clúster fragmentado pueden terminar automáticamente antes de la eliminación de documentos huérfanos tras una migración de fragmentos.
El parámetro terminateSecondaryReadsOnOrphanCleanup controla este comportamiento. Para obtener más información sobre cómo manejar las lecturas secundarias de larga duración, consulte las lecturas secundarias de larga duración en clústeres particionados.
Umbrales de migración
Para minimizar el impacto del balance en el clúster, el balanceador solo comienza a equilibrar después de que la distribución de datos de una colección particionada haya alcanzado ciertos umbrales.
Una colección se considera equilibrada si la diferencia de datos entre particiones (para esa colección) es inferior a tres veces el tamaño de rango configurado para la colección. Para el tamaño de rango predeterminado de 128MB, dos particiones deben tener una diferencia de tamaño de datos para una determinada colección de al menos 384MB para que se produzca una migración.
Limpieza de migración de rango asincrónica
Para migrar datos desde un fragmento, el balanceador migra los datos rango por rango. Sin embargo, no espera a que finalice la fase de eliminación de la migración actual para iniciar la siguiente migración de rango.Consulte Migración de rango para conocer el proceso de migración de rango y la fase de eliminación.
Este comportamiento de puesta en cola permite que los fragmentos descarguen datos más rápidamente en casos de clústeres muy desequilibrados, como cuando se realizan cargas de datos iniciales sin división previa y cuando se agregan nuevos fragmentos.
Este comportamiento también afecta el comando moveRange, y los scripts de migración que utilizan el comando moveRange pueden avanzar más rápidamente.
En algunos casos, las fases de eliminación pueden persistir durante más tiempo. Las migraciones de rango se mejoran para ser más resilientes en caso de un cambio por fallas durante la fase de eliminación. Los documentos huérfanos se limpian incluso si el nodo primario de un set de réplicas falla o se reinicia durante esta fase.
Importante
Cuando se establece el campo _waitForDelete, MongoDB no espera en el orphanCleanupDelaySecs retraso antes de realizar la eliminación de rango. Si se utiliza el parámetro _waitForDelete y se realizan operaciones de lectura en secundarios, la lectura podría terminar debido a la fase de borrar de la migración. Para aprender más, consulta terminateSecondaryReadsOnOrphanCleanup.
Para más información, consulte Esperar para borrar.
Nota
La eliminación de rango es una operación que consume muchos recursos y que puede generar un estrés significativo en la memoria caché y en E/S a medida que el clúster elimina los documentos.
Si planea mover una gran cantidad de datos, como al añadir fragmentos a un clúster o durante la distribución inicial de una colección fragmentada entre varios fragmentos, considere volver a fragmentar la colección. Las operaciones de refragmentación no requieren limpieza de rangos, lo que las hace mucho menos estresantes para el clúster.
Para obtener más información, consulte Repartir una colección.
Migración y replicación de rangos
Durante la migración de rango, el valor _secondaryThrottle determina cuándo la migración avanza al siguiente documento del rango.
En la config.settings colección:
Si la configuración
_secondaryThrottledel balanceador está configurada en un nivel de confirmación de escritura (write concern), cada documento movido durante la migración de rango debe recibir el acuse de recibo solicitado antes de proceder con el siguiente documento.Si la configuración
_secondaryThrottleno está establecida, el proceso de migración no espera la replicación a un documento secundario y, en su lugar, continúa con el siguiente documento.
Para actualizar el parámetro _secondaryThrottle del balanceador, consulta Acelerador secundario como ejemplo.
Independientemente de cualquier configuración _secondaryThrottle, ciertas fases de la migración por rangos tienen la siguiente política de replicación:
MongoDB pausa brevemente todas las lecturas y escrituras de la aplicación en la colección a la que se está migrando en la partición de origen antes de actualizar los servidores de configuración con la ubicación del rango. MongoDB reanuda las lecturas y escrituras de aplicaciones después de la actualización. El movimiento de rango requiere que todas las escrituras sean reconocidas por la mayoría de los nodos del set de réplicas tanto antes como después de confirmar el movimiento de rango en los servidores de configuración.
Cuando una migración saliente termina y se produce la limpieza, todas las escrituras deben ser replicadas a la mayoría de los servidores antes de que la limpieza adicional (de otras migraciones salientes) o nuevas migraciones entrantes puedan continuar.
Para actualizar la configuración de _secondaryThrottle en la colección config.settings, ver secundario Throttle para un ejemplo.
Cantidad máxima de documentos por rango para migrar
Por defecto, MongoDB no puede mover un rango si el número de documentos en el rango es mayor que 2 veces el resultado de dividir el tamaño del rango configurado por el tamaño promedio de los documentos. Si MongoDB puede mover un subrango de un fragmento y reducir su tamaño a menos de eso, el balanceador lo hace migrando un rango. db.collection.stats() incluye el campo avgObjSize, que representa el tamaño medio de los documentos en la colección.
Para los fragmentos que son demasiado grandes para migrar:
La configuración del balanceador
attemptToBalanceJumboChunkspermite que el balanceador migre fragmentos demasiado grandes para mover, siempre que los fragmentos no estén etiquetados como jumbo. Consulte los rangos de balance que exceden el límite de tamaño para obtener más detalles.Al emitir los comandos
moveRangeymoveChunk, es posible especificar la opción forceJumbo para permitir la migración de rangos que son demasiado grandes para moverse. Los rangos pueden o no estar etiquetados como jumbo.
Optimización del rendimiento de la eliminación por rango
Se puede ajustar el impacto en el rendimiento de las eliminaciones por rango con rangeDeleterBatchSize y rangeDeleterBatchDelayMS.
Por ejemplo:
Para limitar la cantidad de documentos eliminados por lote, puede establecer
rangeDeleterBatchSizeen un valor pequeño, como32.Para agregar un retraso adicional entre eliminaciones por lotes, puede establecer por encima del
rangeDeleterBatchDelayMSvalor20predeterminado actual de milisegundos.
Nota
Si existen operaciones de lectura en curso o cursores abiertos en la colección objetivo de las eliminaciones, los procesos de eliminación por rangos pueden no continuar.
Change Streams y documentos huérfanos
A partir de MongoDB 5.3, durante la migración de rango, no se generan eventos de flujo de cambios para las actualizaciones de documentos huérfanos.
Tamaño de la partición
Por defecto, MongoDB intenta llenar todo el espacio disponible en disco con datos en cada partición a medida que el conjunto de datos crece. Para garantizar que el clúster siempre tenga la capacidad de gestionar el crecimiento de datos, supervise el uso del disco, así como otras métricas de rendimiento.
Tamaño del fragmento y equilibrio
Para obtener una introducción chunkSize a, consulte Modificar el tamaño del rango en un clúster fragmentado.
Cuando los datos de la colección compartidos entre dos particiones difieren en tres o más veces la configuración de chunkSize, el equilibrador migra los fragmentos entre las particiones.
Por ejemplo, si chunkSize es 128 MB y los datos de recopilación difieren en 384 MB o más, el equilibrador migra fragmentos entre los fragmentos.
Cuando los fragmentos se mueven, se dividen o se fusionan, los metadatos de la partición se actualizan después de que la operación de fragmento es confirmada por un servidor de configuración. Las Particiones no involucradas en la operación de fragmentos también se actualizan con nuevos metadatos.
El tiempo para la actualización de metadatos de la partición es proporcional al tamaño de la tabla de enrutamiento. Las operaciones CRUD sobre la colección se bloquean temporalmente mientras se actualiza la metadatos de las particiones, y una tabla de enrutamiento más pequeña significa demoras más cortas en las operaciones CRUD.
Desfragmentar una colección reduce la cantidad de fragmentos y el tiempo necesario para actualizar los metadatos de cada fragmento.
Para reducir la carga de trabajo del sistema, configure el balanceador para que se ejecute solo en un horario específico mediante una ventana de balanceo de fragmentos. La desfragmentación se ejecuta durante esta ventana.
Puede utilizar el parámetro chunkDefragmentationThrottlingMS para limitar la velocidad de los comandos de división y fusión ejecutados por el balanceador.
Puedes iniciar y detener la desfragmentación en cualquier momento.
También puedes establecer una zona de particiones. Una zona de particiones se basa en la clave de partición, y se puede asociar cada zona con una o más particiones en un clúster.
Un clúster fragmentado solo divide fragmentos cuando es necesario migrarlos. Esto significa que el tamaño del fragmento puede superar chunkSize. Los fragmentos más grandes reducen la cantidad de fragmentos en un fragmento y mejoran el rendimiento, ya que se reduce el tiempo de actualización de los metadatos. Por ejemplo, podría ver un fragmento de 1 TB en un fragmento aunque haya configurado chunkSize en 256 MB.
chunkSize afecta a lo siguiente:
Cantidad máxima de datos que el balanceador intenta migrar entre dos particiones en una única operación de migración de fragmentos.
Cantidad de datos migrados durante la desfragmentación.
Para detalles sobre la desfragmentación de colecciones fragmentadas, consulte Desfragmentar colecciones fragmentadas.
Se pueden redistribuir los fragmentos para equilibrar
Cuando se ejecuta el método sh.shardCollection(), el balanceador comienza a distribuir los datos de la colección a otras particiones del clúster. Una sola partición solo puede participar en una migración de fragmento a la vez. Cuando MongoDB copia un rango de datos de una partición a otra correctamente, el rango en la partición donante se marca para su eliminación por el eliminador de rangos. Este proceso es lento y requiere muchos recursos.
A partir de MongoDB 8.0, si la implementación cumple los requisitos de recursos, se recomienda usar el método sh.shardAndDistributeCollection() para particionar la colección. Este método encapsula los comandos shardCollection y reshardCollection para particionar la colección y redistribuirla de inmediato con la misma clave. Esto hace que MongoDB vuelva a equilibrar los datos entre las particiones sin esperar al balanceador.
Para obtener más información, se puede consultar Redistribuir con la misma clave de partición.