示例:带有自动移除特性的缓存程序

用户在使用缓存程序的时候,必须要考虑缓存的时效性:对于内容不断变换的应用来说,一份缓存存在的时间越长,它与实际内容之间的差异往往也就越大,因此为了让缓存能够及时地反映真实的内容,程序必须定期对缓存进行更新。

本书前面在《字符串》一章曾经展示过怎样使用字符串键构建缓存程序,但那个缓存程序有一个明显的缺陷,那就是,它无法自动移除过时的缓存。如果我们真的要在实际中使用那个程序的话,那么就必须再编写一个辅助程序来定期地删除旧缓存才行,这样一来使用缓存将会变得非常麻烦。

幸运的是,通过使用 Redis 的键过期功能,我们可以为缓存程序加上自动移除特性,并通过这个特性自动移除过期的、无效的缓存。

代码清单 12-1 展示了一个能够为缓存设置最大有效时间的缓存程序,这个程序跟《字符串》一章展示的缓存程序的绝大部分代码都是相同的,新程序的主要区别在于,它除了会把指定的内容缓存起来之外,还会使用 EXPIRE 命令为缓存设置生存时间,从而使得缓存可以在指定时间到达之后自动被移除。


代码清单 12-1 带有自动移除特性的缓存程序:/expire/unsafe_volatile_cache.py

  1. class VolatileCache:
  2.  
  3. def __init__(self, client):
  4. self.client = client
  5.  
  6. def set(self, key, value, timeout):
  7. """
  8. 把数据缓存到键 key 里面,并为其设置过期时间。
  9. 如果键 key 已经有值,那么使用新值去覆盖旧值。
  10. """
  11. self.client.set(key, value)
  12. self.client.expire(key, timeout)
  13.  
  14. def get(self, key):
  15. """
  16. 获取键 key 储存的缓存数据。
  17. 如果键不存在,又或者缓存已经过期,那么返回 None 。
  18. """
  19. return self.client.get(key)

以下代码简单地展示了这个缓存程序的使用方法:

  1. >>> from redis import Redis
  2. >>> from unsafe_volatile_cache import VolatileCache
  3. >>> client = Redis(decode_responses=True)
  4. >>> cache = VolatileCache(client)
  5. >>> cache.set("homepage", "<html><p>hello world</p></html>", 10) # 设置缓存
  6. >>> cache.get("homepage") # 这个缓存在 10 秒钟之内有效
  7. '<html><p>hello world</p></html>'
  8. >>> cache.get("homepage") # 10 秒钟过后,缓存自动被移除
  9. >>>