2009-09-16 49 views

回答

3

如果您需要这种类型的过期控制,您需要将存储的项目的到期时间与项目本身一起进行。

这通常是通过序列化层完成的。写入memcached的条目存储为条目本身和时间戳。当条目反序列化时,检查时间戳,如果条目已过期,则读取条目将被丢弃并视为缓存未命中。

[ entry, expiresAt ] 

对原始分布式缓存条目的TTL通常被设置为无穷大,并且条目只从缓存手动清除,则或者经由LRU政策。

在memcached常见问题解答中,有关于此技术的preventing stampeding requests部分。

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) 
相关问题