Caché integrada de Azure Cosmos DB: información general

SE APLICA A: NoSQL

La caché integrada de Azure Cosmos DB es una caché en memoria que le ayuda a garantizar costos administrables y baja latencia a medida que crece el volumen de solicitudes. La memoria caché integrada es fácil de configurar y no es necesario dedicar tiempo a escribir código personalizado para la invalidación de caché ni administrar la infraestructura de back-end. La memoria caché integrada usa la puerta de enlace dedicada dentro de la cuenta de Azure Cosmos DB. Al aprovisionar la puerta de enlace dedicada, puede elegir el número de nodos y el tamaño del nodo en función del número de núcleos y memoria necesarios para la carga de trabajo. Cada nodo de puerta de enlace dedicada tiene una caché integrada e independiente del resto.

Una caché integrada se configura automáticamente dentro de la puerta de enlace dedicada. La memoria caché integrada tiene dos partes:

  • Una caché de elementos para lecturas puntuales
  • Una caché de consulta para consultas

La caché integrada es una caché de lectura y escritura a través con una directiva de expulsión de menos usados recientemente (LRU). La caché de elementos y las caché de consulta comparten la misma capacidad dentro de la caché integrada y la directiva de expulsión de LRU se aplica a ambas. En otras palabras, los datos se expulsan de la caché estrictamente en función de cuándo se usaron por última vez, independientemente de si se trata de una consulta o una lectura puntuales. Los datos en caché dentro de cada nodo dependen de los datos que se han escrito o leído recientemente a través de ese nodo específico. Si un elemento o una consulta se almacenan en caché en un nodo, no necesariamente se almacenan en caché en los demás.

Nota:

¿Tiene comentarios sobre la caché integrada? Queremos conocerlos. No dude en compartir sus comentarios directamente con el equipo de ingeniería de Azure Cosmos DB: cosmoscachefeedback@microsoft.com.

Cargas de trabajo que se benefician de la memoria caché integrada

El objetivo principal de la caché integrada es reducir los costos de las cargas de trabajo con mucha actividad de lectura. La baja latencia, aunque útil, no es la principal ventaja de la caché integrada porque Azure Cosmos DB ya es rápido sin almacenamiento en caché.

Las lecturas y consultas puntuales que alcancen la caché integrada tienen un cargo de RU de 0. Los aciertos de caché tendrán un costo por operación mucho menor que las lecturas de la base de datos back-end.

Las cargas de trabajo que se ajusten a las siguientes características deben evaluar si la memoria caché integrada ayuda a reducir los costos:

  • Cargas de trabajo con mucha actividad de lectura
  • Muchas lecturas puntuales repetidas en elementos grandes
  • Muchas consultas de RU elevadas repetidas
  • Clave de partición activa para lecturas

El factor más importante en el ahorro esperado es el grado en que las lecturas se repiten. Si la carga de trabajo ejecuta de forma coherente las mismas lecturas o consultas puntuales en un breve período de tiempo, es una excelente candidata para la caché integrada. Cuando se usa la caché integrada en las lecturas repetidas, solo se usan RU para la primera lectura. Las lecturas posteriores enrutadas a través del mismo nodo de puerta de enlace dedicada (dentro de la ventana MaxIntegratedCacheStaleness y si no se han expulsado los datos) no usarán el rendimiento.

Algunas cargas de trabajo no deben tener en cuenta la caché integrada, entre las que se incluyen:

  • Cargas de trabajo con mucha actividad de escritura
  • Consultas o lecturas puntuales que rara vez se repiten
  • Cargas de trabajo que leen la fuente de cambios

Caché de elementos

La caché de elementos se usa para las lecturas puntuales (búsquedas de clave y valor basadas en el identificador de elemento y la clave de partición).

Rellenado de la caché de elementos

  • Las nuevas escrituras, actualizaciones y eliminaciones se rellenan automáticamente en la memoria caché de elementos del nodo a través del que se enruta la solicitud
  • Elementos de solicitudes de lectura puntuales en las que el elemento aún no está en la memoria caché (error de caché) del nodo a través del que se enruta la solicitud se agregan a la memoria caché de elementos
  • Las solicitudes que forman parte de un lote transaccional o en modo masivo no rellenan la memoria caché de elementos

Invalidación y expulsión de la caché de elementos

Dado que cada nodo tiene una memoria caché independiente, es posible que los elementos se invaliden o se expulsen en la memoria caché de un nodo y no en los demás. Los elementos de la memoria caché de un nodo determinado se invalidan y expulsan según los criterios siguientes:

  • Actualización o eliminación del elemento
  • Menos usados recientemente (LRU)
  • Tiempo de retención en caché (es decir, MaxIntegratedCacheStaleness)

Caché de consultas

La caché de consulta se usa para almacenar en caché las consultas. La caché de consulta transforma una consulta en una búsqueda clave-valor donde la clave es el texto de la consulta y el valor son los resultados de la consulta. La memoria caché integrada no tiene un motor de consultas, solo almacena la búsqueda de clave-valor para cada consulta. Los resultados de la consulta se almacenan como un conjunto y la memoria caché no realiza un seguimiento de los elementos individuales. Un elemento determinado se puede almacenar en la caché de consultas varias veces si aparece en el conjunto de resultados de varias consultas. Las actualizaciones a los elementos subyacentes no se reflejarán en los resultados de la consulta a menos que se alcance la obsolescencia máxima de caché integrada para la consulta y la consulta se sirva desde la base de datos back-end.

Rellenado de la caché de consulta

  • Si la caché no tiene un resultado para esa consulta (error de caché) en el nodo a través del cual se enrutó, la consulta se envía al back-end. Una vez ejecutada la consulta, la caché almacenará sus resultados.
  • Las consultas con la misma forma, pero diferentes parámetros u opciones de solicitud que afectan a los resultados (por ejemplo, recuento máximo de elementos) se almacenarán como su propio par clave-valor.

Expulsión de la caché de consulta

La expulsión de la caché de consultas se basa en el nodo al que se enruta la solicitud. Es posible que las consultas se expulsen o actualicen en un nodo y no en los demás.

  • Menos usados recientemente (LRU)
  • Tiempo de retención en caché (es decir, MaxIntegratedCacheStaleness)

Uso de la caché de consulta

No necesita código especial al trabajar con la caché de consulta, incluso si las consultas tienen varias páginas de resultados. Los procedimientos recomendados y el código para la paginación de consultas son los mismos, tanto si la consulta alcanza la caché integrada como si se ejecuta en el motor de consulta back-end.

La caché de consulta almacenará en caché automáticamente los tokens de continuación de consultas, si procede. Si tiene una consulta con varias páginas de resultados, las páginas almacenadas en la caché integrada tendrán un cargo de RU de 0. Si las páginas posteriores de los resultados de la consulta requieren la ejecución de back-end, tendrán un token de continuación de la página anterior para que puedan evitar duplicar el trabajo anterior.

Importante

Las instancias de caché integradas dentro de distintos nodos de puerta de enlace dedicados tienen cachés independientes entre sí. Si los datos se almacenan en caché dentro de un nodo, no necesariamente se almacenan en caché en los demás. No se garantiza que varias páginas de la misma consulta se enruten al mismo nodo de puerta de enlace dedicado.

Coherencia de la caché integrada

La caché integrada solo admite solicitudes de lectura con coherencia final y de sesión. Si una lectura tiene un prefijo coherente, obsolescencia limitada o coherencia alta, omite la caché integrada y se sirve desde el back-end.

La manera más fácil de configurar la coherencia posible o de sesión para todas las lecturas consiste en establecerla en el nivel de cuenta. Sin embargo, si solo desea que algunas de las lecturas tengan coherencia específica, también puede configurar la coherencia en el nivel de solicitud.

Nota

Las solicitudes de escritura con otras coherencias siguen rellenando la caché, pero para leerla, la solicitud debe tener coherencia eventual o de sesión.

Coherencia de sesión

La coherencia de sesión es el nivel de coherencia más usado tanto para regiones únicas, como para cuentas de Azure Cosmos DB distribuidas globalmente. Con la coherencia de sesión, las sesiones de cliente único pueden leer sus propias escrituras. Las lecturas con coherencia de sesión que no tengan un token de sesión coincidente incurrirán en cargos por RU. Esto incluye la primera solicitud de un elemento o consulta determinado cuando se inicia o reinicia la aplicación cliente, a menos que pase explícitamente un token de sesión válido. Los clientes que están fuera de la sesión que realiza escrituras verán la coherencia eventual cuando utilicen la caché integrada.

MaxIntegratedCacheStaleness

MaxIntegratedCacheStaleness es la mayor obsolescencia aceptable para las lecturas y consultas de punto en caché, independientemente de la coherencia seleccionada. MaxIntegratedCacheStaleness se puede configurar en el nivel de solicitud. Por ejemplo, si establece un MaxIntegratedCacheStaleness de 2 horas, la solicitud solo devolverá datos en caché si los datos tienen menos de 2 horas de antigüedad. Para aumentar la probabilidad de que las lecturas repetidas utilicen la caché integrada, debe establecer el MaxIntegratedCacheStaleness a la altura máxima que permitan los requisitos empresariales.

Cuando se configura MaxIntegratedCacheStaleness en una solicitud que acaba rellenando la caché, no afecta al tiempo que esa solicitud se almacena en caché. MaxIntegratedCacheStaleness aplica coherencia al intentar leer datos en caché. No hay ningún valor de retención de caché o TTL global, por lo que los datos solo se expulsarán de la caché si la caché integrada está llena o se ejecuta una nueva lectura con un valor de MaxIntegratedCacheStaleness inferior a la antigüedad de la entrada almacenada en caché actual.

Se trata de una mejora con respecto al funcionamiento de la mayoría de las memorias caché y permite las siguientes personalizaciones adicionales:

  • Puede establecer distintos requisitos de estancamiento para cada lectura o consulta puntuales.
  • Diferentes clientes, incluso si ejecutan la misma lectura o consulta puntual, pueden configurar diferentes valores MaxIntegratedCacheStaleness.
  • Si quisiera modificar la coherencia de lectura de los datos en caché, el cambio de MaxIntegratedCacheStaleness tendría un efecto inmediato sobre ella

Nota

El valor MaxIntegratedCacheStaleness mínimo es 0, mientras que el valor máximo es de 10 años. Cuando no se configura explícitamente, el valor de MaxIntegratedCacheStaleness predeterminado es de 5 minutos.

Para conocer mejor el parámetro MaxIntegratedCacheStaleness, considere el ejemplo siguiente:

Time Solicitud Response
t = 0 s Ejecutar Consulta A con MaxIntegratedCacheStaleness = 30 segundos Devolver resultados de una base de datos de back-end (cargos de RU normales) y llenar la caché
t = 0 s Ejecutar Consulta B con MaxIntegratedCacheStaleness = 60 segundos Devolver resultados de una base de datos de back-end (cargos de RU normales) y llenar la caché
t = 20 s Ejecutar Consulta A con MaxIntegratedCacheStaleness = 30 segundos Devolver resultados de la caché integrada (cargo de 0 RU)
t = 20 s Ejecutar Consulta B con MaxIntegratedCacheStaleness = 60 segundos Devolver resultados de la caché integrada (cargo de 0 RU)
t = 40 s Ejecutar Consulta A con MaxIntegratedCacheStaleness = 30 segundos Devolver resultados de una base de datos de back-end (cargos de RU normales) y actualizar la caché
t = 40 s Ejecutar Consulta B con MaxIntegratedCacheStaleness = 60 segundos Devolver resultados de la caché integrada (cargo de 0 RU)
t = 50 s Ejecutar Consulta B con MaxIntegratedCacheStaleness = 20 segundos Devolver resultados de una base de datos de back-end (cargos de RU normales) y actualizar la caché

Aprenda a configurar MaxIntegratedCacheStaleness.

Omitir la caché integrada (versión preliminar)

La caché integrada tiene una capacidad de almacenamiento limitada determinada por la SKU de puerta de enlace dedicada aprovisionada. De forma predeterminada, todas las solicitudes de los clientes configurados con la cadena de conexión de puerta de enlace dedicada pasan por la caché integrada y ocupan espacio en caché. Puede controlar qué elementos y consultas se almacenan en caché con la opción de omitir solicitud de caché integrada, actualmente en versión preliminar. Esta opción de solicitud es útil para las solicitudes de escritura o lectura de elementos que no se espera que se repitan con frecuencia. Si se omite la caché integrada para los elementos con acceso poco frecuente, se ahorra espacio en la memoria caché para los elementos con más repeticiones, lo que aumenta el potencial de ahorro de RU y reduce las expulsiones. Las solicitudes que omiten la memoria caché siguen enrutadas a través de la puerta de enlace dedicada. Estas solicitudes se sirven desde el back-end y las RU de costo.

Aprenda a omitir la memoria caché integrada.

Métricas

Al usar la caché integrada, resulta útil supervisar algunas métricas clave. Estas métricas incluyen:

  • DedicatedGatewayCPUUsage: uso de CPU con los tipos de agregación Avg, Max o Min en los datos de todos los nodos de puerta de enlace dedicada.
  • DedicatedGatewayAverageCPUUsage: (en desuso) uso medio de CPU en todos los nodos de puerta de enlace dedicados.
  • DedicatedGatewayMaximumCPUUsage: (en desuso) uso máximo de CPU en todos los nodos de puerta de enlace dedicada.
  • DedicatedGatewayMemoryUsage: uso de memoria con los tipos de agregación Avg, Max o Min en los datos de todos los nodos de puerta de enlace dedicada.
  • DedicatedGatewayAverageMemoryUsage: (en desuso) uso medio de memoria en todos los nodos de puerta de enlace dedicada.
  • DedicatedGatewayRequests: número total de solicitudes de puerta de enlace dedicada en todos los nodos de puerta de enlace dedicada.
  • IntegratedCacheEvictedEntriesSize: cantidad media de datos expulsados de la caché integrada debido a la LRU en los nodos de puerta de enlace dedicada. Este valor no incluye los datos que hayan expirado debido a que se superó el tiempo de MaxIntegratedCacheStaleness.
  • IntegratedCacheItemExpirationCount: número de elementos que se expulsan de la caché integrada debido a que las lecturas puntuales almacenadas en caché superan el tiempo MaxIntegratedCacheStaleness en todos los nodos de puerta de enlace dedicada.
  • IntegratedCacheQueryExpirationCount: número de consultas que se expulsan de la caché integrada debido a que las consultas almacenadas en caché superan el tiempo MaxIntegratedCacheStaleness en todos los nodos de puerta de enlace dedicada.
  • IntegratedCacheItemHitRate: la proporción de lecturas puntuales que usaban la caché (de todas las lecturas puntuales enrutadas a través de la puerta de enlace dedicada con coherencia final o de sesión). Este valor es un promedio de las instancias de caché integradas en todos los nodos de puerta de enlace dedicada.
  • IntegratedCacheQueryHitRate: la proporción de consultas que usaban la caché (de todas las consultas enrutadas a través de la puerta de enlace dedicada con coherencia final o de sesión). Este valor es un promedio de las instancias de caché integradas en todos los nodos de puerta de enlace dedicada.

Todas las métricas existentes están disponibles, de manera predeterminada, en Métricas en Azure Portal (no en la hoja de métricas clásica):

Screenshot of the Azure portal that shows the location of integrated cache metrics.

Las métricas son un promedio, el máximo o la suma en todos los nodos de puerta de enlace dedicada. Por ejemplo, si aprovisiona un clúster de puerta de enlace dedicada con cinco nodos, las métricas reflejan el valor agregado en los cinco nodos. No es posible determinar los valores de métrica de cada nodo individual.

Solucionar los problemas comunes

En los ejemplos siguientes, se muestra cómo depurar algunos escenarios comunes:

No sé si mi aplicación usa la puerta de enlace dedicada

Active DedicatedGatewayRequests. Esta métrica incluye todas las solicitudes que usan la puerta de enlace dedicada, independientemente de si han alcanzado la caché integrada. Si la aplicación usa la puerta de enlace estándar o el modo directo con la cadena de conexión original, no verá un mensaje de error, pero el valor de DedicatedGatewayRequests será cero. Si la aplicación usa el modo directo con la cadena de conexión de puerta de enlace dedicada, es posible que vea un pequeño número de DedicatedGatewayRequests.

No sé si mis solicitudes alcanzan la memoria caché integrada

Compruebe IntegratedCacheItemHitRate y IntegratedCacheQueryHitRate. Si ambos valores son cero, significa que las solicitudes no están llegando a la caché integrada. Compruebe que usa la cadena de conexión de la puerta de enlace dedicada, que se conecta con el modo de puerta de enlace y que usa la coherencia de sesión o final.

Quiero saber si mi puerta de enlace dedicada es demasiado pequeña

Compruebe IntegratedCacheItemHitRate y IntegratedCacheQueryHitRate. Si estos valores son altos (por ejemplo, por encima de 0,7-0,8), es una buena señal de que la puerta de enlace dedicada es suficientemente grande.

Si IntegratedCacheItemHitRate o IntegratedCacheEvictedEntriesSize son bajos, observe IntegratedCacheQueryHitRate. Si IntegratedCacheEvictedEntriesSize es alto, puede significar que un mayor tamaño de puerta de enlace dedicada sería beneficioso. Puede experimentar aumentando el tamaño de la puerta de enlace dedicada y comparando los nuevos IntegratedCacheItemHitRate y IntegratedCacheQueryHitRate. Si una puerta de enlace dedicada mayor no mejora IntegratedCacheItemHitRate o IntegratedCacheQueryHitRate, es posible que las lecturas simplemente no se repitan lo suficiente como para que la caché integrada resulte afectada.

Quiero saber si mi puerta de enlace dedicada es demasiado grande

Es más difícil medir si una puerta de enlace dedicada es demasiado grande que medir si es demasiado pequeña. En general, debe empezar por valores pequeños y aumentar lentamente el tamaño de la puerta de enlace dedicada hasta que IntegratedCacheItemHitRate y IntegratedCacheQueryHitRate dejen de mejorar. En algunos casos, solo una de las dos métricas de aciertos de caché serán importantes, no ambas. Por ejemplo, si la carga de trabajo es principalmente consultas, en lugar de lecturas puntuales, IntegratedCacheQueryHitRate es mucho más importante que IntegratedCacheItemHitRate.

Si la mayoría de los datos se expulsa de la memoria caché debido a que se supera MaxIntegratedCacheStaleness, en lugar de LRU, la memoria caché podría ser mayor de lo necesario. Si la combinación de IntegratedCacheItemExpirationCount y IntegratedCacheQueryExpirationCount es casi tan grande como IntegratedCacheEvictedEntriesSize, puede experimentar con un tamaño de puerta de enlace dedicada menor y comparar el rendimiento.

Quiero saber si necesito agregar más nodos de puerta de enlace dedicada

En algunos casos, si la latencia es inesperadamente alta, puede que necesite más nodos de puerta de enlace dedicada, en lugar de nodos mayores. Consulte que DedicatedGatewayCPUUsage y DedicatedGatewayMemoryUsage para determinar si agregar más nodos de puerta de enlace dedicada reduciría la latencia. Es bueno tener en cuenta que, dado que todas las instancias de la caché integrada son independientes entre sí, la incorporación de más nodos de puerta de enlace dedicada no reducirá IntegratedCacheEvictedEntriesSize. Sin embargo, la incorporación de más nodos mejorará el volumen de solicitudes que puede controlar el clúster de puerta de enlace dedicado.

Pasos siguientes