Django中的层次缓存

6
我想要做的是将缓存中的一些值标记为相关,这样我就可以一次性删除它们。例如,当我向数据库插入新条目时,我想删除基于旧数据库值的缓存中的所有内容。
我可以使用cache.clear(),但这对我来说似乎太过暴力了。或者我可以将相关值一起存储在字典中,并将其缓存。或者我可以在缓存中的额外字段中维护某种索引。但是所有这些方法对我来说都太复杂了(最终会变慢?)。
你认为呢?有没有现成的解决方案?还是我的方法有误?谢谢回答。
2个回答

6

你是否正在使用缓存 API?听起来是这样的。

这篇帖子,它指向了这些幻灯片,帮助我创建了一个很好的生成缓存系统,让我创建了我想要的层次结构。

简而言之,您在缓存中存储一组键(例如group),并将存储的值合并到键创建函数中,以便可以一次性使整个键集无效。

有了这个基本概念,您可以创建高度复杂的层次结构或仅创建一个简单的分组系统。

例如:

class Cache(object):
    def generate_cache_key(self, key, group=None):
        """
        Generate a cache key relating them via an outside source (group)
        Generates key such as 'group-1:KEY-your-key-here'

        Note: consider this pseudo code and definitely incomplete code.
        """
        key_fragments = [('key', key)]

        if group:
            key_fragments.append((group, cache.get(group, '1')))

        combined_key = ":".join(['%s-%s' % (name, value) for name, value in key_fragments)

        hashed_key = md5(combined_key).hexdigest()
        return hashed_key


    def increment_group(self, group):
        """
        Invalidate an entire group
        """
        cache.incr(group)


    def set(self, key, value, group=None):
        key = self.generate_cache_key(key, group)
        cache.set(key, value)


    def get(self, key, group=None):
        key = self.generate_cache_key(key, group)
        return cache.get(key)

# example
>>> cache = Cache()
>>> cache.set('key', 'value', 'somehow_related')
>>> cache.set('key2', 'value2', 'somehow_related')
>>> cache.increment_group('somehow_related')
>>> cache.get('key') # both invalidated
>>> cache.get('key2') # both invalidated

哇,真聪明!我猜旧值实际上没有被删除不是问题吧? - tobik
我指向上面的幻灯片只是说当memcached内存不足时,它会首先清除最旧的键。我不确定删除这些键并防止旧但仍然有效的键被优先清除对现实世界的改进是什么。我会优化这个问题。 - Yuji 'Tomita' Tomita
1
这将当前版本号存储在缓存中。如果缓存按最后一次获取或设置操作的时间来刷新,那么我想这应该可以正常工作,但是如果它使用其他方法,那么可能会刷新组的当前版本,使其重置为1,并且您可能会从缓存中获取过期的数据。 - HostedMetrics.com

0

对我来说,将字典或类似的东西(使用JSON或类似的方式)进行序列化缓存听起来不错。缓存后端是键值存储,例如memcache,它们不是分层的。


对我来说听起来也不错,但是想象一下这样的情况:如果我要缓存50个HTML页面,加载/存储每一个页面都意味着首先要加载所有50个页面。缓存是否足够快速和无限以处理这个问题? - tobik
好的,不是那种情况。还有另一种方法:使页面的缓存键取决于几个特定于页面的变量。这些变量可以在数据库中,并且可以使用短期过期进行缓存。页面翻动应该很低,您可以让旧键的页面在较长时间内过期。 - Tobu
谢谢你的想法,非常有趣。但是我可能会使用下一个答案中的解决方案,因为更符合我的需求。 - tobik
1
我的建议基本上与Yuji的答案相同。旧值被删除,请参阅有关过期的文档(默认为5分钟)。 - Tobu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接