una sirve react qué patterns para ejemplo diseño consume api rest caching memcached varnish

sirve - La mejor manera de almacenar en caché los resultados de la API REST de las llamadas GET



qué es una api rest y para qué sirve (5)

Dado que REST es una cuestión de HTTP, podría ser que la mejor manera de almacenar las solicitudes en caché sea usar el almacenamiento en caché de HTTP.

Considere el uso de ETags en sus respuestas, verifique el ETag en las solicitudes para responder con ''304 Not Modified'' y tenga Rack :: Cache para servir datos almacenados en caché si los ETags son iguales. Esto funciona muy bien para el contenido ''público'' de control de caché.

Rack :: Cache está mejor configurado para usar memcache para sus necesidades de almacenamiento.

La semana pasada escribí una publicación en el blog sobre la forma interesante en que Rack :: Cache usa ETags para detectar y devolver contenido en caché a nuevos clientes: http://blog.craz8.com/articles/2012/12/19/rack-cache-and-etags-for-even-faster-rails

Incluso si no está utilizando Rails, las herramientas de middleware de Rack son bastante buenas para esto.

Estoy pensando en la mejor manera de crear una capa de caché delante o como primera capa para las solicitudes GET a mi API RESTful (escrita en Ruby).

No todas las solicitudes se pueden almacenar en caché, ya que incluso para algunas solicitudes GET, la API tiene que validar el usuario / aplicación solicitante. Eso significa que necesito configurar qué solicitud es almacenable en caché y por cuánto tiempo es válida cada respuesta almacenada en caché. Para algunos casos necesito un tiempo de caducidad muy corto, por ejemplo, de 15 años o menos. Y debería poder dejar que las entradas de la memoria caché caduquen por la aplicación de la API incluso si aún no se ha alcanzado la fecha de caducidad.

Ya pensé en muchas soluciones posibles, mis dos mejores ideas:

  • primera capa de la API (incluso antes del enrutamiento), guardar la lógica de caché (para tener todas las opciones de configuración en mi mano), las respuestas y la fecha de caducidad almacenadas en Memcached

  • un proxy de servidor web (alto configurable), tal vez algo como Squid pero nunca he usado un proxy para un caso como este antes y no estoy del todo seguro

También pensé en una solución de caché como Varnish, utilicé Varnish para aplicaciones web "habituales" y es impresionante, pero la configuración es algo especial. Pero lo usaría si es la solución más rápida.

Otro pensamiento fue almacenar en caché el Índice Solr, que ya estoy usando en la capa de datos para no consultar la base de datos para la mayoría de las solicitudes.

Si alguien tiene una pista o buenas fuentes para leer sobre este tema, hágamelo saber.


En primer lugar, cree su API RESTful para que sea RESTful. Eso significa que los usuarios autenticados también pueden obtener contenido en caché para mantener todo el estado en la URL que necesita para contener los detalles de autenticación. Por supuesto, la tasa de aciertos será más baja aquí, pero se puede almacenar en caché.

Con una gran cantidad de usuarios registrados, será muy beneficioso tener algún tipo de caché de modelo detrás de un caché de página completa, ya que muchos modelos aún se comparten, incluso si algunos no lo están (en una buena estructura de POO).

Luego, para un caché de página completa, lo mejor es mantener todas las solicitudes fuera del servidor web y, especialmente, lejos del procesamiento dinámico en el siguiente paso (en su caso, Ruby). La forma más rápida de almacenar en caché páginas completas desde un servidor web normal es siempre un proxy de almacenamiento en caché frente a los servidores web.

El barniz es, en mi opinión, tan bueno y fácil como es posible, pero algunos prefieren el calamar.


He utilizado redis con éxito de esta manera en mi vista REST:

from django.conf import settings import hashlib import json from redis import StrictRedis from django.utils.encoding import force_bytes def get_redis(): #get redis connection from RQ config in settings rc = settings.RQ_QUEUES[''default''] cache = StrictRedis(host=rc[''HOST''], port=rc[''PORT''], db=rc[''DB'']) return cache class EventList(ListAPIView): queryset = Event.objects.all() serializer_class = EventSerializer renderer_classes = (JSONRenderer, ) def get(self, request, format=None): if IsAdminUser not in self.permission_classes: # dont cache requests from admins # make a key that represents the request results you want to cache # your requirements may vary key = get_key_from_request() # I find it useful to hash the key, when query parms are added # I also preface event cache key with a string, so I can clear the cache # when events are changed key = "todaysevents" + hashlib.md5(force_bytes(key)).hexdigest() # I dont want any cache issues (such as not being able to connect to redis) # to affect my end users, so I protect this section try: cache = get_redis() data = cache.get(key) if not data: # not cached, so perform standard REST functions for this view queryset = self.filter_queryset(self.get_queryset()) serializer = self.get_serializer(queryset, many=True) data = serializer.data # cache the data as a string cache.set(key, json.dumps(data)) # manage the expiration of the cache expire = 60 * 60 * 2 cache.expire(key, expire) else: # this is the place where you save all the time # just return the cached data data = json.loads(data) return Response(data) except Exception as e: logger.exception("Error accessing event cache/n %s" % (e)) # for Admins or exceptions, BAU return super(EventList, self).get(request, format)

En las actualizaciones de mi modelo de evento, borro cualquier caché de eventos. Esto casi nunca se realiza (solo los administradores crean eventos, y no tan a menudo), así que siempre borro todos los cachés de eventos

class Event(models.Model): ... def clear_cache(self): try: cache = get_redis() eventkey = "todaysevents" for key in cache.scan_iter("%s*" % eventkey): cache.delete(key) except Exception as e: pass def save(self, *args, **kwargs): self.clear_cache() return super(Event, self).save(*args, **kwargs)


Redis Cache es la mejor opción. Chequea aquí.

Es de código abierto. Almacén y caché de clave-valor avanzado.


memcached es una gran opción, y veo que ya mencionaste esto como una posible opción. También Redis parece ser elogiado mucho como otra opción en este nivel.

En el nivel de la aplicación, en términos de un enfoque más granular para el almacenamiento en caché en un archivo por archivo y / o módulo, el almacenamiento local siempre es una opción para los objetos comunes que un usuario puede solicitar una y otra vez, incluso tan simple como simplemente dejar de responder. objetos en sesión para que se puedan reutilizar y hacer otra llamada de descanso http y codificar adecuadamente.

Ahora la gente va y viene discutiendo sobre el barniz contra el calamar, y ambos parecen tener sus pros y sus contras, así que no puedo comentar cuál es mejor, pero mucha gente dice que el barniz con un servidor de apache optimizado es ideal para sitios web dinámicos.