2010-08-18 73 views
5

在从缓存中读取之后将Python对象(列表,字典,字符串等)保存到缓存和解压缩之前,什么是快速压缩Python对象的方法?在保存到缓存之前压缩Python对象

我正在使用Django,我希望直接在Django的缓存后端添加压缩/解压缩支持,这使得它可用于我的所有Django应用程序。

我看着Django的/核心/缓存/后端/ 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)) 

看起来像泡菜/ unpickle由cmemcache库完成。我不知道在哪里放置压缩/解压缩代码。

回答

4

我进一步查看了python-memcache的源代码。

在将它们发送到memcached之前,它已经支持zlib的压缩值。

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): 

下面是Django的在其内存缓存后台“设置”命令FPGA实现:

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

显然,它不具有“min_compress_len”参数。

5

首先 - 你确定你需要它吗?你的数据结构是否太大以适应缓存中的未压缩?压缩/解压缩将会产生开销,这可能会使您首先通过缓存取得的任何收益失效。

如果你真的需要压缩,那么你可能要使用zlib

如果你要使用zlib,你可能会想在compress方法可用不同的压缩级别进行实验,以平衡CPU时间与压缩级别:

zlib.compress(string[, level])
压缩字符串数据,返回一个包含压缩数据的字符串。 level是一个从1到9的整数,用于控制压缩的级别; 1是最快的并且产生最小的压缩,9是最慢的并且产生最多的。缺省值为6.如果发生任何错误,则引发error异常。

+0

我的服务器是IO绑定和RAM绑定,而不是CPU绑定。当前的memcached分配使用1.3GB的RAM。因此,将数据压缩50%可节省650MB RAM,或者可以在缓存中存储两次以上的项目。 – jack 2010-08-18 12:08:23

+0

@jack - 看我的编辑 - 祝你好运! – 2010-08-18 12:11:48

+0

谢谢,我投了你的答案。但我希望找到一个更通用的解决方案,它在缓存后端进行修改。 – jack 2010-08-18 15:43:46