我在memcached上有几个项目应该在创建时间后24小时到期。我需要更新这些项目,同时保持到期时间不变。
我该怎么做?显然,替换功能需要一个到期参数。
答案 0 :(得分:3)
如果您需要这种类型的到期控制,您需要将存储项目的到期时间与项目本身一起进行。
通常通过序列化层实现此方法。写入memcached的条目存储为条目本身和时间戳。当反序列化该条目时,将检查时间戳,如果它已过期,则读取条目将被丢弃并视为缓存未命中。
[ entry, expiresAt ]
原始memcached条目上的TTL通常设置为无穷大,只能手动或通过LRU策略从缓存中删除条目。
在memcached常见问题解答中,有preventing stampeding requests部分涉及此技术。
答案 1 :(得分:0)
您需要在缓存值时存储它及其原始超时值。这是一个Python实现:
class ExpiringCache(BaseCache):
"""A cache that allows you to update values without changing when the
data will expire. We do this by storing when the value was
inserted in the cache and decrementing the timeout when we update.
"""
def get(self, key, *args, **kwargs):
raw_value = super(ExpiringCache, self).get(key, *args, **kwargs)
# we get None on a cache miss, but otherwise it's a 3-tuple
if raw_value is None:
return None
value, start_time, timeout = raw_value
return value
def set(self, key, value, *args, **kwargs):
timeout = kwargs.get('timeout')
raw_value = (value, now(), timeout)
super(ExpiringCache, self).set(key, raw_value, *args, **kwargs)
def update(self, key, value, timeout=None):
"""If this value is still in the cache, update it but reduce the
timeout. If it's not present, just set it.
"""
raw_value = super(ExpiringCache, self).get(key)
if raw_value is None:
self.set(key, value, timeout=timeout)
return
original_value, start_time, original_timeout = raw_value
if not original_timeout:
# we are caching without a timeout, so just set the new value
self.set(key, value, timeout=original_timeout)
return
elapsed_time = (now() - start_time).total_seconds()
remaining_timeout = timeout - elapsed_time
if remaining_timeout > 0:
self.set(key, value, timeout=remaining_timeout)