La clave de partición ideal permite a MongoDB distribuir documentos uniformemente en todo el clúster al mismo tiempo que facilita los patrones de query más comunes. Una clave de partición subóptima puede conducir a problemas de rendimiento o escalado debido a una distribución desigual de los datos. Puedes cambiar la clave de partición de una colección para cambiar la distribución de tus datos en un clúster.
A partir de MongoDB 8.0, puedes rehacer una colección con la misma clave de partición, lo que te permite redistribuir datos para incluir nuevas particiones o en distintas zonas sin cambiar tu clave de partición. Para rehacer a la misma clave de partición, establece forceRedistribution en true.
A partir de MongoDB 8.0.10, puedes volver a fragmentar una colección de series de tiempo. Todas las particiones en la colección de series de tiempo deben ejecutar la versión 8.0.10 o posterior para reparticionar.
Nota
Antes de volver a dividir la colección, lea Solucionar problemas de claves de partición para obtener información sobre los problemas comunes de rendimiento y escalado y consejos sobre cómo resolverlos.
Acerca de esta tarea
Solo se puede volver a dividir la partición de una colección a la vez.
writeConcernMajorityJournalDefaultdebe sertrue.Para volver a fragmentar una colección que tenga una restricción de unicidad, la nueva clave de partición debe satisfacer los requisitos del índice único para cualquier índice único existente.
Los siguientes comandos y métodos de shell correspondientes no son compatibles con la colección que se está redividiendo durante la operación de redivisión:
Si ejecutas una de las siguientes operaciones, la operación espera hasta que termine el nuevo particionado antes de ejecutarse:
dropDatabaseen la base de datos que aloja la colección que está sufriendo un reajuste de particiones
Si la colección que está redistribuyendo utiliza MongoDB Search, el índice de búsqueda deja de estar disponible una vez finalizada la operación de redistribución. Deberá reconstruir manualmente el índice de búsqueda una vez que finalice dicha operación.
Si la colección que está redistribuyendo está archivada en Atlas Online Archives, los archivos de archivo en línea se marcan como
Orphaneduna vez que finaliza la operación de redistribución. Puede crear otro archivo en línea para la misma base de datos, colección y campos que el archivo huérfano, siempre que no exista otro archivo con la misma combinación en estadoActive.
Antes de comenzar
Antes de comenzar el re-sharding de tu colección, asegúrate de cumplir con los siguientes requisitos:
Su aplicación puede tolerar un período de dos segundos en el que la colección afectada bloquea los guardados. Durante el periodo en el que las écritas están bloqueadas, tu aplicación experimenta un aumento en la latencia.
Si tu carga de trabajo no puede tolerar este requerimiento, considera refinar la clave de partición en su lugar.
Su base de datos cumple con estos requisitos de recursos:
Asegúrate de que el espacio de almacenamiento disponible en cada partición receptora sea al menos el doble del tamaño de almacenamiento de la colección que se desea refragmentar, más el tamaño total de su índice, dividido por el número de particiones:
( ( collection_storage_size + index_size ) * 2 ) / shard_count = storage_req Por ejemplo, considera una colección con un tamaño de almacenamiento de 2 TB de datos y un índice de 400 GB. Para distribuirlo en cuatro particiones necesitarías:
( ( 2 TB collection + 0.4 TB index ) * 2 ) / 4 shards = 1.2 TB storage Para redistribuir esta colección, cada partición requiere 1.2 TB de almacenamiento disponible.
En MongoDB Atlas, es posible que debas mejorar al siguiente nivel de almacenamiento para la operación de redistribución de fragmentos. Puedes revertir la actualización una vez que la operación se haya completado.
Asegúrate de que tu capacidad de E/S esté por debajo de 50%.
Asegúrate de que la carga de tu CPU esté por debajo del 80%.
Importante
Estos requisitos no son exigidos por la base de datos. Una falta de asignación de suficientes recursos puede provocar:
la base de datos se queda sin espacio y se apaga
rendimiento reducido
la operación tarda más de lo esperado
Si tu aplicación tiene periodos de menor tráfico, realiza esta operación en la colección durante ese tiempo si es posible.
No es necesario crear un índice en la nueva clave de partición antes de volver a particionar. La operación de redistribución compila automáticamente los índices requeridos durante la fase de índices.
No hay creaciones de índices en proceso. Para comprobar si hay creaciones de índices en ejecución, utiliza
$currentOp:db.getSiblingDB("admin").aggregate( [ { $currentOp : { idleConnections: true } }, { $match: { $or: [ { "op": "command", "command.createIndexes": { $exists: true } }, { "op": "none", "msg": /^Index Build/ } ] } } ] ) En el documento de resultados, si el valor en el campo
inproges un arreglo vacío, no hay creaciones de índices en curso:{ inprog: [], ok: 1, '$clusterTime': { ... }, operationTime: <timestamp> }
Nota
Una operación de resharding es un proceso que consume muchos recursos de escritura y puede generar mayores tasas de oplog. Puede que desees:
defina un tamaño fijo para el oplog para prevenir el crecimiento sin límites del oplog.
aumente el tamaño de Oplog para minimizar la posibilidad de que uno o más nodos secundarios queden obsoletos.
Consulta la documentación de Oplog del set de réplicas para obtener más información.
Protocolo de guardar en dos fases
Las query que no incluyen la clave de partición completa en el filtro de query pueden requerir un protocolo de escritura en dos fases. Este protocolo transmite la query a varias particiones y puede reducir significativamente el rendimiento.
Las queries que proporcionan la clave de partición antigua en lugar de la nueva clave de partición utilizan el protocolo de guardar de dos fases.
El método
deleteOne()utiliza el protocolo de guardar de dos fases cuando el filtro de query no utiliza la clave de partición completa o el campo_id.Los métodos
replaceOne()yupdateOne():Cuando la query proporciona la clave de partición completa, el protocolo de dos fases nunca se utiliza.
Cuando la query no proporciona la clave de partición completa pero proporciona el campo
_id, el uso del protocolo de guardar en dos fases depende del valor deupsert. Siupsertse establece entrue, se utiliza el protocolo de guardar en dos fases. Siupsertesfalse, no se utiliza el protocolo de guardar en dos fases.Cuando la query no proporciona ni la clave de partición completa ni el campo
_id, siempre se utiliza el protocolo de guardar en dos fases.
Los siguientes métodos utilizan el protocolo de guardar en dos fases cuando el filtro de query no utiliza la clave de partición completa:
Para un rendimiento óptimo, actualice su aplicación después de que finalice la operación de refragmentación para usar la nueva clave de partición en los filtros de query para estas operaciones.
Pasos
Importante
Le recomendamos encarecidamente que consulte la sección "Acerca de esta tarea" y lea la sección "Pasos" completa antes de volver a fragmentar su colección.
En una operación de re-sharding de una colección, una partición puede ser:
dador, que actualmente almacena los fragmentos para la colección particionada.
destinatario, que almacena nuevos fragmentos para la colección particionada en función de las claves de partición y zonas.
Una partición puede ser donante y receptor al mismo tiempo.
El servidor de configuración primario es siempre el coordinador de replanificación y comienza cada fase de la operación de replanificación.
Inicie la operación de re-sharding.
Mientras esté conectado al mongos, emite un comando reshardCollection que especifique la colección a redistribuir y la nueva clave de partición:
db.adminCommand({ reshardCollection: "<database>.<collection>", key: <shardkey> })
MongoDB establece el número máximo de segundos para bloquear guardados en dos segundos y comienza la operación de redistribución de particiones.
Para volver a particionar con la misma clave de partición, establece forceRedistribution en true:
db.adminCommand({ reshardCollection: "<database>.<collection>", key: <shardkey>, forceRedistribution: true })
También puede usar sh.reshardCollection() para redistribuir una colección con la misma clave. Para un ejemplo, consulte Redistribuir datos a nuevas particiones.
Supervise la operación de resharding.
Para supervisar la operación de redistribución, puedes utilizar la etapa de pipeline $currentOp:
db.getSiblingDB("admin").aggregate([ { $currentOp: { allUsers: true, localOps: false } }, { $match: { type: "op", "originatingCommand.reshardCollection": "<database>.<collection>" } } ])
Nota
Para ver los valores actualizados, es necesario ejecutar continuamente la pipeline anterior.
La $currentOp salida de la pipeline:
totalOperationTimeElapsedSecs: elapsed operation time en segundosremainingOperationTimeEstimatedSecs: tiempo restante estimado en segundos para la operación de refragmentación actual. Se devuelve como-1cuando se inicia una nueva operación de refragmentación.A partir de MongoDB 7.0,
remainingOperationTimeEstimatedSecstambién está disponible en el coordinador durante una operación de rehashing.remainingOperationTimeEstimatedSecsse establece en una estimación de tiempo pesimista:La estimación de tiempo de la fase de actualización se establece en el tiempo de la fase de clonación, que es un periodo relativamente largo.
En la práctica, si sólo hay unas pocas operaciones de escritura pendientes, el tiempo real de la fase de sincronización es relativamente corto.
[ { shard: '<shard>', type: 'op', desc: 'ReshardingRecipientService | ReshardingDonorService | ReshardingCoordinatorService <reshardingUUID>', op: 'command', ns: '<database>.<collection>', originatingCommand: { reshardCollection: '<database>.<collection>', key: <shardkey>, unique: <boolean>, collation: { locale: 'simple' } }, totalOperationTimeElapsedSecs: <number>, remainingOperationTimeEstimatedSecs: <number>, ... }, ... ]
Comportamiento
Duración mínima de una operación de redistribución
La duración mínima de una operación de redistribución de fragmentos siempre es de 5 minutos.
Escrituras reintentables
Se pueden reintentar las escrituras reintentables iniciadas antes o durante el reshardeo, durante y después de que la colección haya sido reshardeada, durante hasta 5 minutos. Después de 5 minutos es posible que no puedas encontrar el resultado definitivo del guardado y los intentos posteriores de volver a intentar el guardado fallan con un error IncompleteTransactionHistory.
Limitaciones de resharding
Si la colección utiliza Atlas Search, el índice de búsqueda deja de estar disponible una vez finalizada la operación. Para restaurarlo, vuelva a crearlo manualmente.
Las colecciones que utilizan Queryable Encryption no son compatibles.
Caso de error
Duplicate _id Values
La operación de redistribución falla si los valores de _id no son globalmente únicos para evitar la corrupción de los datos de la colección. Los valores duplicados de _id también pueden impedir que la migración de fragmentos tenga éxito. Si tienes documentos con valores duplicados de _id, copia los datos de cada uno en un nuevo documento y luego elimina los documentos duplicados.