2012-03-21 15 views
5

Necesito algo así como un almacén temporal de clave-valor en memoria. Sé que hay soluciones como Redis. Pero me pregunto si el uso de un diccionario de Python podría funcionar. Y potencialmente ser aún más rápido? Así que piense en un servidor Tornado (o similar) ejecutando y manteniendo un diccionario de python en memoria y simplemente devuelva el valor apropiado según la solicitud HTTP.¿Utiliza el diccionario de Python como base de datos de valores-clave temporal en memoria?

¿Por qué necesito esto? Como parte de un servicio, se almacenan valores clave pero tienen esta propiedad: cuanto más recientes sean, más probable es que se acceda a ellos. Así que quiero mantener los últimos 100 valores clave en la memoria (así como escribir en el disco) para una recuperación más rápida.

Si el servidor muere, el diccionario se puede restaurar nuevamente desde el disco.

¿Alguien ha hecho algo como esto? ¿Me estoy perdiendo algo aquí?

PD: Creo que no es posible con un servidor WSGI, ¿verdad? Porque, por lo que sé, no puedes guardar algo en la memoria entre las solicitudes individuales.

Respuesta

4

Definitivamente trabajaría con memcached. Una vez que se ha configurado se puede decorar fácilmente funciones/métodos como se hace en mi ejemplo:

#!/usr/bin/env python 

import time 
import memcache 
import hashlib 

def memoize(f): 

    def newfn(*args, **kwargs): 
     mc = memcache.Client(['127.0.0.1:11211'], debug=0) 
     # generate md5 out of args and function 
     m = hashlib.md5() 
     margs = [x.__repr__() for x in args] 
     mkwargs = [x.__repr__() for x in kwargs.values()] 
     map(m.update, margs + mkwargs) 
     m.update(f.__name__) 
     m.update(f.__class__.__name__) 
     key = m.hexdigest() 

     value = mc.get(key) 
     if value: 
      return value 
     else: 
      value = f(*args, **kwargs) 
      mc.set(key, value, 60) 
      return value 
     return f(*args) 

    return newfn 

@memoize 
def expensive_function(x): 
    time.sleep(5) 
    return x 

if __name__ == '__main__': 
    print expensive_function('abc') 
    print expensive_function('abc') 

No se preocupan por la latencia de red, ya que la clase de optimización será una pérdida de su tiempo.

0

Si está agrupando el diccionario en el mismo servidor que está ejecutando su servicio real, entonces sí, eso funcionaría bien.


Si va a crear cosas separadas, bueno, esto es básicamente lo que es para memcached. Don't reinvent the wheel.

0

Es posible y es mucho más rápido que redis/memcache debido a la falta de latencia de la red. Puede usar cPickle para volcar el diccionario de vez en cuando. Sin embargo, es complicado si su programa genera subprocesos, entonces la actualización de los valores en un proceso no afecta al otro.

+0

Dado que el OP se refiere a un servidor de Tornado que correlaciona las solicitudes al dict ... todavía habrá latencia de red. – Amber

+0

@amber pero no a Memcache/Redis. –

+0

Lo que el OP parece sugerir es * reimplementar * memcache/redis a través de tornado. – Amber

0
  1. Se podía datos que acaba de caché pasado en dict, nadie prohíbe al respecto y funciona en el entorno de un servidor
  2. cuando se añaden nuevos datos - almacenarlo en algunos Redis (memcachedb)
  3. Cuando se vuelva a servidores - solo cargue los últimos N registros en el diccionario

Todo depende del volumen de datos. Creo que se necesita más memoria para mantener las estructuras complejas en el diccionario en Python, el acceso al pensamiento será rápido - sí

2

Un proceso en el diccionario Python es manera más rápido que un servidor memcached. De acuerdo con un punto de referencia no riguroso que realicé hace algunos días, un solo obtener toma alrededor de 2us usando un diccionario de python en proceso y alrededor de 50us usando un servidor de memcached escuchando en localhost. En mi punto de referencia, estaba usando libmemcached como cliente C y python-libmemcached como envoltorio de Python sobre este C-cliente.

1

Estoy experimentando con algo similar, y la biblioteca corecache es una gran manera de probar algunos sistemas de almacenamiento en caché. https://pypi.python.org/pypi/cachecore

En particular, su aplicación SimpleCache se basa en un diccionario Python vainilla, y en mis pruebas preliminares Es extremadamente rápido, 10 veces más rápido que llamar memcached localmente (suponiendo que ya estoy en la aplicación de pitón que necesita el almacenamiento en caché, probablemente el servicio de tornado en su caso).

Cuestiones relacionadas