示例:缓存

对数据进行缓存是 Redis 最常见的用法之一:因为 Redis 把数据储存在内存而不是硬盘上面,并且访问内存数据的速度比访问硬盘数据的速度要快得多,所以用户可以通过把需要快速访问的数据储存在 Redis 里面来提升应用程序访问这些数据时的速度。

代码清单 2-1 展示了一个使用 Redis 实现的缓存程序代码,这个程序使用 SET 命令来将需要被缓存的数据储存到指定的字符串键里面,并使用 GET 命令来从指定的字符串键里面获取被缓存的数据。


代码清单 2-1 使用字符串键实现的缓存程序:/string/cache.py

  1. class Cache:
  2.  
  3. def __init__(self, client):
  4. self.client = client
  5.  
  6. def set(self, key, value):
  7. """
  8. 把需要被缓存的数据储存到键 key 里面,
  9. 如果键 key 已经有值,那么使用新值去覆盖旧值。
  10. """
  11. self.client.set(key, value)
  12.  
  13. def get(self, key):
  14. """
  15. 获取储存在键 key 里面的缓存数据,
  16. 如果数据不存在,那么返回 None 。
  17. """
  18. return self.client.get(key)
  19.  
  20. def update(self, key, new_value):
  21. """
  22. 对键 key 储存的缓存数据进行更新,
  23. 并返回键 key 在被更新之前储存的缓存数据。
  24. 如果键 key 之前并没有储存数据,
  25. 那么返回 None 。
  26. """
  27. return self.client.getset(key, new_value)

除了用于设置缓存的 set() 方法以及用于获取缓存的 get() 方法之外,缓存程序还提供了由 GETSET 命令实现的 update() 方法:这个方法可以让用户在对缓存进行设置的同时,获得之前被缓存的旧值。用户可以根据自己的需要决定是使用 set() 方法还是 update() 方法对缓存进行设置。

以下代码展示了怎样使用这个程序来缓存一个 HTML 页面,并在有需要时获取它:

  1. >>> from redis import Redis
  2. >>> from cache import Cache
  3. >>> client = Redis(decode_responses=True) # 使用文本编码方式打开客户端
  4. >>> cache = Cache(client)
  5. >>> cache.set("greeting-page", "<html><p>hello world</p></html>")
  6. >>> cache.get("greeting-page")
  7. '<html><p>hello world</p></html>'
  8. >>> cache.update("greeting-page", "<html><p>good morning</p></html>")
  9. '<html><p>hello world</p></html>'
  10. >>> cache.get("greeting-page")
  11. '<html><p>good morning</p></html>'

因为 Redis 的字符串键不仅可以储存文本数据,还可以储存二进制数据,所以这个缓存程序不仅可以用来缓存网页等文本数据,还可以用来缓存图片和视频等二进制数据。比如说,如果你正在运营一个图片网站,那么你同样可以使用这个缓存程序来缓存网站上的热门图片,从而提高用户访问这些热门图片的速度。

作为例子,以下代码展示了将 Redis 的 Logo 图片缓存到键 redis-logo.jpg 里面的方法:

  1. >>> from redis import Redis
  2. >>> from cache import Cache
  3. >>> client = Redis() # 使用二进制编码方式打开客户端
  4. >>> cache = Cache(client)
  5. >>> image = open("redis-logo.jpg", "rb") # 以二进制只读方式打开图片文件
  6. >>> data = image.read() # 读取文件内容
  7. >>> image.close() # 关闭文件
  8. >>> cache.set("redis-logo.jpg", data) # 将内存缓存到键 redis-logo.jpg 里面
  9. >>> cache.get("redis-logo.jpg")[:20] # 读取二进制数据的前 20 个字节
  10. b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x00H\x00H\x00\x00'

注解

在测试以上两段代码的时候,请务必以正确的编码方式打开客户端(第一段代码采用文本方式,第二段代码采用二进制方式),否则测试代码将会出现编码错误。