自制小memcache

sys*_*out 5 python memcached

我正在将"云"之外的Google App Engine Web应用程序移动到标准Web框架(webpy),我想知道如何实现Gae上提供的memcache功能.

在我的应用程序中,我只使用此缓存来存储每隔X小时从远程api检索到的一堆数据; 换句话说,我并没有过多地强调这个缓存.

我天真地实现了这样的事情:

class TinyCache():
    class _Container():
        def __init__(self, value, seconds):
            self.value = value
            self.cache_age = datetime.now()
            self.cache_time = timedelta(seconds = seconds)
        def is_stale(self):
            return self.cache_age + self.cache_time < datetime.now() 

    def __init__(self):
        self.dict_cache={}

    def add(self, key, value, seconds = 7200):
        self.dict_cache[key] = self._Container(value, seconds)

    def get(self, key):
        if key in self.dict_cache:
            if self.dict_cache[key].is_stale():
                del self.dict_cache[key]
                return None
            else:
                return self.dict_cache[key].value
        else:
            return None
Run Code Online (Sandbox Code Playgroud)

典型用法是:

data = tinycache.get("remote_api_data")
if data is not None:
    return data
else:
    data = self.api_call()
    tinycache.add("remote_api_data", data, 7200)
    return data
Run Code Online (Sandbox Code Playgroud)

我怎么能改进它?
我需要将其设为线程安全吗?

Man*_*res 2

在我看来,您的缓存可能会增长效率低下,因为它将保留很少使用的条目。get因为,除非请求对特定键进行操作,否则缓存中的条目似乎不会被删除。

如果您想改进缓存,我会添加以下两个简单的功能:

  1. 当请求一个项目时,我会重新启动seconds到初始值。因此要保留您的系统经常使用的元素。
  2. 我将在一个单独的线程中实现一种机制来遍历缓存并删除太旧的条目。

您还可以从这个固定大小缓存中得到一些想法

已编辑

我刚刚找到这个食谱,太酷了。基本上你可以用函数装饰器包装你想要缓存的逻辑。就像是:

@lru_cache(maxsize=20)
def my_expensive_function(x, y):
    # my expensive logic here
    return result
Run Code Online (Sandbox Code Playgroud)

这些LRU 和 LFU 缓存装饰器将为您实现缓存逻辑。最近最少使用 (LRU) 或最少经常使用 (LFU)(有关这些的参考,请参阅Cache_algorithms )