2010-08-18 20 views
5

¿Cuál es el método más rápido para comprimir objetos Python (lista, diccionario, cadena, etc.) antes de guardarlos en la memoria caché y descomprimirlos después de leerlos desde la memoria caché?Comprimir objetos Python antes de guardarlos en la memoria caché

estoy usando Django y espero añadir comprimir/descomprimir el apoyo directamente en el back-end caché de Django, que pone a disposición de todas mis aplicaciones de Django.

Miré en django/core/cache/backend/memcached.py

import cmemcache as memcache 

class CacheClass(BaseCache): 

    def __init__(self, server, params): 
     BaseCache.__init__(self, params) 
     self._cache = memcache.Client(server.split(';')) 

    def get(self, key, default=None): 
     val = self._cache.get(smart_str(key)) 
     if val is None: 
      return default 
     return val 

    def set(self, key, value, timeout=0): 
     self._cache.set(smart_str(key), value, self._get_memcache_timeout(timeout)) 

Parece que la salmuera/unpickle se realiza mediante cmemcache biblioteca. No sé dónde colocar el código de compresión/descompresión.

Respuesta

4

Miré más a fondo el código fuente de python-memcache.

Ya soportaba valores de compresión por zlib antes de enviarlos a memcached.

lv = len(val) 
# We should try to compress if min_compress_len > 0 and we could 
# import zlib and this string is longer than our min threshold. 
if min_compress_len and _supports_compress and lv > min_compress_len: 
    comp_val = compress(val) 
    # Only retain the result if the compression result is smaller 
    # than the original. 
    if len(comp_val) < lv: 
     flags |= Client._FLAG_COMPRESSED 
     val = comp_val 

def _set(self, cmd, key, val, time, min_compress_len = 0): 

Aquí es IMPLEMENTACIÓN de Django para el comando "set" en su backend Memcache:

def set(self, key, value, timeout=0): 
    self._cache.set(smart_str(key), value, self._get_memcache_timeout(timeout)) 

Al parecer, no se han "min_compress_len" parámetro.

5

En primer lugar, ¿estás seguro de que lo necesitas? ¿Sus estructuras de datos son demasiado grandes solo para caber sin comprimir en el caché? Habrá una sobrecarga para la compresión/descompresión, que puede anular cualquier ganancia que haya hecho al almacenar en caché en primer lugar.

Si usted realmente no necesita compresión, entonces es probable que quieren usar zlib.

Si se va a usar zlib, es posible que desee experimentar con los diferentes niveles de compresión disponibles en el método compress, para equilibrar el tiempo de CPU vs niveles de compresión:

zlib.compress(string[, level])
comprime los datos en la cadena de , devolviendo una cadena contenía datos comprimidos. level es un número entero de 1 a 9 que controla el nivel de compresión; 1 es el más rápido y produce la menor compresión, 9 es el más lento y produce la mayor cantidad. El valor predeterminado es 6. Aumenta la excepción error si se produce algún error.

+0

Mi servidor está vinculado a IO y a la RAM, no a la CPU. La asignación actual de memcached usa 1.3GB de RAM. Por lo tanto, al comprimir los datos en un 50%, se ahorran 650MB de RAM o permiten almacenar dos veces más elementos en la memoria caché. – jack

+0

@jack - ver mi edición - ¡buena suerte! –

+0

gracias, voté su respuesta. Pero espero encontrar una solución más genérica que se modifique en el backend de caché. – jack

Cuestiones relacionadas