API de Memcache para servicios agrupados en paquetes heredados

Esta página proporciona una descripción general del servicio Memcache de App Engine. Las aplicaciones web escalables de alto rendimiento con frecuencia usan caché de datos en memoria distribuido frente a o en lugar de un almacenamiento continuo robusto para algunas tareas. App Engine incluye un servicio de memoria caché para este fin. Para conocer cómo configurar, supervisar y usar el servicio Memcache, lee Usar Memcache.

Cuándo usar una memoria caché

Uno de los usos de una memoria caché es acelerar las consultas comunes sobre el almacén de datos. Si muchas solicitudes hacen la misma consulta con los mismos parámetros y los cambios en los resultados no necesitan aparecer en el sitio web de inmediato, la aplicación puede almacenar los resultados en Memcache. Las solicitudes posteriores pueden verificar Memcache y solo consultar el almacén de datos si los resultados no existen o han vencido. Los datos de sesión, las preferencias de usuario y otros datos mostrados por las consultas para páginas web son buenos candidatos para almacenar en caché.

Memcache puede ser útil para otros valores temporales. Sin embargo, a la hora de considerar si almacenar un valor únicamente en Memcache sin el respaldo de otro almacenamiento continuo, asegúrate de que tu aplicación se comporte de manera aceptable cuando el valor no esté disponible repentinamente. Los valores pueden vencer en Memcache en cualquier momento y pueden hacerlo antes de la fecha de vencimiento configurada para el valor. Por ejemplo, si la ausencia repentina de los datos de sesión de un usuario provocan el fallo de la sesión, esos datos probablemente deberían almacenarse en el almacén de datos además de en Memcache.

Niveles de servicio

App Engine admite dos niveles de servicio de Memcache:

  • Memcache compartida es la configuración predeterminada gratuita para las aplicaciones de App Engine. Brinda capacidad de caché sobre la base del "mejor esfuerzo" y está sujeta a la demanda general de todas las aplicaciones de App Engine que usan el servicio de Memcache compartida.

  • Memcache exclusiva proporciona una capacidad de caché fija asignada exclusivamente a tu aplicación. Se factura por GB-hora de tamaño de caché y requiere facturación para habilitarse. Disponer de control sobre el tamaño de la caché puede permitir un rendimiento más predecible de tu app y reducir la cantidad de lecturas desde un almacenamiento duradero más costoso.

Ambos niveles de servicio de Memcache usan la misma API. A fin de configurar el servicio de Memcache para tu aplicación, consulta Usa Memcache.

La tabla siguiente resume las diferencias entre las dos clases de servicio de Memcache

Función Memcache exclusiva Memcache compartida
Precio $0.06 por GB, por hora Gratis
Capacidad
us-central
De 1 a 100 GB
asia-northeast1, europe-west, europe-west3 y us-east1:
1 a 20 GB
otras regiones:
1 a 2 GB
Capacidad no garantizada
Rendimiento Hasta 10,000 lecturas o 5,000 escrituras (exclusivo) por segundo y por GB (elementos <1 KB). Para más detalles, consulta Estadísticas de caché. No garantizada
Almacenamiento duradero No No
SLA Ninguno Ninguno

La facturación de Memcache exclusiva se cobra en incrementos de 15 minutos. Si pagas en una moneda distinta del dólar estadounidense, se aplican los precios que aparecen en tu moneda en Cloud Platform SKUs.

Si tu aplicación necesita más capacidad de Memcache, comunícate con nuestro equipo de ventas.

Límites

Los siguientes límites se aplican al uso del servicio de Memcache:

  • El tamaño máximo de un dato de caché es de 1 MB (10^6 bytes).
  • Una clave no puede ser mayor a 250 bytes. En el entorno de ejecución de Python, las claves que son cadenas de más de 250 bytes generarán un hash. (Otros entornos de ejecución se comportan de manera diferente).
  • Las operaciones de lotes múltiples pueden tener cualquier cantidad de elementos. El tamaño total de la llamada y el tamaño total de los datos recuperados no deben exceder los 32 megabytes.
  • Una clave de Memcache no puede contener un byte nulo.

Recomendaciones y prácticas recomendadas

Cuando uses Memcache, te recomendamos diseñar tus aplicaciones para lo siguiente:

  • Controlar el caso en el que un valor almacenado en caché no siempre está disponible.

    • Memcache no es un almacenamiento duradero. Según la política de expulsión, las claves se expulsan cuando se llena la caché. Los cambios en los eventos de mantenimiento del centro de datos o la configuración de la caché también pueden limpiar toda la caché de manera parcial o total.
    • Es posible que Memcache experimente una falta de disponibilidad temporal. Las operaciones de Memcache pueden fallar por diversos motivos, incluidos los cambios en la configuración de la caché o los eventos de mantenimiento del centro de datos. Las aplicaciones deberían diseñarse para detectar operaciones fallidas sin exponer estos errores a los usuarios finales. Esta guía se aplica especialmente a las operaciones Set.
  • Usar la capacidad de lotes de la API cuando sea posible.

    • Hacerlo así aumenta el rendimiento y la eficiencia de tu aplicación, en especial para elementos pequeños.
  • Distribuye la carga en el espacio de claves de Memcache.

    • Tener un conjunto único o pequeño de elementos de Memcache representa una cantidad desproporcionada de tráfico que dificultará el escalamiento de tu aplicación. Esta guía se aplica tanto a las operaciones por segundo como al ancho de banda. A menudo, puedes solucionar este problema fragmentando de forma explícita tus datos.

      Por ejemplo, puedes dividir un contador frecuentemente actualizado entre diversas claves, y volver a leerlas y sumarlas solo cuando necesites un total. De igual manera, puedes dividir una porción de 500,000 datos que debe leerse en cada solicitud HTTP en varias claves y volver a leerlas con una única llamada a la API de lote. (Sería incluso mejor almacenar en caché el valor en la memoria de la instancia). Para la Memcache exclusiva, la tasa de acceso máxima en una clave única debería ser de 1 o 2 órdenes de magnitud menores a la clasificación por GB.

  • Retén tus propias claves para recuperar valores de la caché.

    • Memcache no proporciona un método para enumerar las claves. Debido a la naturaleza de la caché, no es posible enumerar claves sin interrumpir la caché. Además, algunos lenguajes, como Python, las claves largas de hash y las claves originales solo se conocen en la aplicación.

Cómo vencen los datos almacenados en caché

Memcache contiene pares de clave/valor. Los pares en memoria cambian en cualquier momento a medida que los elementos se escriben y recuperan de la caché.

De forma predeterminada, los valores almacenados en Memcache se retienen tanto como sea posible. Los valores pueden expulsarse de la caché cuando se agrega un nuevo valor a la caché y esta tiene poca memoria. Cuando los valores se expulsan debido a la presión en la memoria, los primeros valores que se expulsan son los menos usados recientemente.

Cuando se almacena un valor, la aplicación puede brindar una fecha de vencimiento que puede ser una cantidad de segundos relativa al momento en que se agrega el valor, o un tiempo Unix absoluto en el futuro (una cantidad de segundos transcurridos desde el 1 de enero de 1970). El valor se expulsa a más tardar en esa fecha, a pesar de que puede expulsarse anteriormente por otros motivos. Aumentar el valor almacenado para una clave existente no actualiza su fecha de vencimiento.

En circunstancias excepcionales, los valores también pueden desaparecer de la caché antes del vencimiento por motivos diferentes a la presión en la memoria. Si bien Memcache es resistente a las fallas del servidor, los valores de Memcache no se guardan en el disco, por lo que una falla en el servicio puede hacer que los valores no estén disponibles.

En general, una aplicación no debería esperar que un valor almacenado en caché esté siempre disponible.

Puedes borrar la caché completa de una aplicación a través de la API o en la sección de Memcache de la consola de Google Cloud.

Estadísticas de caché

Operaciones por segundo según el tamaño del elemento

Memcache exclusiva se clasifica en operaciones por segundo por GB, en las que una operación se define como un acceso individual al elemento de caché, como get, set o delete. La tasa de la operación varía según el tamaño del elemento, aproximadamente de acuerdo con la tabla siguiente. Superar estas tasas puede dar como resultado un aumento de la latencia de la API o errores.

En las siguientes tablas, se proporciona la cantidad máxima de operaciones get-hit o set sostenidas y exclusivas por GB de caché. Ten en cuenta que una operación get-hit es una llamada get que descubre que existe un valor almacenado con una clave determinada y muestra ese valor.

Tamaño del elemento (KB) Operaciones get-hit máximas Operaciones set máximas
≤1 10,000 5,000
100 2,000 1,000
512 500 250

Una aplicación configurada para varios GB de caché puede, en teoría, lograr una tasa de operación acumulada calculada como la cantidad de GB multiplicada por la tasa por GB. Por ejemplo, una app configurada para 5 GB de caché podría alcanzar 50,000 operaciones de Memcache por segundo en elementos de 1 KB. Lograr este nivel requiere una buena distribución de la carga en el espacio de claves de Memcache.

Para cada patrón de IO, los límites mencionados con anterioridad corresponden a lecturas o escrituras. Para lecturas y escrituras simultáneas, los límites están en escala variable. Cuantas más lecturas se ejecuten, menos escrituras se ejecutarán y viceversa. Cada uno de los siguientes son ejemplos de límites de IOPS para lecturas y escrituras simultáneas de valores de 1 KB por 1 GB de caché.

IOPS de lectura IOPS de escritura
10000 0
8,000 1000
5,000 2,500
1000 4,500
0 5,000

Unidades de procesamiento de Memcache (MCU)

La capacidad de procesamiento de Memcache puede variar según el tamaño del elemento al que estás accediendo y la operación que deseas realizar en el elemento. Puedes asociar aproximadamente un costo con operaciones y calcular la capacidad de tráfico que puedes esperar de la Memcache exclusiva mediante el uso de una unidad llamada Unidad de procesamiento de Memcache (MCU). La MCU se define de tal manera que puedes esperar 10,000 MCU por segundo por GB de Memcache exclusiva. La consola de Google Cloud muestra la cantidad de MCU que está usando la app en este momento.

Ten en cuenta que la MCU es un cálculo estadístico aproximado y que, además, no es una unidad lineal. Cada operación de caché que lee o escribe un valor tiene un costo de MCU correspondiente que depende del tamaño del valor. La MCU para un set depende del tamaño del valor: es 2 veces el costo de una operación get-hit exitosa.

Tamaño del elemento de valor (KB) Costo de la MCU para get-hit Costo de la MCU para set
≤1 1.0 2.0
2 1.3 2.6
10 1.7 3.4
100 5.0 10.0
512 20.0 40.0
1,024 50.0 100.0

Las operaciones que no leen o escriben un valor tienen un costo de MCU fijo:

Operación MCU
get-miss 1.0
delete 2.0
increment 2.0
flush 100.0
stats 100.0

Ten en cuenta que una operación get-miss es un get que descubre que no hay ningún valor almacenado con la clave especificada.

Función comparar y establecer

La función de comparar y establecer permite que las solicitudes múltiples que se manejan en simultáneo actualicen el valor de la misma clave de Memcache de manera atómica para evitar condiciones de carrera.

Componentes lógicos principales de la función comparar y establecer

Si deseas actualizar el valor de una clave de Memcache que podría recibir otras solicitudes de escritura simultáneas, debes usar el objeto de Memcache Client, que almacena determinada información sobre el estado, que usan los métodos que admiten comparar y establecer. No puedes usar las funciones de Memcache get() o set(), porque no tienen estado. La clase Client en sí misma no cuenta con seguridad en los subprocesos, por lo que no debes utilizar el mismo objeto Client en más de un subproceso.

Cuando recuperas las claves, debes usar los métodos Client de Memcache compatibles con la función comparar y establecer: gets() o get_multi() con el parámetro for_cas establecido en True.

Cuando actualizas una clave, debes usar los métodos Client de Memcache compatibles con la función comparar y establecer: cas() o cas_multi().

Otro componente lógico principal es el servicio de Memcache de App Engine y su comportamiento respecto a la función comparar y establecer. El servicio de Memcache de App Engine se comporta en sí mismo de forma atómica. Esto significa que, cuando dos solicitudes simultáneas (para el mismo ID de aplicación) utilicen Memcache, estas se dirigirán hacia la misma instancia del servicio de Memcache. Este servicio tendrá el suficiente bloqueo interno como para que las solicitudes simultáneas de una misma clave se serialicen de forma apropiada. En particular, esto significa que dos solicitudes cas() para la misma clave no se ejecutan en paralelo: el servicio administra la primera solicitud que llegó hasta que se completa (es decir, hasta que se actualiza el valor y la marca de tiempo) y luego administra la segunda.

Para aprender a utilizar la función comparar y establecer en Python, consulta Cómo manejar escrituras simultáneas.

¿Qué sigue?