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

用Redis来搞性能缓存,提升速度和效率那些事儿怎么设置才靠谱

说到用Redis提升系统速度和效率,这事儿说白了就是找个“临时笔记本”,把那些费时费力算出来的结果或者经常要翻看的数据先记下来,下次需要的时候直接看笔记,省得重新计算或者跑大老远去数据库里翻,Redis就是这个速度极快的“临时笔记本”,而且这个笔记本特别擅长记一些简单的键值对,那怎么设置才算靠谱,不让这个笔记本反而变成麻烦呢?我从几个方面来说道说道。

用Redis来搞性能缓存,提升速度和效率那些事儿怎么设置才靠谱

最关键的,你得想清楚“什么数据值得放进缓存里”。(参考开源社区普遍实践)不是所有数据都适合,符合下面几种情况的,就是缓存的好苗子:

  1. 读的次数远远多于写的数据:比如商品的分类信息、用户的基本资料、新闻网站的热门文章,这些东西一旦创建,很长时间不会变,但每天被查看成千上万次,每次读都去查数据库,数据库压力山大,把它丢进Redis,速度能飞起来。
  2. 计算起来特别复杂或者耗时的结果:比如一个复杂的报表统计、一次大数据分析的结果、网页上某个需要渲染半天的部分,算一次可能要好几秒,但算出来的结果可能几分钟内都是有效的,那就算一次,然后把结果塞进Redis,接下来几分钟所有需要这个结果的人直接来取现成的,体验立马提升。
  3. 需要应对突发的高并发访问:比如明星出轨新闻爆出那一刻,全网都去刷他的微博主页,如果每次都去数据库查,数据库很可能当场“挂掉”,这时候可以用Redis先把主页信息缓存住,哪怕数据不是最新的,但至少能保证服务不中断,大家都能刷出页面来,只是可能看不到最新的那条评论,这叫“保活”。

选好了要缓存什么,接下来就是“怎么存”的问题了,Redis虽然快,但内存比硬盘贵,不可能无限制地存东西,所以设置过期时间(TTL)是必须的。(参考Redis官方文档核心建议)你不能把数据放进缓存就撒手不管了,那迟早会把内存撑爆,给缓存数据设置一个合理的存活时间,比如用户信息缓存15分钟,热门商品列表缓存5分钟,排行榜缓存1小时,时间到了,Redis会自动把它删掉,下次需要时再重新从数据库加载并设置新的过期时间,这就像给你的笔记定个“复习期限”,到期了看看信息有没有变,变了就更新一下笔记。

用Redis来搞性能缓存,提升速度和效率那些事儿怎么设置才靠谱

过期时间怎么定也有讲究,如果所有缓存都在同一时刻失效,会导致所有请求瞬间都涌向数据库,造成“缓存雪崩”。(参考分布式系统常见问题描述)为了避免这个,可以给缓存过期时间加个随机数,比如基础是10分钟,然后加上一个0到2分钟的随机值,这样缓存就不会在同一时刻集体失效了,压力会平摊开。

还有一个头疼的问题是“缓存穿透”。(参考分布式系统常见问题描述)就是有人故意请求一个根本不存在的数据,比如查询一个不存在的用户ID,这个数据缓存里肯定没有,每次请求都会落到数据库上,相当于缓存失效了,对付的办法很简单,如果从数据库没查到,也在Redis里存一个空值(比如user_id:-1: null),并设置一个较短的过期时间(比如1分钟),这样下次再有人来查这个不存在的ID,在缓存层就直接返回空了,保护了数据库。

比穿透更厉害的是“缓存击穿”。(参考分布式系统常见问题描述)指的是某个非常热点的数据(比如秒杀商品详情)过期的那一刻,突然有大量请求同时过来,都发现缓存没了,于是同时去访问数据库,对付这个可以用“互斥锁”机制,简单说就是,当第一个发现缓存失效的请求过来时,它先去占个“坑”(在Redis里设置一个特殊的锁标记),然后由它一个人去数据库加载数据重建缓存,其他请求看到有“坑”被占了,就等一会儿(比如休眠50毫秒),然后重新尝试从缓存读取,这时候很可能第一个请求已经重建好缓存了,这样就避免了数据库被重复查询。

Redis本身也是个软件,跑在服务器上,所以高可用和持久化也得考虑。(参考Redis官方文档核心建议)如果你只有一台Redis服务器,它万一宕机了,所有缓存瞬间清空,数据库压力会暴增,系统可能崩溃,生产环境一般会做主从复制(Master-Slave),一台主节点负责写,多台从节点备份数据负责读,这样即使主节点挂了,可以从从节点里选一个顶上去,要配置好持久化策略(RDB快照和AOF日志),定期把内存中的数据备份到硬盘上,防止服务器彻底宕机后数据全部丢失。

用Redis搞缓存想靠谱,核心就几点:选对缓存的数据、务必设置过期时间、用加随机数防雪崩、用存空值防穿透、用锁机制防击穿、最后做好高可用和持久化备份,把这些事儿琢磨透了,Redis就能真正成为你提升系统性能的利器,而不是一个隐藏的故障点。

用Redis来搞性能缓存,提升速度和效率那些事儿怎么设置才靠谱