当前位置:首页 > 问答 > 正文

Redis缓存新玩法,主要是用来存啥数据加速响应和减轻数据库压力

根据微信公众号“阿里云”的一篇文章《Redis不止是缓存,这些用法让系统更高效》,以及博客园“匠心独运”的博文《Redis实战:如何用缓存为数据库减负》,Redis最常见的玩法确实是作为缓存,但具体存什么数据、怎么存,有很多巧思可以极大提升系统速度。

最直接、最普遍的做法是缓存数据库的查询结果,这是减轻数据库压力的首选,一个电商网站的商品详情页,每次用户点击商品都要去数据库里查询商品信息、库存数量等,如果同时有成千上万人浏览,数据库很容易就撑不住了,这时候,就可以在用户第一次查询后,把商品信息以唯一的Key(比如product:12345)存入Redis,并设置一个过期时间(比如30分钟),接下来的半小时内,再有用户来查询这个商品,系统就直接从速度极快的Redis里读取数据,完全不用再去麻烦数据库,根据“匠心独运”的博文提到,这种模式通常能拦截掉80%以上的重复数据库查询,效果立竿见影。

Redis缓存新玩法,主要是用来存啥数据加速响应和减轻数据库压力

除了这种完整的查询结果,Redis还非常适合存储那些需要复杂计算或聚合才能得到的数据,网站首页经常有一个“热门文章排行榜”或者“本周销量TOP10”,如果每次有人访问首页,都实时去数据库里统计文章的点击量或商品的销量然后排序,对数据库来说是巨大的开销,更聪明的做法是:在用户点击文章或购买商品时,就在Redis里对一个计数器进行增加操作(使用Redis的ZSET有序集合结构非常方便),然后每隔一段时间(比如每小时)才把Redis里的最终排名结果同步到数据库做持久化,而首页展示时,直接读取Redis里已经算好的排名列表,速度极快,数据库几乎无感。

根据“阿里云”文章中的思路,Redis非常适合用来存储用户的会话信息,传统Web应用会把用户的登录状态(Session)存在服务器的内存或文件中,这在分布式环境下很麻烦,用户这次访问服务器A,下次访问服务器B,可能就需要重新登录,如果把Session统一存到Redis里,所有服务器都从同一个Redis读取和验证会话状态,就轻松实现了分布式会话管理,用户登录后,其用户ID、权限等信息被存入Redis并生成一个唯一Session ID返回给浏览器,后续请求只需验证这个ID即可,无需频繁查询用户数据库。

Redis缓存新玩法,主要是用来存啥数据加速响应和减轻数据库压力

还有一种高级玩法是缓存“热点数据”,这是指在短时间内被极度频繁访问的少量数据,某个大V发布了一条微博,或者一个秒杀活动刚开始的瞬间,海量请求会涌向同一条数据,即使这条数据已经在了缓存里,如果Redis是分布式部署的,所有请求也可能都打到存放这条数据的某一个Redis实例上,导致该实例网卡被打满,针对这种情况,“阿里云”的文章提到可以利用Redis的“本地缓存”结合“分布式缓存”的多级缓存架构,即在应用服务器本地内存里也存一份最热点的数据,请求来了先看本地,没有再问Redis,这样能更好地应对瞬时的极端流量。

Redis还可以用来存储一些状态性的临时数据,减轻数据库的“写压力”,用户操作时的互斥锁(防止重复提交)、短信验证码、一个需要逐步完成的流程状态(如订单的待支付、已支付、已发货等),这些数据的特点是读写频繁,但重要性可能没那么高,或者有时效性,把它们放在Redis里,可以避免数据库表被大量的小规模更新操作频繁锁住,让数据库更专注于核心业务数据的持久化和复杂查询。

Redis缓存的核心思想就是“用空间换时间”,把那些频繁读取、计算成本高、但又不是强实时性要求(可以通过设置过期时间来保证最终一致性)的数据放在内存里,让用户请求尽量不走慢速的磁盘数据库,从而实现响应的加速和数据库压力的根本性缓解。