El balanceador de MongoDB es un proceso en segundo plano que supervisa la cantidad de fragmentos en cada partición. Cuando el número de fragmentos en una partición dada alcanza umbrales de migración específicos, el balanceador intenta migrar automáticamente los fragmentos entre las particiones y alcanzar un número igual de fragmentos por partición.
El procedimiento de balanceo para clústeres fragmentados es completamente transparente para el usuario y la capa de aplicación, aunque puede haber algún impacto en el rendimiento durante la ejecución del procedimiento.
El balanceador se ejecuta en el primario del set de réplicas del servidor de configuración (CSRS).
Balanceador de clúster
El proceso del balanceador es responsable de redistribuir los fragmentos de una colección particionada uniformemente entre las particiones para cada colección particionada. Por defecto, el proceso de balanceador siempre está habilitado.
Para abordar la distribución desigual de los fragmentos en una colección fragmentada, el equilibrador migra los fragmentos de las particiones con más fragmentos a las particiones con un menor número de fragmentos. El balanceador migra los fragmentos hasta que haya una distribución equitativa de fragmentos para la colección en las particiones. Para obtener detalles sobre la migración de fragmentos, consulta Procedimiento de migración de fragmentos.
Las migraciones de fragmentos pueden afectar el espacio en disco, ya que la partición fuente archiva automáticamente los documentos migrados por defecto. Para más detalles, consulta moveChunk directorio.
Las migraciones de fragmentos implican unos ciertos gastos en general en términos de ancho de banda y carga de trabajo, ambos pueden impactar el rendimiento de la base de datos. [1] El balanceador intenta minimizar el impacto mediante:
Restringir una partición a no más de una migración en un momento dado; es decir, una partición no puede participar en varias migraciones de fragmentos al mismo tiempo. Para migrar varios fragmentos de una partición, el balanceador migra los fragmentos uno a la vez.
Modificado en la versión 3.4: A partir de MongoDB 3.4, MongoDB puede realizar migraciones de fragmentos en paralelo. Observando la restricción de que una partición puede participar en como máximo una migración a la vez, para un clúster con n particiones, MongoDB puede realizar como máximo n/2 (redondeado hacia abajo) migraciones simultáneas de fragmentos.
See también Limpieza de migración de fragmentos asíncrona.
Iniciar una ronda de balanceo solo cuando la diferencia en el número de fragmentos entre la partición con el mayor número de fragmentos de una colección particionada y la partición con el menor número de fragmentos de esa colección alcance el umbral de migración.
Se puede desactivar el balanceador temporalmente para tareas de mantenimiento, pero dejar el balanceador desactivado durante periodos prolongados puede degradar el rendimiento del clúster. Para aprender más, consulte Deshabilitar el balanceador.
También se puede limitar el período durante el cual se ejecuta el balanceador para evitar que afecte el tráfico de producción. Consultar Programar el período del balanceo para obtener más detalles.
Nota
La especificación de la ventana de balanceo se refiere a la zona horaria local del primario del set de réplicas del servidor de configuración.
| [1] | La operación de partición de colección puede realizar una creación y distribución inicial de fragmentos para colecciones vacías o no existentes si se han definido zonas y rangos de zonas para la colección. La creación inicial y la distribución del fragmento permiten una configuración más rápida del particionado por zonas. Tras la distribución inicial, el balanceador gestiona la distribución de fragmentos en adelante como es habitual. MongoDB admite el particionado de colecciones en índices hash compuestos. Al realizar el particionado de una colección vacía o inexistente usando claves de partición compuestas con hash, se aplican requisitos adicionales para que MongoDB pueda realizar la creación y distribución inicial de fragmentos. Consulta Predefinir zonas y rangos de zonas para una colección vacía o inexistente como ejemplo. |
Agregar y remover particiones del clúster
Agregar una partición a un clúster crea un desequilibrio, ya que la nueva partición no tiene fragmentos. Si bien MongoDB comienza a migrar datos a la nueva partición de inmediato, puede tomar algún tiempo antes de que el clúster se equilibre. Consulta el tutorial Agregar particiones a un clúster para ver las instrucciones para agregar una partición a un clúster.
Al eliminar una partición de un clúster, se crea un desequilibrio similar, ya que los fragmentos que residen en esa partición deben redistribuirse por todo el clúster. Mientras MongoDB comienza a drenar una partición eliminada inmediatamente, puede pasar algún tiempo antes de que el clúster se equilibre. No apagar los servidores asociados a la partición eliminada 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 Remover Particiones de un Clúster Particionado Existente para obtener instrucciones sobre cómo remover de manera segura una partición de un clúster.
Procedimiento de migración de fragmentos
Todas las migraciones de fragmentos utilizan el siguiente procedimiento:
El proceso de balanceador envía el comando
moveChunka la partición de origen.La fuente inicia el movimiento con un comando
moveChunkinterno. Durante el proceso de migración, las operaciones al fragmento se dirigen a la partición de origen. La partición de origen es responsable de las operaciones de guardado entrantes para el fragmento.La partición de destino compila cualquier índice requerido por el origen que no exista en el destino.
La partición de destino comienza a solicitar documentos en el fragmento y empieza a recibir copias de los datos. Ver también Migración y replicación de fragmento.
Después de recibir el documento final en el fragmento, la partición de destino inicia un proceso de sincronización para garantizar que cuente con los cambios en los documentos migrados que ocurrieron durante la migración.
Cuando se completa la sincronización, la partición 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 fragmento.
Luego de que la partición de origen complete la actualización de los metadatos y una vez que no haya cursores abiertos en el fragmento, la partición de origen borra su copia de los documentos.
Nota
Si el balanceador necesita realizar migraciones adicionales de fragmentos desde la partición de origen, puede iniciar la siguiente migración de fragmentos sin esperar a que el proceso de migración actual termine este paso de eliminación. Consulte Limpieza asíncrona de migración de fragmentos.
El proceso de migración garantiza la coherencia y maximiza la disponibilidad de fragmentos durante el balanceo.
Advertencia
Las lecturas secundarias en un clúster con particiones y migraciones pueden omitir documentos
Las lecturas secundarias de larga duración en un clúster fragmentado pueden perder documentos si se están realizando migraciones.
Antes de borrar un fragmento durante la migración de fragmento, MongoDB espera orphanCleanupDelaySecs, o hasta que finalicen las queries en curso que impliquen el fragmento en el primario de la partición, lo que ocurra después. Las consultas que se ejecutaron inicialmente en un nodo primario, pero que continúan después de que el nodo ha bajado de nivel a un nodo secundario, serán tratadas como si se hubieran ejecutado inicialmente en un nodo secundario. Es decir, el servidor solo espera por orphanDelayCleanupSecs si no hay consultas que apunten al fragmento en el primario actual.
Las consultas que se dirigen al fragmento y se ejecutan en secundarios pueden omitir documentos si estas consultas tardan más de orphanCleanupDelaySecs.
Umbrales de migración
Para minimizar el impacto del equilibrio en el clúster, el balanceador inicia el balanceo solo después de que la distribución de datos de una colección particionada alcance el umbral de migración que deja el clúster desbalanceado. Cuando el número de fragmentos en la partición más cargada supera el número óptimo de fragmentos por partición en más de 1 fragmento, la colección está desbalanceada y el balanceador inicia migraciones de fragmentos. El número óptimo de fragmentos por partición es el número total de fragmentos en una colección particionada dividido por el número de particiones, redondeado hacia arriba al número entero más cercano. Si existen zonas, MongoDB calcula el número óptimo de fragmentos por zona.
Por ejemplo, si un usuario añade un nuevo fragmento a una colección de 10 particiones con 20 fragmentos cada uno, el balanceador no migra ningún dato. El número óptimo de fragmentos en cada partición es 200 dividido por 11, o 18.18, que MongoDB redondea a 19. Debido a que la diferencia entre 19 y 20 es 1, el clúster está equilibrado y el balanceador no migra ningún fragmento a la nueva partición.
Limpieza asíncrona de migración de fragmentos
Para migrar varios fragmentos desde una partición, el balanceador migra los fragmentos uno a la vez. Sin embargo, el balanceador no espera a que se complete la fase de borrado de la migración actual antes de comenzar la siguiente migración de fragmentos. Consulta Migración de fragmentos para el proceso de migración de fragmentos y la fase de borrado.
Este comportamiento de colas permite a las particiones descargar fragmentos más rápidamente en caso de un clúster muy desequilibrado, como al realizar cargas iniciales de datos sin pre-división y al agregar nuevas particiones.
Este comportamiento también afecta el comando moveChunk, y los scripts de migración que utilizan el comando moveChunk pueden avanzar más rápidamente.
En algunos casos, las fases de eliminación pueden persistir más tiempo. A partir de MongoDB 4.4, las migraciones de fragmentos se mejoran para ser más resilientes en el evento de una conmutación por error durante la fase de borrado. Los documentos huérfanos se eliminan incluso si el primario de un set de réplicas falla o se reinicia durante esta fase.
El _waitForDelete, disponible como configuración para el balanceador, así como el comando moveChunk, puede modificar el comportamiento para que la fase de borrado de la migración actual bloquee el inicio de la siguiente migración de fragmento. El _waitForDelete generalmente es para fines de pruebas internas. Para obtener más información, consulta Esperar a borrar.
Nota
La eliminación de rangos es una operación intensiva que consume muchos recursos y puede causar un estrés significativo en la caché y en las operaciones de entrada/salida mientras el clúster elimina los documentos.
En los casos en los que se planea mover una gran cantidad de datos, como al agregar particiones a un clúster o durante la distribución inicial de una colección particionada en varias particiones, considera volver a fragmentar la colección. Las operaciones de redistribución no requieren limpieza de rangos, lo que las hace mucho menos exigentes para el clúster.
Para obtener más información, consulta Redistribuir una colección.
Migración y replicación de fragmentos
Cambiado en la versión 3.4.
Durante la migración de fragmentos, el valor _secondaryThrottle determina cuándo la migración continuará con el siguiente documento en el fragmento.
En la colección config.settings:
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 el ajuste
_secondaryThrottleno está configurado, el proceso de migración no espera a que se replique en un 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 de fragmentos siguen la siguiente política de replicación:
MongoDB detiene brevemente todas las lecturas y escrituras de la aplicación en la colección que se está migrando, en la partición de origen, antes de actualizar los servidores de configuración con la nueva ubicación del fragmento, y reanuda las lecturas y escrituras de la aplicación después de la actualización. La transferencia del fragmento requiere que todas las escrituras sean reconocidas por la mayoría de los miembros del set de réplicas tanto antes como después de completar la transferencia del fragmento a los servidores de configuración.
Cuando una migración de fragmento saliente finaliza y se realiza la limpieza, todas las escrituras deben replicarse en la mayoría de los servidores antes de que pueda proceder una limpieza adicional (de otras migraciones salientes) o nuevas migraciones entrantes.
Para actualizar la configuración de _secondaryThrottle en la colección config.settings, ver secundario Throttle para un ejemplo.
Número máximo de documentos por fragmento para migrar
De forma predeterminada, MongoDB no puede mover ningún fragmento si el número de documentos en el fragmento es mayor que 1.3 veces el resultado de dividir el tamaño de fragmento configurado por el tamaño promedio de documento. db.collection.stats() incluye el campo avgObjSize, que representa el tamaño promedio de los documentos en la colección.
Para fragmentos que son demasiado grandes para migrar, a partir de MongoDB 4.4:
Una nueva configuración del equilibrador
attemptToBalanceJumboChunkspermite que el equilibrador migre fragmentos demasiado grandes para moverse, siempre que los fragmentos no estén etiquetados como jumbo. Consulta los detalles en Fragmentos de saldo que exceden el límite de tamaño.El comando
moveChunkpuede especificar una nueva opción forceJumbo para permitir la migración de fragmentos que son demasiado grandes para mover. Es posible que los fragmentos estén o no etiquetados como jumbo.
Optimización del rendimiento de la eliminación por rango
Puede ajustar el impacto de rendimiento de las eliminaciones de rango con los parámetros rangeDeleterBatchSize y rangeDeleterBatchDelayMS. Por ejemplo:
Para limitar la cantidad de documentos eliminados por lote, puede establecer
rangeDeleterBatchSizeen un valor pequeño, como32.Para añadir un retraso adicional entre las eliminaciones por lotes, se puede establecer
rangeDeleterBatchDelayMSpor encima del valor por defecto actual de20milisegundos.
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.
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.
Consulta el tutorial Cambiar el tamaño máximo de almacenamiento de una partición dada para obtener instrucciones sobre cómo establecer el tamaño máximo de una partición.