Docs Menu
Docs Home
/ /

Repartir una colección

Nuevo en la versión 5.0.

La clave de fragmento ideal permite a MongoDB distribuir los documentos uniformemente en todo el clúster, a la vez que facilita patrones de consulta comunes. Una clave de fragmento deficiente puede provocar problemas de rendimiento o escalabilidad debido a una distribución desigual de los datos. A partir de MongoDB 5.0, se puede cambiar la clave de fragmento de una colección para modificar la distribución de los datos en el clúster.

Nota

Antes de volver a fragmentar su colección, lea Solucionar problemas de claves de fragmento para obtener información sobre problemas comunes de rendimiento y escalabilidad y consejos sobre cómo solucionarlos.

Antes de volver a particionar su colección, asegúrese de cumplir con los siguientes requisitos:

  • Su aplicación puede tolerar un periodo de dos segundos en el que la colección que se está reparticionando bloquea las escrituras. Durante este periodo, la aplicación experimenta un aumento de latencia. Si su carga de trabajo no puede soportar este requisito, considere refinar su clave de shard.

  • Su base de datos cumple estos requisitos de recursos:

    • Espacio de almacenamiento disponible: asegúrese de que el espacio de almacenamiento disponible en cada fragmento en el que se distribuirá la colección sea al menos el doble del tamaño de la colección que desea volver a fragmentar y su tamaño de índice total, dividido por la cantidad de fragmentos.

      storage_req = ( ( collection_size + index_size ) * 2 ) / shard_count

      Por ejemplo, considere una colección que contiene 2 TB de datos y tiene un índice de 400 GB distribuido en cuatro fragmentos. Para realizar una operación de refragmentación en esta colección, cada fragmento requeriría 1.2 TB de almacenamiento disponible.

      1.2 TB storage = ( ( 2 TB collection + 0.4 TB index ) * 2 ) / 4 shards

      Para cumplir con los requisitos de almacenamiento, es posible que deba actualizar al siguiente nivel de almacenamiento durante la operación de refragmentación. Puede reducir la capacidad una vez finalizada la operación.

    • E/S: asegúrese de que su capacidad de E/S sea inferior al 50%.

    • Carga de la CPU: asegúrese de que la carga de su CPU sea inferior al 80%.

    Importante

    La base de datos no exige estos requisitos. Si no se asignan suficientes recursos, pueden producirse las siguientes consecuencias:

    • La base de datos se está quedando sin espacio y se está apagando

    • disminución del rendimiento

    • La operación de refragmentación está tardando más de lo esperado

    Si su aplicación tiene períodos de tiempo con menos tráfico, vuelva a fragmentar su colección durante ese tiempo si es posible.

  • Debe reescribir las consultas de su aplicación para utilizar tanto la clave de fragmento actual como la nueva clave de fragmento.

    Tip

    Si su aplicación puede tolerar el tiempo de inactividad, puede realizar estos pasos para evitar reescribir las consultas de su aplicación para usar las claves de fragmento actuales y nuevas:

    1. Detenga su aplicación.

    2. Reescriba su aplicación para utilizar la nueva clave de fragmento.

    3. Espere a que se complete la repartición. Para supervisar el proceso de repartición, utilice la $currentOp etapa de canalización.

    4. Implementa tu aplicación reescrita.

    Antes de que se complete la reorganización de los fragmentos, las siguientes consultas devuelven un error si el filtro de consulta no incluye ni la clave de fragmento actual ni un campo único (como _id):

    Para un rendimiento óptimo, le recomendamos que también reescriba otras consultas para incluir la nueva clave de fragmento.

    Una vez que se complete la operación de refragmentación, puede eliminar la clave de fragmento anterior de las consultas.

  • No hay compilaciones de índices en curso. Para comprobar si hay compilaciones de índices en ejecución, utilice $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 inprog es un arreglo vacío, no hay creaciones de índices en curso:

    {
    inprog: [],
    ok: 1,
    '$clusterTime': { ... },
    operationTime: <timestamp>
    }

Nota

El reenrutamiento es un proceso de guardar intensivo que puede generar tasas aumentadas de oplog. Puedes optar por:

  • defina un tamaño fijo para el oplog para prevenir el crecimiento sin límites del oplog.

  • Aumente el tamaño del registro de operaciones para minimizar la posibilidad de que uno o más nodos secundarios queden obsoletos.

Consulte la documentación del registro de operaciones del conjunto de réplicas para obtener más detalles.

Importante

Le recomendamos encarecidamente que consulte Acerca de esta tarea y lea la sección Pasos en su totalidad antes de volver a fragmentar su colección.

En una operación de refragmentación de una colección, un fragmento puede ser:

  • donante, que actualmente almacena fragmentos para la colección fragmentada.

  • destinatario, que almacena nuevos fragmentos para la colección fragmentada en función de las claves y zonas del fragmento.

Un fragmento puede ser donante y receptor a la vez. El conjunto de fragmentos donantes es idéntico al de los fragmentos receptores, a menos que se utilicen zonas.

El servidor de configuración principal siempre es el coordinador de re-sharding e inicia cada fase de la operación de re-sharding.

1

Debe desactivar el balanceador antes de comenzar a repartir una colección. Para desactivarlo, consulte aquí.

2

Mientras esté conectado a,mongos reshardCollection emita un comando que especifique la colección que se va a fragmentar nuevamente y la nueva clave de fragmento:

db.adminCommand({
reshardCollection: "<database>.<collection>",
key: <shardkey>
})

MongoDB establece el número máximo de segundos para bloquear escrituras en dos segundos y comienza la operación de re-fragmentación.

3

Para supervisar la operación de re-segmentación, puede utilizar la $currentOp etapa de canalización:

db.getSiblingDB("admin").aggregate([
{ $currentOp: { allUsers: true, localOps: false } },
{
$match: {
type: "op",
"originatingCommand.reshardCollection": "<database>.<collection>"
}
}
])

Nota

Para ver valores actualizados, debe ejecutar continuamente el proceso anterior.

El pipeline $currentOp genera:

  • totalOperationTimeElapsedSecs: tiempo de operación transcurrido en segundos

  • remainingOperationTimeEstimatedSecs: Tiempo restante estimado en segundos para la operación de re-fragmentación actual. Se devuelve como -1 al iniciar una nueva operación de re-fragmentación.

    Empezando en:

    • MongoDB,5.0 pero antes de MongoDB,6.1 remainingOperationTimeEstimatedSecs solo está disponible en un fragmento de destinatario durante una operación de reorganización de fragmentos.

    • MongoDB 6.1, remainingOperationTimeEstimatedSecs también está disponible en el coordinador durante una operación de reorganización.

    La operación de refragmentación realiza estas fases en orden:

    1. La fase de clonación duplica los datos de la recopilación actual.

    2. La fase de recuperación aplica cualquier operación de escritura pendiente a la colección fragmentada nuevamente.

    remainingOperationTimeEstimatedSecs se establece en una estimación de tiempo pesimista:

    • La estimación del tiempo de la fase de recuperación se establece en el tiempo de la fase de clonación, que es un tiempo relativamente largo.

    • En la práctica, si solo hay unas pocas operaciones de escritura pendientes, el tiempo real de la fase de recuperació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>,
...
},
...
]
4

Para habilitar el balanceador, consulte aquí.

La duración mínima de una operación de re-segmentación es siempre 5 minutos.

Las escrituras reintentables iniciadas antes o durante la repartición pueden reintentarse durante y después de la repartición de la colección durante un máximo de 5 minutos. Después de 5 minutos, es posible que no se pueda encontrar el resultado definitivo de la escritura y que los intentos posteriores de reintentar la escritura fallen con un IncompleteTransactionHistory error.

La operación de repartición falla si los valores _id no son únicos globalmente para evitar dañar los datos de la colección. Los valores _id duplicados también pueden impedir la migración correcta de fragmentos. Si tiene documentos con valores _id duplicados, copie los datos de cada uno en un nuevo documento y, a continuación, elimine los documentos duplicados.

Volver

Refinar una clave de fragmento

En esta página