Fragmentación es un método para distribuir datos entre múltiples máquinas. MongoDB utiliza la fragmentación para brindar soporte a las implementaciones con conjuntos de datos muy grandes y operaciones de alto rendimiento.
Los sistemas de bases de datos con grandes conjuntos de datos o aplicaciones de alto rendimiento pueden ser un desafío para la capacidad de un solo servidor. Por ejemplo, las altas tasas de los query pueden agotar la capacidad de la CPU del servidor. Los tamaños de los conjuntos de trabajo que superan la RAM del sistema sobrecargan la capacidad de E/S de las unidades de disco.
Existen dos métodos para abordar el crecimiento del sistema: escalado vertical y horizontal.
El escalado vertical implica aumentar la capacidad de un único servidor, como usar una CPU más potente, añadir más RAM o incrementar la cantidad de espacio de almacenamiento. Las limitaciones de la tecnología disponible pueden impedir que una sola máquina sea suficientemente potente para una carga de trabajo específica. Además, los proveedores basados en la nube tienen límites estrictos debido a las configuraciones de hardware disponibles. Como resultado, existe un límite práctico para el escalado vertical.
El escalado horizontal implica dividir el conjunto de datos del sistema y la carga entre varios servidores, añadiendo servidores adicionales para aumentar la capacidad según sea necesario. Aunque la velocidad o capacidad total de una sola máquina quizás no es alta, cada máquina gestiona un subconjunto de la carga de trabajo total, lo que potencialmente puede proporcionar una mayor eficiencia que un único servidor de alta velocidad y alta capacidad. Ampliar la capacidad de la implementación solo requiere agregar servidores adicionales según sea necesario, lo que puede resultar en un costo total más bajo que el hardware de alta gama para una sola máquina. La compensación es una mayor complejidad en la infraestructura y el mantenimiento para la implementación.
MongoDB es compatible con el escalado horizontal mediante fragmentación.
Puedes partir colecciones en la interfaz de usuario para implementaciones alojadas en MongoDB Atlas.
Clúster fragmentado
Un clúster particionado de MongoDB incluye los siguientes componentes:
partición: cada fragmento contiene un subconjunto de los datos particionados. Cada partición debe implementarse como un set de réplicas.
mongos: El
mongosactúa como un enrutador de consultas y proporciona una interfaz entre las aplicaciones cliente y el clúster fragmentado.mongospuede admitir lecturas protegidas para minimizar las latencias.servidores de configuración: los servidores de configuración almacenan metadatos y configuraciones para el clúster. Los servidores de configuración deben implementarse como un set de réplicas (CSRS).
El siguiente gráfico describe la interacción de los componentes dentro de un clúster compartido:
MongoDB fragmenta los datos a nivel de colección, distribuyendo los datos de la colección entre los fragmentos del clúster.
Claves de partición
MongoDB utiliza la clave de fragmentación para distribuir los documentos de la colección entre fragmentos. La clave de fragmentación consiste en uno o varios campos dentro de los documentos.
Los documentos en colecciones particionadas pueden no tener los campos de clave de partición. Los campos de clave de partición faltantes se tratan como si tuvieran valores nulos al distribuir los documentos entre las particiones, pero no al enrutar los query. Para obtener más información, consulta Campos de clave de partición faltantes.
Se selecciona la clave de fragmentación al fragmentar una colección.
A partir de MongoDB 5.0, puedes redistribuir una colección cambiando la clave de partición de una colección.
Para ajustar una clave de fragmentación, agrega un campo o campos de sufijo a la clave de fragmentación existente.
El valor de la clave de partición de un documento determina su distribución entre las particiones. Puede actualizar el valor de la clave de partición de un documento a menos que su campo de valor de la clave de partición sea el campo _id inmutable. Para obtener más información, consulte Cambiar el valor de la clave de partición de un documento.
Índice de clave de fragmentación
Para fragmentar una colección poblada, la colección debe tener un índice que comience con la clave de fragmentación. Al fragmentar una colección vacía, MongoDB crea el índice de soporte si la colección aún no tiene un índice adecuado para la clave de fragmentación especificada. Consulta los índices de clave de fragmentación.
Estrategia de clave de fragmentación
La elección de la clave de partición afecta al rendimiento, la eficiencia y la escalabilidad de un clúster particionado. Un clúster con el mejor hardware e infraestructura posible puede verse limitado por la elección de la clave de partición. La elección de la clave de partición y su índice de respaldo también puede afectar la estrategia de particionado que el clúster puede utilizar.
Fragmentos
MongoDB divide los datos fragmentados en fragmentos. Cada fragmento tiene un rango inferior inclusivo y superior exclusivo basado en la clave de fragmentación.
Balanceador y distribución uniforme de datos
En un intento de lograr una distribución uniforme de los datos entre todos los fragmentos del clúster, un balanceador se ejecuta en segundo plano para migrar rangos entre los fragmentos.
Ventajas de la fragmentación
Lecturas/escritura
MongoDB distribuye la carga de trabajo de lectura y escritura a través de los fragmentos en el clúster fragmentado, permitiendo que cada fragmento procese un subconjunto de operaciones del clúster. Tanto las cargas de trabajo de lectura como de escritura se pueden escalar horizontalmente en el clúster agregando más fragmentos.
Para los query que incluyen la clave de fragmentación o el prefijo de una clave de fragmentación compuesta, mongos puede dirigir la consulta a un fragmento específico o a un conjunto de particiones. Estas operaciones dirigidas son generalmente más eficientes que la difusión a cada partición en el clúster.
mongos puede brindar soporte para lecturas protegidas para minimizar las latencias.
Capacidad de almacenamiento
La fragmentación distribuye los datos a través de las particiones en el clúster para que cada fragmento contenga un subconjunto de los datos totales del clúster. A medida que el conjunto de datos crece, las particiones adicionales incrementan la capacidad de almacenamiento del clúster.
Alta disponibilidad
La implementación de servidores de configuración y particiones como sets de réplicas proporciona una mayor disponibilidad.
Incluso si uno o más sets de réplicas de particiones se vuelven completamente inaccesibles, el clúster puede continuar realizando lecturas y escrituras parciales. Es decir, aunque no se pueda acceder a los datos en las particiones no disponibles, las lecturas o las escrituras dirigidas a los fragmentos disponibles aún pueden realizarse con éxito.
Consideraciones antes de la fragmentación
Los requisitos y la complejidad de la infraestructura de clústeres fragmentados requieren una planificación, una ejecución y un mantenimiento cuidadosos.
Una vez que se ha fragmentado una colección, MongoDB no proporciona ningún método para desfragmentar una colección fragmentada.
Aunque se puede volver a particionar la colección más tarde, es importante considerar cuidadosamente la elección de la clave de partición para evitar problemas de escalabilidad y rendimiento.
Para entender los requisitos operativos y las restricciones para la fragmentación de la colección, se debe consultar Restricciones operativas en clústeres particionados.
Si los query no incluyen la clave de fragmentación o el prefijo de una clave de fragmentación compuesta, mongos realiza una operación de difusión, consultando todas las particiones en el clúster fragmentado. Estos query de dispersión/recopilación pueden ser operaciones de larga duración.
A partir de MongoDB 5.1, al iniciar, reiniciar o agregar un servidor de partición con sh.addShard() debe establecerse el nivel de confirmación de escritura (write concern) a nivel de clúster (CWWC).
Si el CWWC no está establecido y el fragmento está configurado de tal manera que el nivel de confirmación de escritura por defecto es { w : 1 }, el servidor de fragmentos no se iniciará o no se añadirá y devolverá un error.
Consulta los cálculos del nivel de confirmación de escritura (write concern) por defecto para obtener más información sobre cómo se calcula el nivel de confirmación de escritura por defecto.
Nota
Si hay un contrato de soporte activo con MongoDB, se debe considerar contactar al representante de cuenta para recibir ayuda con la planificación e implementación de clústeres particionados.
Colecciones fragmentadas y no fragmentadas
Una base de datos puede tener una combinación de colecciones fragmentadas y no fragmentadas. Las colecciones fragmentadas se particionan y distribuyen entre los fragmentos del clúster. Las colecciones no fragmentadas se almacenan en un fragmento principal. Cada base de datos tiene su propio fragmento principal.
Conexión a un clúster fragmentado
Debes conectarte a un enrutador mongos para interactuar con cualquier colección en el clúster. Esto incluye colecciones fragmentadas y no fragmentadas. Los clientes nunca deben conectarse a un solo fragmento para realizar operaciones de lectura o escritura.
Es posible realizar la conexión a un mongos de la misma manera que se hace la conexión a un mongod usando el mongosh o un driver de MongoDB.
Estrategia de fragmentación
MongoDB admite dos estrategias de fragmentación para distribuir datos en clústeres compartidos.
Particionamiento encriptado
La fragmentación encriptada implica calcular un hash del valor del campo de clave de fragmentación. A cada fragmento se le asigna un rango basado en los valores de la clave de fragmentación encriptada.
Tip
MongoDB calcula automáticamente los hashes al resolver los query utilizando índices encriptados. Las aplicaciones no necesitan calcular hashes.
Aunque un rango de claves de fragmentación puede ser "cercano", es poco probable que sus valores encriptados estén en el mismo fragmento. La distribución de datos basada en valores encriptados permite una distribución más uniforme, especialmente en conjuntos de datos donde la clave de fragmentación cambia monótonamente.
Sin embargo, la distribución encriptada significa que los query basados en rango en la clave de fragmentación tienen menos probabilidades de dirigirse a una sola partición, lo que resulta en más operaciones de difusión a nivel de clúster
Consulta la fragmentación encriptada para obtener más información.
Particionamiento clasificado por rango
La fragmentación clasificada por rango implica dividir los datos en rangos basados en los valores de la clave de fragmentación. Cada fragmento se asigna a continuación a un rango basado en los valores de la clave de fragmentación.
Es más probable que un rango de claves de fragmentación cuyos valores son "cercanos" residan en el mismo fragmento. Esto permite operaciones dirigidas, ya que un mongos puede dirigir las operaciones únicamente a las particiones que contienen los datos necesarios.
La eficiencia de la fragmentación clasificada por rango depende de la clave de fragmentación seleccionada. Las claves de fragmentación mal diseñadas pueden provocar una distribución desigual de los datos, lo que puede anular algunos beneficios de la fragmentación o causar cuellos de botella en el rendimiento. Ve selección de clave de fragmentación para fragmentación basada en rango.
Consulta Fragmentación clasificada por rango para obtener más información.
Zonas en clústeres compartidos
Las zonas pueden ayudar a mejorar la localidad de los datos para clústeres fragmentados que se extienden por múltiples centros de datos.
En clústeres particionados, puedes crear zonas de datos particionados basadas en la clave de partición. Puedes asociar cada zona con una o más particiones en el clúster. Una partición puede asociarse con cualquier cantidad de zonas. En un clúster equilibrado, MongoDB migra fragmentos cubiertos por una zona solo a aquellas particiones asociadas con la zona.
Cada zona cubre uno o más rangos de valores de clave de fragmentación. Cada rango que cubre una zona siempre incluye su límite inferior y excluye su límite superior.
Debes usar los campos contenidos en la clave de fragmentación al definir un nuevo rango para que una zona lo cubra. Si utilizas una clave de fragmentación compuesta, el rango debe incluir el prefijo de la clave de fragmentación. Consulta claves de fragmentación en zonas para más información.
El posible uso de zonas en el futuro debe tenerse en cuenta al elegir una clave de fragmentación.
Tip
Configurar zonas y rangos de zonas antes de particionar una colección vacía o inexistente permite una configuración más rápida de la partición zonificada.
Consulta las zonas para obtener más información.
Intercalaciones en la fragmentación
Utiliza el comando shardCollection con la opción collation :
{ locale : "simple" } para fragmentar una colección que tenga una intercalación por defecto. Para que la fragmentación sea exitosa, se requiere que:
La colección debe tener un índice cuyo prefijo sea la clave de fragmentación
El índice debe tener la intercalación
{ locale: "simple" }
Al crear nuevas colecciones con una intercalación, asegúrate de que estas condiciones se cumplan antes de fragmentar la colección.
Nota
Los query en la colección fragmentada continúan utilizando la intercalación por defecto configurada para la colección. Para usar la intercalación del índice de clave de fragmentación simple, especifique {locale : "simple"} en el documento de intercalación del query.
Consulta shardCollection para obtener más información sobre la fragmentación y la intercalación.
Flujos de cambio
A partir de MongoDB,3.6 losflujos de cambios están disponibles para conjuntos de réplicas y clústeres fragmentados. Permiten a las aplicaciones acceder a los cambios de datos en tiempo real sin la complejidad ni el riesgo de seguir el registro de operaciones. Las aplicaciones pueden usar flujos de cambios para suscribirse a todos los cambios de datos en una o varias colecciones.
Transacciones
Con la introducción de las transacciones distribuidas, las transacciones multi-documento están disponibles en clústeres particionados.
Hasta que se produzca la confirmación de una transacción, los cambios de datos realizados en la transacción no son visibles fuera de la transacción.
Sin embargo, cuando una transacción se guarda en múltiples fragmentos, no todas las operaciones de lectura externas necesitan esperar a que el resultado de la transacción confirmada sea visible en todos los fragmentos. Por ejemplo, si se confirma una transacción y la escritura 1 es visible en el fragmento A, pero la escritura 2 aún no es visible en el fragmento B, una lectura externa con el nivel de consistencia de lectura "local" puede leer los resultados de la escritura 1 sin ver la escritura 2.
Obtén más información
E-Book práctico de agregaciones de MongoDB
Para obtener más información sobre cómo funciona la fragmentación con agregaciones, lea el capítulo sobre fragmentación en Agregaciones prácticas de MongoDB. libro electrónico.