Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Divida un almacén de datos en un conjunto de particiones horizontales o fragmentos. Este enfoque puede mejorar la escalabilidad al almacenar y acceder a grandes volúmenes de datos.
Contexto y problema
Un almacén de datos en un solo servidor tiene las siguientes limitaciones:
Espacio de almacenamiento: Un almacén de datos para una aplicación en la nube a gran escala puede contener un gran volumen de datos que crece con el tiempo. Un servidor proporciona una cantidad finita de almacenamiento en disco y puede reemplazar los discos existentes por discos más grandes o agregar más discos a medida que crecen los volúmenes de datos. El sistema finalmente alcanza un límite en el que no se puede aumentar la capacidad de almacenamiento en un solo servidor.
Recursos informáticos: Una aplicación en la nube debe admitir un gran número de usuarios simultáneos que ejecutan consultas en el almacén de datos. Es posible que un único servidor no proporcione suficiente capacidad de computación para esta carga, lo que da lugar a tiempos de espera prolongados y a tiempos de espera. Puede agregar procesadores de memoria o actualización, pero el sistema alcanza un límite en el que no puede aumentar aún más los recursos de proceso.
Ancho de banda de red: La velocidad a la que un único servidor puede recibir solicitudes y enviar respuestas limita el rendimiento del almacén de datos. El volumen de tráfico de red puede superar la capacidad de la conexión de red, lo que da lugar a solicitudes con error.
Geografía: Los requisitos legales, de cumplimiento o de rendimiento pueden requerir que almacene datos de usuario en la misma región geográfica que los usuarios. Si los usuarios abarcan países o regiones, es posible que no pueda almacenar todos los datos de la aplicación en un único almacén de datos.
Para posponer estas limitaciones temporalmente, puede escalar verticalmente agregando capacidad de disco, potencia de procesamiento, memoria y conexiones de red. Una aplicación en la nube que debe admitir un gran número de usuarios y grandes volúmenes de datos debe escalar horizontalmente.
Solución
Dividir el almacén de datos en particiones horizontales o fragmentos. Cada partición tiene el mismo esquema, pero contiene su propio subconjunto distinto de los datos. Cada partición es un almacén de datos completo que puede contener datos para muchas entidades de distintos tipos. Una partición se ejecuta en un servidor que funciona como nodo de almacenamiento.
Este modelo proporciona las siguientes ventajas:
Puede escalar el sistema añadiendo más fragmentos en nodos de almacenamiento adicionales.
Un sistema puede usar hardware precompilado en lugar de equipos especializados y costosos para cada nodo de almacenamiento.
Puede reducir la contención y mejorar el rendimiento al equilibrar la carga de trabajo entre los fragmentos.
En la nube, las particiones pueden residir físicamente cerca de los usuarios que acceden a los datos.
Al dividir un almacén de datos en particiones, decida qué datos colocar en cada partición. Cada partición normalmente contiene elementos agrupados por uno o varios atributos de datos. Estos atributos forman la clave de fragmento, a veces denominada clave de partición.
El sharding organiza físicamente los datos. Cuando una aplicación almacena y recupera datos, la lógica de particionamiento la dirige a la partición adecuada. Puede implementar esta lógica en el código de acceso a datos de la aplicación o en el sistema de almacenamiento de datos si admite de forma transparente el particionamiento.
La abstracción de la ubicación física de los datos en la lógica de particionamiento proporciona control sobre qué particiones contienen qué datos. También puede migrar datos entre particiones sin modificar la lógica de negocios de la aplicación cuando necesite redistribuir datos, como cuando las particiones se vuelven desequilibradas. La compensación es el costo adicional del acceso a datos para determinar la localización de cada elemento de datos durante la recuperación.
Selección de clave de partición
La clave de partición es la decisión de diseño más crítica en un sistema particionado. Para cambiar una clave de partición después de elegirla, normalmente debe migrar todos los datos a un nuevo diseño de partición, que es una operación costosa y arriesgada en un sistema activo. Tome esta decisión cuidadosamente antes de escribir cualquier código.
Una clave de partición eficaz es inmutable, tiene una cardinalidad alta, distribuye los datos y carga uniformemente, y se alinea con los patrones de consulta dominantes para que la mayoría de las solicitudes se resuelvan en una sola partición. Evite aumentar de forma monotónica los valores (enteros de autoincremento y marcas de tiempo secuenciales), los atributos de cardinalidad baja (booleanos y conjuntos de enumeraciones pequeños) y los atributos volátiles que cambian con frecuencia. Estos atributos conducen a zonas activas o a un costoso movimiento de datos entre particiones.
Si ningún atributo único cumple estos criterios, defina una clave de partición compuesta combinando dos o más atributos. Si las consultas necesitan recuperar datos por atributos que no forman parte de la clave de fragmento, use un patrón como el patrón de tabla índice para proporcionar búsquedas secundarias.
Para más información sobre cómo elegir claves de partición en los servicios de Azure, consulte Guía de creación de particiones de datos y Estrategias de creación de particiones de datos.
Estrategias de particionamiento
Use una de las estrategias siguientes al seleccionar la clave de partición y decida cómo distribuir datos entre particiones. No necesita una correspondencia uno a uno entre fragmentos y los servidores que los hospedan. Un solo servidor puede hospedar varias particiones.
Estrategia de particionamiento de búsqueda
En la estrategia de búsqueda, también denominada estrategia basada en directorios, la lógica de particionamiento implementa un mapa que enruta una solicitud de datos a la partición que contiene esos datos mediante la clave de partición. En una aplicación multiinquilino, puede almacenar todos los datos de un inquilino juntos en una partición mediante el identificador de inquilino como clave de partición. Varios inquilinos pueden compartir la misma partición, pero los datos de un solo inquilino no se distribuyen entre varias particiones. En el siguiente diagrama se muestra la fragmentación de los datos de inquilinos basada en los identificadores de inquilinos.
La asignación entre los valores de clave de partición y el almacenamiento físico puede ser directa, donde cada valor de clave de partición se asigna a una partición física. Una técnica más flexible es la creación de particiones virtuales, donde los valores de clave de partición se asignan a particiones virtuales y, a continuación, el sistema asigna esas particiones virtuales a menos particiones físicas. Una aplicación busca datos mediante un valor de clave de partición que hace referencia a una partición virtual y el sistema asigna de forma transparente particiones virtuales a particiones físicas. La asignación entre una partición virtual y una partición física puede cambiar sin necesidad de modificaciones en el código de aplicación.
Estrategia de fragmentación basada en rangos
La estrategia basada en intervalos agrupa los elementos relacionados en el mismo fragmento y los ordena por clave de fragmento secuencial. Esta estrategia admite aplicaciones que recuperan con frecuencia conjuntos de elementos mediante consultas de intervalo. Las consultas de intervalo devuelven un conjunto de elementos de datos para una clave de fragmento que se encuentra dentro de un intervalo determinado.
Por ejemplo, si una aplicación necesita encontrar regularmente todos los pedidos realizados en un mes determinado, puede recuperar los datos más rápido si almacena todos los pedidos de un mes en el orden de fecha y hora en la misma partición. Si almacena cada pedido en una partición diferente, la aplicación tiene que capturarlos individualmente mediante la realización de un gran número de consultas de punto. En el diagrama siguiente se muestran conjuntos secuenciales, o intervalos, de datos almacenados en particiones.
En este ejemplo, la clave de fragmentación es una clave compuesta que contiene el mes del pedido como el elemento más significativo, seguido del día y la hora del pedido. Los nuevos pedidos se ordenan naturalmente a medida que se crean y se añaden a un fragmento.
Algunos almacenes de datos admiten claves de partición de dos partes. Una clave de partición identifica la partición y una clave de fila identifica de forma única un elemento dentro de la partición. La partición normalmente almacena los datos en el orden de las claves de fila. Para los elementos que necesitan consultas de intervalo y deben agruparse, puede usar una clave de fragmento que tenga el mismo valor para la clave de partición, pero un valor único para la clave de fila.
Estrategia de particionamiento basada en hash
La estrategia basada en hash reduce la posibilidad de zonas activas, que son particiones que reciben una cantidad desproporcionada de carga. Esta estrategia distribuye los datos entre particiones para equilibrar el tamaño de cada partición y la carga media que encuentra cada partición. La lógica de particionamiento calcula la partición para almacenar un elemento en función de un hash de uno o más atributos de los datos. La función hash elegida debe distribuir los datos uniformemente entre las particiones. En el diagrama siguiente se muestra la fragmentación de los datos de los inquilinos a partir de un hash de sus ID.
Para comprender la ventaja de la estrategia hash sobre otras estrategias de fragmentación, piense en cómo una aplicación multiinquilino que inscribe nuevos clientes secuencialmente podría asignar los clientes a fragmentos en la base de datos. Cuando se usa la estrategia de intervalo, los datos de los inquilinos de 1 a n se almacenan en la partición A, los datos de los inquilinos n+1 a m se almacenan en la partición B y los intervalos de inquilinos posteriores se asignan a particiones sucesivas. Si los inquilinos registrados más recientemente también son los más activos, la mayoría de la actividad de datos se produce en algunos fragmentos, lo que puede provocar zonas críticas. Por el contrario, la estrategia hash asigna inquilinos a particiones en función de un hash de su identificador de inquilino. El hash suele distribuir entidades secuenciales entre diferentes particiones, lo que equilibra la carga. En el diagrama anterior se muestra este enfoque para los inquilinos 55 y 56.
Estrategia de particionamiento geográfico
La estrategia geográfica asigna datos a particiones en función del origen geográfico o de la región de consumo prevista de esos datos. En muchas cargas de trabajo, los usuarios y los datos que generan se concentran en regiones específicas. Los requisitos normativos, como las leyes de residencia de datos, pueden requerir que los datos específicos permanezcan dentro de una jurisdicción específica. Incluso sin controladores normativos, colocar los datos cerca de los usuarios que acceden a ellos con más frecuencia reduce la latencia de red para lecturas y escrituras.
En esta estrategia, se deriva la clave de partición de un atributo geográfico, como el país o región del usuario, la región del centro de datos de origen o un identificador de inquilino regional. Cada fragmento se hospeda o se fija a la infraestructura dentro de ese límite geográfico.
Por ejemplo, una aplicación que atiende a los clientes de Norteamérica, Europa y Asia-Pacific podría mantener tres grupos de particiones, un grupo en cada región de Azure correspondiente. Una aplicación europea que solo atiende a los usuarios europeos enruta una solicitud a la partición de Europa. Este enfoque reduce la latencia y cumple los requisitos de residencia de datos.
El particionamiento geográfico presenta el riesgo de distribución de datos desigual. Si la mayoría de los usuarios residen en una región, la partición de esa región conlleva una carga y almacenamiento desproporcionados. Puede combinar particionamiento geográfico con otra estrategia, como hash o búsqueda, dentro de cada región para distribuir la carga uniformemente entre varias particiones dentro del mismo límite geográfico.
Ventajas y consideraciones para cada estrategia
Las cuatro estrategias de particionamiento tienen las siguientes ventajas y consideraciones:
La estrategia de búsqueda proporciona más control sobre la configuración de particiones. Las particiones virtuales reducen el impacto del reequilibrio porque puede agregar nuevas particiones físicas para equilibrar la carga de trabajo. Puede modificar la asignación entre una partición virtual y sus particiones físicas sin afectar al código de aplicación. La búsqueda de ubicaciones de particiones agrega sobrecarga.
La estrategia de rango es fácil de implementar y funciona bien con consultas de rango. Las consultas de intervalo pueden recuperar varios elementos de datos de una sola partición en una sola operación. La administración de datos es más sencilla. Por ejemplo, puede programar actualizaciones por zona horaria en función de los patrones de carga locales cuando los usuarios de la misma región comparten una partición. Sin embargo, esta estrategia no equilibra la carga uniformemente entre fragmentos. El reequilibrio es difícil y podría no resolver la carga desigual cuando la mayoría de la actividad se concentra en las claves de partición adyacentes.
La estrategia de hash proporciona una mejor oportunidad de una distribución uniforme de los datos y la carga. Puede enrutar las solicitudes directamente mediante la función hash sin mantener un mapa. Calcular el hash agrega cierta sobrecarga. El reequilibrio es difícil sin un hash coherente.
La estrategia geográfica cumple los requisitos de residencia y soberanía de datos que otras estrategias no abordan de forma inherente. Reduce la latencia de lectura y escritura cuando los usuarios acceden a los datos de su región. Sin embargo, el particionamiento geográfico puede crear datos significativos y desequilibrios de carga cuando las poblaciones de usuarios no se distribuyen uniformemente entre regiones. Las consultas que abarcan regiones, como los informes globales, deben recuperar datos de todas las particiones geográficas e incurrir en una mayor latencia. Combine el particionamiento geográfico con otra estrategia dentro de cada región cuando se requiera tanto cumplimiento como una distribución de carga equitativa.
La mayoría de los sistemas de particionamiento implementan uno de estos enfoques, pero también debe tener en cuenta los requisitos empresariales de la aplicación y sus patrones de uso de datos. Por ejemplo, en una aplicación multitenencia:
Puede particionar datos en función de la carga de trabajo. Segrega los datos de los inquilinos altamente volátiles en particiones independientes para mejorar la velocidad de acceso a los datos para otros inquilinos.
Puede particionar datos en función de la ubicación del inquilino. Desconectar los datos de inquilino en una región geográfica específica para realizar copias de seguridad y mantenimiento durante las horas de poca actividad de esa región, mientras que los datos de inquilino de otras regiones permanecen en línea durante sus horas laborables.
Asigne inquilinos de alto valor a sus propios fragmentos dedicados y ligeramente cargados. Los inquilinos de menor valor pueden compartir fragmentos empaquetados más densamente.
Almacene los datos de los clientes que requieren un aislamiento de datos sólido y privacidad en servidores independientes.
Escalado y operaciones de movimiento de datos para cada estrategia
Cada estrategia de fragmentación proporciona diferentes funcionalidades y niveles de complejidad para administrar el escalado interno, el escalado externo, el movimiento de datos y el mantenimiento del estado.
La estrategia de búsqueda permite el escalado y las operaciones de movimiento de datos en el nivel de usuario, ya sea en línea o sin conexión. Para mover datos:
Suspenda algunas o todas las actividades del usuario, normalmente durante los períodos de poca actividad.
Mueva los datos a la nueva partición virtual o a la partición física.
Actualice los mapeos.
Invalide o actualice las memorias caché que contengan estos datos.
Reanude la actividad del usuario.
A menudo, puede administrar esta operación de forma centralizada. La estrategia de búsqueda requiere que el estado sea altamente almacenable en caché y compatible con la réplica.
La estrategia de intervalo limita las operaciones de escalado y movimiento de datos porque se deben dividir y fusionar datos entre fragmentos, normalmente cuando parte o todo el almacén de datos está sin conexión. Al mover datos para reequilibrar particiones, es posible que no elimine la carga desigual si la mayoría de la actividad se concentra en claves de partición adyacentes o identificadores de datos dentro del mismo intervalo. La estrategia de rango también puede requerir que el estado asigne intervalos a particiones físicas.
La estrategia hash complica las operaciones de escalado y movimiento de datos. Las claves de partición son hashes de las claves de fragmento o identificadores de datos. Con una función hash estándar, como
hash(key) mod N, agregando o quitando una partición reasigna la mayoría de las claves y desencadena la migración de datos a gran escala. El hashing consistente reduce este impacto organizando el espacio de hash para que solo se mueva una pequeña fracción de claves cuando cambia el número de fragmentos. La estrategia de hash no requiere mantener un estado de mapeo independiente.La estrategia geográfica vincula directamente las operaciones de escalado al aprovisionamiento de infraestructura regional. Agregar capacidad en una región no alivia la carga en otra región. Los requisitos normativos que exigen particionamiento geográfico también pueden restringir el movimiento de datos a través de límites geográficos. Dentro de cada región, el escalado usa la estrategia secundaria que distribuye los datos entre las particiones de esa región.
Problemas y consideraciones
Tenga en cuenta los siguientes puntos a medida que decida cómo implementar este patrón:
Use sharding como complemento a otras formas de particionamiento, como el particionamiento vertical y el particionamiento funcional. Por ejemplo, un solo fragmento puede contener entidades particionadas verticalmente, y puede implementar una partición funcional como varios fragmentos. Para obtener más información, consulte Creación de particiones de datos horizontales, verticales y funcionales.
Mantenga los fragmentos equilibrados para que puedan manejar un volumen de entrada/salida (E/S) similar. El sesgo de datos se acumula con el tiempo cuando se insertan y eliminan registros, lo que lleva a puntos críticos. Planifique reequilibrar periódicamente.
El reequilibrio mueve los datos entre particiones y a menudo provoca tiempo de inactividad o un rendimiento reducido. Para reequilibrar con menos frecuencia, use particiones virtuales. Mapee muchas particiones lógicas a menos fragmentos físicos. Cuando se sobrecarga una partición, redistribuya sus particiones virtuales a nuevas particiones físicas sin volver a guardar el conjunto de datos completo. Azure Cosmos DB usa este enfoque para desacoplar el esquema de partición de la infraestructura física.
Prefiere muchos fragmentos pequeños a pocos grandes. Las particiones más pequeñas se migran más rápido, equilibran la carga de forma más uniforme y proporcionan más flexibilidad para la redistribución de datos.
Use datos estables para la clave de partición. Si cambia la clave de partición, es posible que tenga que mover el elemento de datos correspondiente entre particiones, lo que aumenta la sobrecarga de la operación de actualización. Evite basar la clave de partición en información potencialmente volátil. Elija los atributos que son invariables o forman de forma natural una clave.
Asegúrese de que las claves de partición sean únicas. Por ejemplo, evite usar campos de incremento automático como la clave de partición. En algunos sistemas, los campos autoincrementados no se pueden coordinar entre particiones, lo que puede dar lugar a que los elementos de particiones diferentes tengan la misma clave de partición.
Nota:
Los valores autoincrementados en otros campos que no son claves de fragmento también pueden causar problemas. Por ejemplo, si usa campos autoincrementados para generar identificadores únicos, se podrían asignar dos elementos diferentes en particiones diferentes al mismo identificador.
Particione los datos para admitir las consultas realizadas con más frecuencia. Es posible que no pueda diseñar una clave de partición que coincida con los requisitos de cada consulta en los datos. Si es necesario, cree tablas de índice secundarias para admitir consultas que recuperan datos por atributos que no forman parte de la clave de partición. Para obtener más información, vea Patrón de tabla de índice.
Diseñe la clave de partición y el modelo de datos para mantener la mayoría de las operaciones en el ámbito de una sola partición. Las consultas que acceden solo a una sola partición son más eficaces que las consultas que recuperan datos de varias particiones. Desnormalice los datos para mantener las entidades relacionadas que se consultan normalmente, como los clientes y sus pedidos, en la misma partición para reducir el número de lecturas independientes.
Las consultas entre particiones agregan latencia, consumo de recursos y complejidad. Cuando una aplicación debe recuperar datos de varias particiones, use consultas de distribución ramificada paralelas que se ejecutan en cada partición simultáneamente y agregue los resultados. Incluso con el paralelismo, la partición más lenta determina la latencia general.
Sugerencia
Si una entidad de una partición hace referencia a una entidad en otra partición, incluya la clave de partición para la segunda entidad como parte del esquema de la primera entidad. Este enfoque puede mejorar el rendimiento de las consultas que hacen referencia a datos relacionados entre particiones.
Reconsidere la clave de partición o si el particionamiento se ajusta a sus necesidades si la carga de trabajo requiere una integridad transaccional sólida en los límites de particiones. Las transacciones entre particiones presentan desafíos. Protocolos de coordinación distribuidos, como la confirmación en dos fases, agregar latencia, introducir modos de error y reducir el rendimiento. La mayoría de los sistemas particionados evitan transacciones distribuidas y adoptan la coherencia final en su lugar. En este modelo, cada partición se actualiza de forma independiente y la aplicación controla incoherencias temporales.
Asegúrese de que los recursos disponibles para cada nodo de almacenamiento de particiones pueden controlar los requisitos de escalabilidad en términos de tamaño y rendimiento de los datos. Para más información, consulte Estrategias de creación de particiones de datos.
Considere la posibilidad de replicar los datos de referencia en todos los fragmentos. Si una consulta en una partición también hace referencia a datos estáticos o de movimiento lento, agregue estos datos a la partición. Después, la aplicación puede capturar todos los datos de la consulta sin realizar un recorrido de ida y vuelta a un almacén de datos independiente.
Nota:
Si los datos de referencia que se mantienen en varias particiones cambian, el sistema debe sincronizar estos cambios en todas las particiones. Se puede producir algún grado de incoherencia mientras se ejecuta esta sincronización. Diseñe las aplicaciones para tolerar esta incoherencia.
Los sistemas fragmentados multiplican la carga operativa. Prevea estas preocupaciones:
Supervisión: Debe agregar métricas y registros en todas las particiones para obtener una vista completa del estado del sistema.
Copia de seguridad y restauración: Debe realizar una copia de seguridad de cada partición de forma independiente y diseñar procedimientos de restauración para mantener la coherencia entre particiones. Una restauración a un momento dado de una partición puede crear incoherencias con otras particiones.
Cambios de esquema: Debe coordinar los cambios del lenguaje de definición de datos (DDL) en todas las particiones.
Puede implementar estas tareas mediante scripts u otras soluciones de automatización.
Puede geolocalizar particiones para colocar sus datos cerca de las instancias de aplicación que las usan. Este enfoque puede mejorar el rendimiento, pero requiere un planeamiento adicional para las operaciones que deben tener acceso a varias particiones en diferentes ubicaciones.
Cuándo usar este patrón
Sugerencia
Antes de diseñar una capa de particionamiento personalizada, determine qué responsabilidades de particionamiento ya controla la plataforma de datos. Algunos servicios administran completamente el particionamiento. Por ejemplo, Azure Cosmos DB distribuye los datos entre particiones físicas, controla las divisiones y enruta las consultas sin intervención de la aplicación. Otros servicios gestionan el sharding parcialmente. Por ejemplo, Azure SQL Database proporciona herramientas de base de datos elásticas para la administración de mapas de particiones y el enrutamiento dependiente de los datos, pero diseña la clave de partición y administra las operaciones de división. Use el patrón de particionamiento al compilar y operar la lógica de particionamiento usted mismo.
Use este patrón en los siguientes supuestos:
El volumen total de datos supera la capacidad de almacenamiento de una sola instancia de base de datos y ninguna opción de escalado vertical aborda el déficit.
El rendimiento de la transacción o la simultaneidad de consultas supera lo que una sola instancia puede admitir y las réplicas de lectura por sí solas no resuelven el cuello de botella porque la carga de escritura también es alta.
Nota:
El particionamiento mejora el rendimiento y la escalabilidad de un sistema, y también puede mejorar la disponibilidad. Un error en una partición no impide necesariamente que una aplicación acceda a datos en otras particiones. Y un operador puede realizar el mantenimiento o la recuperación de una partición sin hacer que todos los datos no estén disponibles. Para obtener más información, consulte Guía de creación de particiones de datos.
Los requisitos normativos o de cumplimiento exigen que determinados subconjuntos de datos residan en jurisdicciones geográficas específicas y que ninguna implementación de una sola región pueda cumplir todos los requisitos.
Los distintos inquilinos o segmentos de cliente requieren aislamiento de datos físicos por motivos de seguridad, rendimiento o contractuales.
En escenarios como estos, el patrón de particionamiento se aplica a veces más allá de los almacenes de datos tradicionales. Por ejemplo, un sistema de administración de zonas DNS podría particionarse por equipo, entorno o región para reducir el radio de explosión de los cambios de DNS y establecer límites de propiedad claros. En ese contexto, la motivación principal es la segmentación operativa en lugar de la escalabilidad. Para más información, consulte Fragmentación de zonas DNS privadas (Sharding private DNS zones).
El particionamiento introduce una complejidad sustancial y permanente en la arquitectura de datos. Esa complejidad afecta al desarrollo, las operaciones, las pruebas, el diseño de consultas y la recuperación de errores durante la vigencia del sistema.
Este patrón podría no ser adecuado cuando:
El volumen de datos y el rendimiento encajan en una sola instancia de base de datos, incluso con un crecimiento proyectado. El escalado vertical conserva la simplicidad de las consultas y la integridad transaccional.
El cuello de botella es el volumen de lectura, no el volumen de escritura ni la capacidad de almacenamiento. Las réplicas de lectura y las capas de caché pueden descargar el tráfico de lectura sin la complejidad de la consulta entre fragmentos que presenta el particionamiento.
El motor de base de datos admite la creación de particiones de nivel de tabla que satisfaga sus necesidades de rendimiento. La creación de particiones dentro de una sola instancia no requiere varios servidores ni lógica de enrutamiento.
Los patrones de consulta dominantes requieren combinaciones entre entidades, transacciones multientidad o agregaciones de conjuntos de datos completos. El particionamiento hace que estas operaciones sean costosas y la sobrecarga de las consultas de distribución y la coordinación distribuida pueden superar las ventajas de escalado.
Diseño de cargas de trabajo
Evalúe cómo usar el patrón de particionamiento en el diseño de una carga de trabajo para abordar los objetivos y los principios descritos en los pilares de Azure Well-Architected Framework. En la tabla siguiente se proporciona una guía sobre cómo este patrón apoya los objetivos de cada pilar.
| Fundamento | Cómo apoya este patrón los objetivos de los pilares |
|---|---|
| Las decisiones de diseño de fiabilidad ayudan a que su carga de trabajo sea resiliente a fallos y garantizan que se recupere a un estado de pleno funcionamiento después de que se produzca un fallo. | Los datos y el procesamiento se aíslan en la partición, por lo que un mal funcionamiento de una partición permanece aislado en esa partición. - Creación de particiones de datos - RE:07 Autopreservación |
| La optimización de costos se centra en mantener y mejorar la rentabilidad de la carga de trabajo en la inversión. | Un sistema que implementa particiones suele beneficiarse del uso de varias instancias de recursos de proceso o almacenamiento menos costosos en lugar de un único recurso más caro. En muchos casos, esta configuración puede ahorrar dinero. - CO:07 Costos de componentes |
| Eficiencia del rendimiento ayuda a su carga de trabajo a satisfacer eficientemente las demandas mediante optimizaciones en el escalado, los datos y el código. | Al usar particionamiento en la estrategia de escalado, los datos y el procesamiento se aíslan en cada partición, por lo que las solicitudes solo compiten por los recursos dentro de su partición asignada. También puede usar el particionamiento para optimizar en función de la geografía. - PE:05 Escalado y particionamiento - PE:08 Rendimiento de datos |
Si este patrón introduce concesiones dentro de un pilar, considérelas en relación con los objetivos de los otros pilares.
Ejemplo
Considere un sitio web que expone una amplia colección de información sobre libros publicados en todo el mundo. El número de posibles libros catalogados en esta carga de trabajo y los patrones de consulta y uso típicos superan lo que puede controlar una base de datos relacional única. El arquitecto de cargas de trabajo decide particionar los datos en varias instancias de base de datos mediante el ISBN estático de los libros como clave de partición. En concreto, el arquitecto usa el dígito de comprobación (0 - 10) del ISBN, que proporciona 11 particiones lógicas posibles con distribución de datos equilibrada.
Para empezar, el arquitecto coloca las 11 particiones lógicas en tres bases de datos de particiones físicas. En este enfoque de partición virtual, muchas particiones lógicas se asignan a menos nodos físicos. El arquitecto usa el enfoque de particionamiento de consulta y almacena la asignación de clave a servidor en una base de datos de mapa de fragmentos.
Azure App Service está etiquetado como un sitio web de catálogo de libros. Se conecta a varias instancias de SQL Database y a una instancia de Azure AI Search. Una de las bases de datos se etiqueta como la base de datos ShardMap. Incluye una tabla de ejemplo que refleja una parte de la tabla de correspondencia, que se muestra más adelante en este artículo. La tabla incluye tres instancias de bases de datos de particiones: bookdbshard0, bookdbshard1 y bookdbshard2. Las otras bases de datos incluyen listas de ejemplo idénticas de tablas en ellas. Las tablas incluyen Libros, Catálogo de la Biblioteca del Congreso y un indicador de más tablas. AI Search se utiliza para la navegación por facetas y la búsqueda en el sitio. La identidad administrada está asociada a App Service.
Mapa de particiones de búsqueda
La base de datos de mapa de particiones contiene la siguiente tabla y datos de asignación de particiones.
SELECT ShardKey, DatabaseServer
FROM BookDataShardMap
| ShardKey | DatabaseServer |
|----------|----------------|
| 0 | bookdbshard0 |
| 1 | bookdbshard0 |
| 2 | bookdbshard0 |
| 3 | bookdbshard1 |
| 4 | bookdbshard1 |
| 5 | bookdbshard1 |
| 6 | bookdbshard2 |
| 7 | bookdbshard2 |
| 8 | bookdbshard2 |
| 9 | bookdbshard0 |
| 10 | bookdbshard1 |
Código de sitio web de ejemplo: acceso a un único fragmento
El sitio web no conoce cuántas bases de datos de particiones físicas existen (tres en este caso) o la lógica que asigna una clave de partición a una instancia de base de datos. Sólo sabe que el dígito de verificación del ISBN de un libro es la clave de partición. El sitio web tiene acceso de solo lectura a la base de datos del mapa de particiones y acceso de lectura y escritura a todas las bases de datos de particiones. En este ejemplo, el sitio web usa la identidad administrada del sistema del host de Azure App Service para la autorización, evitando que los secretos se incluyan en las cadenas de conexión.
El sitio web se configura con las siguientes cadenas de conexión en un appsettings.json archivo, como se muestra en este ejemplo, o a través de la configuración de la aplicación de App Service.
{
...
"ConnectionStrings": {
"ShardMapDb": "Data Source=tcp:<database-server-name>.database.windows.net,1433;Initial Catalog=ShardMap;Authentication=Active Directory Default;App=Book Site v1.5a",
"BookDbFragment": "Data Source=tcp:SHARD.database.windows.net,1433;Initial Catalog=Books;Authentication=Active Directory Default;App=Book Site v1.5a"
},
...
}
El código siguiente muestra cómo el sitio web ejecuta una consulta de actualización en el grupo de particiones de la base de datos de la carga de trabajo.
...
// All data for this book is stored in a shard based on the book's ISBN check digit,
// which is converted to an integer 0 - 10 (special value 'X' becomes 10).
int isbnCheckDigit = book.Isbn.CheckDigitAsInt;
// Establish a pooled connection to the database shard for this specific book.
using (SqlConnection sqlConn = await shardedDatabaseConnections.OpenShardConnectionForKeyAsync(key: isbnCheckDigit, cancellationToken))
{
// Update the book's Library of Congress catalog information.
SqlCommand cmd = sqlConn.CreateCommand();
cmd.CommandText = @"UPDATE LibraryOfCongressCatalog
SET ControlNumber = @lccn,
...
Classification = @lcc
WHERE BookID = @bookId";
cmd.Parameters.AddWithValue("@lccn", book.LibraryOfCongress.Lccn);
...
cmd.Parameters.AddWithValue("@lcc", book.LibraryOfCongress.Lcc);
cmd.Parameters.AddWithValue("@bookId", book.Id);
await cmd.ExecuteNonQueryAsync(cancellationToken);
}
...
En el código de ejemplo anterior, si book.Isbn era 978-8-1130-1024-6, isbnCheckDigit debe ser 6. Normalmente, la OpenShardConnectionForKeyAsync(6) llamada se implementa mediante un enfoque cache-aside. Si la información de particiones almacenada en caché para la clave de partición 6 no está disponible, el método consulta la base de datos de mapa de particiones identificada por la ShardMapDb cadena de conexión. El método recupera el valor bookdbshard2 de la memoria caché de la aplicación o de la base de datos de particiones y lo sustituye por SHARD en la BookDbFragment cadena de conexión. A continuación, el método establece o restablece una conexión agrupada a bookdbshard2.database.windows.net, la abre y la devuelve al código de llamada. A continuación, el código actualiza el registro existente en esa instancia de base de datos.
Código de sitio web de ejemplo: acceso a varias particiones
En el caso poco frecuente cuando el sitio web requiere una consulta directa entre particiones, la aplicación realiza una consulta de distribución ramificada paralela en todas las particiones.
...
// Retrieve all shard keys.
var shardKeys = shardedDatabaseConnections.GetAllShardKeys();
// Run the query in a fan-out style against each shard in the shard list.
Parallel.ForEachAsync(shardKeys, async (shardKey, cancellationToken) =>
{
using (SqlConnection sqlConn = await shardedDatabaseConnections.OpenShardConnectionForKeyAsync(key: shardKey, cancellationToken))
{
SqlCommand cmd = sqlConn.CreateCommand();
cmd.CommandText = @"SELECT ...
FROM ...
WHERE ...";
SqlDataReader reader = await cmd.ExecuteReaderAsync(cancellationToken);
while (await reader.ReadAsync(cancellationToken))
{
// Collect the results into a thread-safe data structure.
}
reader.Close();
}
});
...
Como alternativa a las consultas entre particiones, esta carga de trabajo puede usar un índice mantenido externamente en Azure AI Search para la búsqueda de sitios o la navegación por facetas.
Agregar instancias de fragmento
El equipo de cargas de trabajo sabe que si el catálogo de datos o su uso simultáneo crece significativamente, es posible que requieran más de tres instancias de base de datos. El equipo de cargas de trabajo no espera agregar servidores de bases de datos dinámicamente y aceptan tiempo de inactividad de la carga de trabajo cuando una nueva partición está en línea. Para poner en línea una nueva instancia de partición, deben mover datos de particiones existentes a la nueva partición y actualizar la tabla de asignación de particiones. Con este enfoque bastante estático, la carga de trabajo puede almacenar en caché con confianza la asignación de la base de datos de clave de partición en el código del sitio web.
La lógica de clave de fragmento de este ejemplo tiene un límite superior de 11 fragmentos físicos. Si el equipo de carga de trabajo determina a través de la estimación de carga que finalmente requieren más de 11 instancias de base de datos, deben realizar un cambio invasivo en la lógica de clave de partición. Este cambio implica una planeación cuidadosa de las modificaciones de código y la migración de datos a la nueva lógica de clave.
Funcionalidad de SDK
En lugar de escribir código personalizado para la administración de particiones y el enrutamiento de consultas a instancias de SQL Database, evalúe la biblioteca cliente de bases de datos elásticas. Esta biblioteca admite la administración de mapas de particiones, el enrutamiento de consultas dependientes de datos y las consultas entre particiones en C# y Java.
Paso siguiente
- Niveles de coherencia en Azure Cosmos DB: la distribución de datos entre particiones presenta desventajas de coherencia. En este artículo se describe el espectro de modelos de coherencia, de fuerte a eventual, y sus efectos sobre la disponibilidad y la latencia.
Recursos relacionados
- Creación de particiones de datos horizontales, verticales y funcionales: en este artículo se describen otras estrategias para crear particiones de datos en la nube para mejorar la escalabilidad, reducir la contención y optimizar el rendimiento.
- Patrón de tabla de índice: a veces no se pueden admitir todas las consultas a través del diseño de la clave de partición solo. Una aplicación puede usar el patrón Index Table para recuperar datos de un almacén de datos grande especificando una clave distinta de la clave de partición.
- Patrón de vista materializada: para mantener el rendimiento de algunas operaciones de consulta, puede crear vistas materializadas que agregan y resumen datos, especialmente si distribuye esos datos entre particiones.