Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /

Escrituras locales distribuidas para cargas de trabajo solo de inserción

MongoDB Tag Aware Sharding permite a los administradores controlar la distribución de datos en un clúster fragmentado definiendo rangos de clave de partición y etiquetarlos en una o más particiones.

Este tutorial utiliza Zonas junto con una implementación de clúster multi-centro de datos y lógica en el lado de la aplicación para admitir escrituras locales distribuidas, así como una alta disponibilidad de escritura en caso de una elección de set de réplicas o falla del centro de datos.

Al definir las zonas y sus rangos antes de fragmentar una colección vacía o inexistente, la operación de recopilación de fragmentos crea fragmentos para los rangos de zona definidos, así como fragmentos adicionales para cubrir todo el rango de valores de clave de fragmento, y realiza una distribución inicial de fragmentos basada en los rangos de zona. Esta creación y distribución inicial de fragmentos permite una configuración más rápida de la fragmentación por zonas. Tras la distribución inicial, el balanceador gestiona la distribución de fragmentos en adelante.

Consulte Zonas predefinidas y rangos de zonas para una colección vacía o inexistente para ver un ejemplo.

Importante

Los conceptos comentados en este tutorial requieren una arquitectura de implementación específica y lógica a nivel de aplicación.

Estos conceptos requieren familiaridad con los clústeres fragmentados de MongoDB, sets de réplicas, y el comportamiento general de las zonas.

Este tutorial asume una carga de trabajo de solo inserción o con un uso intensivo de la misma. Los conceptos y estrategias que se describen en este tutorial no son adecuados para casos de uso que requieren lecturas o actualizaciones rápidas.

Considera una aplicación intensiva en inserciones, donde las lecturas son poco frecuentes y tienen baja prioridad comparadas con los guardados. La aplicación escribe documentos en una colección particionada y requiere un tiempo de actividad casi constante de la base de datos para cumplir con sus SLA o SLO.

Lo siguiente representa una visión parcial del formato de los documentos que la aplicación escribe en la base de datos:

{
"_id" : ObjectId("56f08c447fe58b2e96f595fa"),
"message_id" : 329620,
"datacenter" : "alfa",
"userid" : 123,
...
}
{
"_id" : ObjectId("56f08c447fe58b2e96f595fb"),
"message_id" : 578494,
"datacenter" : "bravo",
"userid" : 456,
...
}
{
"_id" : ObjectId("56f08c447fe58b2e96f595fc"),
"message_id" : 689979,
"datacenter" : "bravo",
"userid" : 789,
...
}

La colección utiliza el { datacenter : 1, userid : 1 } índice compuesto como clave de fragmento.

El campo datacenter en cada documento permite crear un rango de etiquetas en cada valor distinto del centro de datos. Sin el campo datacenter, no sería posible asociar un documento a un centro de datos específico.

El userid campo proporciona una cardinalidad alta y un componente de frecuencia baja a la clave del fragmento en relación datacenter con.

Consulte Elegir una clave de partición para obtener instrucciones más generales sobre cómo seleccionar una clave de partición.

La implementación consiste en dos centros de datos, alfa y bravo. Existen dos particiones, shard0000 y shard0001. Cada partición es un set de réplicas con tres miembros. shard0000 tiene dos nodos en alfa y un nodo de prioridad 0 en bravo. shard0001 tiene dos nodos en bravo y un nodo de prioridad 0 en alfa.

Diagrama de la arquitectura de un clúster fragmentado para alta disponibilidad

Esta aplicación requiere una etiqueta por centro de datos. A cada partición se le asigna una etiqueta en función del centro de datos que contiene la mayoría de los miembros de su conjunto de réplicas. Hay dos rangos de etiquetas, uno para cada centro de datos.

alfa Datacenter

Etiquete las particiones que tengan la mayoría de los nodos en este centro de datos como alfa.

Crea un rango de etiquetas con:

  • un límite inferior de { "datacenter" : "alfa", "userid" : MinKey },

  • un límite superior de { "datacenter" : "alfa", "userid" : MaxKey }, y

  • la etiqueta alfa

bravo Datacenter

Etiquete las particiones que tengan la mayoría de los nodos en este centro de datos como bravo.

Crea un rango de etiquetas con:

  • un límite inferior de { "datacenter" : "bravo", "userid" : MinKey },

  • un límite superior de { "datacenter" : "bravo", "userid" : MaxKey }, y

  • la etiqueta bravo

Nota

Los valores MinKey y MaxKey son valores especiales reservados para comparaciones

En base a las etiquetas y los rangos de etiquetas configurados, mongos enruta documentos con datacenter : alfa al Centro de Datos alfa y documentos con datacenter : bravo al Centro de Datos bravo.

Si un documento insertado o actualizado coincide con un rango de etiquetas configurado, solo se puede guardar en una partición con la etiqueta relacionada.

MongoDB puede escribir documentos que no coincidan con un rango de etiquetas configurado en cualquier partición del clúster.

Nota

El comportamiento descrito anteriormente requiere que el clúster se encuentre en un estado estable sin fragmentos que violen un rango de etiquetas configurado. Consulte la siguiente sección sobre balanceador para más información.

El balanceador migra los fragmentos etiquetados a la partición correspondiente. Hasta la migración, las particiones pueden contener fragmentos que violan los rangos de etiquetas y las etiquetas configurados. Una vez que se complete el balanceo, las particiones solo deben contener fragmentos cuyos rangos no infrinjan sus etiquetas asignadas y los rangos de etiquetas.

Agregar o remover etiquetas o rangos de etiquetas puede resultar en migraciones de fragmentos. Dependiendo del tamaño de tu conjunto de datos y del número de fragmentos que afecte el rango de etiquetas, estas migraciones pueden impactar el rendimiento del clúster. Considera ejecutar tu balanceador durante ventanas programadas específicas. Consulta Programar la Ventana de Balance para un tutorial sobre cómo configurar una ventana de programación.

Por defecto, la aplicación escribe en el centro de datos más cercano. Si el centro de datos local está inactivo o si los guardados en ese centro de datos no se reconocen dentro de un período de tiempo establecido, la aplicación cambia al otro centro de datos disponible cambiando el valor del campo datacenter antes de intentar guardar el documento en la base de datos.

La aplicación admite tiempos de espera de escritura. Utiliza Write Concern para establecer un tiempo de espera para cada operación de escritura.

Si la aplicación encuentra un error de guardar o de tiempo de espera, modifica el campo datacenter en cada documento y realiza la operación de guardar. Esto enruta el documento al otro centro de datos. Si ambos centros de datos están caídos, las operaciones de guardar no pueden tener éxito. Consulte Resuelva el error al guardar.

La aplicación verifica periódicamente la conectividad a cualquier centro de datos marcado como “caído”. Si se restablece la conectividad, la aplicación puede continuar realizando operaciones normales de guardado.

Dada la lógica de conmutación, así como los balanceadores de carga o mecanismos similares implementados para gestionar el tráfico de clientes entre centros de datos, la aplicación no puede predecir en cuál de los dos centros de datos se escribió un documento determinado. Para garantizar que no se pierda ningún documento durante las operaciones de lectura, la aplicación debe realizar consultas de difusión sin incluir el datacenter campo en ninguna consulta.

La aplicación realiza lecturas utilizando una preferencia de lectura de nearest para reducir la latencia.

Es posible que una operación de escritura se complete correctamente a pesar de un error de tiempo de espera. La aplicación responde al error intentando reescribir el documento en el otro centro de datos; esto puede provocar la duplicación del documento en ambos centros de datos. La aplicación resuelve los duplicados como parte de la lógica de lectura.

La aplicación tiene la lógica para cambiar de centro de datos si uno o más guardados fallan o si los guardados no se confirman dentro de un periodo de tiempo determinado. La aplicación modifica el campo datacenter según la etiqueta del centro de datos objetivo para dirigir el documento hacia ese centro de datos.

Por ejemplo, una aplicación que intenta guardar en el centro de datos alfa podría seguir este procedimiento general:

  1. Intento de guardar un documento, especificando datacenter : alfa.

  2. En caso de tiempo de espera de escritura o error, se registra alfa como momentáneamente inactivo.

  3. Intenta guardar el mismo documento, modificando datacenter : bravo.

  4. En caso de tiempo de espera de escritura o error, se registra bravo como momentáneamente inactivo.

  5. Si tanto alfa como bravo están inactivos, se deben registrar e informar los errores.

Consulta Resolver error de guardado.

Debe estar conectado a un mongos asociado con el clúster fragmentado de destino para continuar. No puedes crear etiquetas conectándote directamente a un miembro de un set de réplicas.

1

Etiquete cada fragmento en el centro de datos alfa con la etiqueta alfa.

sh.addShardTag("shard0000", "alfa")

Etiquete cada fragmento en el centro de datos bravo con la etiqueta bravo.

sh.addShardTag("shard0001", "bravo")

Puede revisar las etiquetas asignadas a cualquier fragmento determinado sh.status() ejecutando.

2

Defina el rango de la alfa base de datos y asócielo a la alfa etiqueta mediante el método. Este método sh.addTagRange() requiere:

  • El namespace completo de la colección objetivo.

  • El límite inferior inclusivo del rango.

  • El límite superior exclusivo del rango.

  • El nombre de la etiqueta.

sh.addTagRange(
"<database>.<collection>",
{ "datacenter" : "alfa", "userid" : MinKey },
{ "datacenter" : "alfa", "userid" : MaxKey },
"alfa"
)

Defina el rango de la bravo base de datos y asócielo a la bravo etiqueta mediante el método. Este método sh.addTagRange() requiere:

  • El namespace completo de la colección objetivo.

  • El límite inferior inclusivo del rango.

  • El límite superior exclusivo del rango.

  • El nombre de la etiqueta.

sh.addTagRange(
"<database>.<collection>",
{ "datacenter" : "bravo", "userid" : MinKey },
{ "datacenter" : "bravo", "userid" : MaxKey },
"bravo"
)

Los valores MinKey y MaxKey son valores reservados especiales para comparaciones. MinKey siempre se compara como menor que cualquier otro valor posible, mientras que MaxKey siempre se compara como mayor que cualquier otro valor posible. Los rangos configurados registran a cada usuario para cada datacenter.

3

La próxima vez que se ejecute el balanceador, migrará los datos a través de los fragmentos respetando las zonas configuradas.

Una vez que finaliza el equilibrado, las particiones etiquetadas como alfa solo deben contener documentos con datacenter : alfa, mientras que las particiones etiquetadas como bravo solo deben contener documentos con datacenter : bravo.

Puedes revisar la distribución de fragmentos ejecutando sh.status().

Cuando el centro de datos predeterminado de la aplicación está inactivo o es inaccesible, la aplicación cambia el campo datacenter al otro centro de datos.

Por ejemplo, la aplicación intenta guardar el siguiente documento en el centro de datos alfa de forma predeterminada:

{
"_id" : ObjectId("56f08c447fe58b2e96f595fa"),
"message_id" : 329620,
"datacenter" : "alfa",
"userid" : 123,
...
}

Si la aplicación recibe un error al intentar escribir, o si el reconocimiento de escritura tarda demasiado, la aplicación registra el centro de datos como no disponible y modifica el campo datacenter para apuntar al centro de datos bravo.

{
"_id" : ObjectId("56f08c457fe58b2e96f595fb"),
"message_id" : 329620,
"datacenter" : "bravo",
"userid" : 123,
...
}

La aplicación revisa periódicamente el centro de datos alfa para verificar la conectividad. Si el centro de datos vuelve a ser accesible, la aplicación puede reanudar los guardados normales.

Nota

Es posible que el guardado original en datacenter : alfa haya tenido éxito, especialmente si el error estaba relacionado con un tiempo de espera. Si es así, el documento con message_id : 329620 ahora puede duplicarse en ambos centros de datos. Las aplicaciones deben resolver duplicados como parte de las operaciones de lectura.

La lógica de cambio de la aplicación permite una duplicación potencial de documentos. Al realizar lecturas, la aplicación resuelve cualquier documento duplicado en la capa de la aplicación.

La siguiente query busca documentos donde el userid es 123. Observa que aunque userid es parte de la clave de partición, la query no incluye el campo datacenter y, por lo tanto, no realiza una operación de lectura dirigida.

db.collection.find( { "userid" : 123 } )

Los resultados muestran que el documento con message_id de 329620 se ha insertado en MongoDB dos veces, probablemente como resultado de un reconocimiento de escritura retrasado.

{
"_id" : ObjectId("56f08c447fe58b2e96f595fa"),
"message_id" : 329620
"datacenter" : "alfa",
"userid" : 123,
data : {...}
}
{
"_id" : ObjectId("56f08c457fe58b2e96f595fb"),
"message_id" : 329620
"datacenter" : "bravo",
"userid" : 123,
...
}

La aplicación puede ignorar los duplicados, tomando uno de los dos documentos, o intentar recortar los duplicados hasta que solo quede un único documento.

Un método para eliminar duplicados es utilizar el método ObjectId.getTimestamp() para extraer la marca de tiempo del campo _id . La aplicación puede entonces mantener el primer documento insertado o el último documento insertado. Esto supone que el campo _id usa el ObjectId()de MongoDB.

Por ejemplo, usar getTimestamp() en el documento con ObjectId("56f08c447fe58b2e96f595fa") da como resultado:

ISODate("2016-03-22T00:05:24Z")

El uso de getTimestamp() en el documento con ObjectId("56f08c457fe58b2e96f595fb") devuelve:

ISODate("2016-03-22T00:05:25Z")

Volver

Segmentar por aplicación o cliente

En esta página