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

Redis狂神那些零散但实用的学习笔记,里面有些话挺接地气也挺管用的

Redis狂神那些零散但实用的学习笔记

开篇大实话 狂神说:学Redis,你别一上来就想着把源码给啃了,那玩意儿是高手进阶用的,咱们先得会用,知道它为啥快,能干啥,咋用着不踩坑,等你成了老司机,再研究发动机原理也不迟,这东西就是个工具,你的目标是拿它解决问题,不是成为Redis专家(成为专家更好)。

关于数据类型,别死记硬背 都知道Redis有五种基本数据类型:String、List、Set、Zset、Hash,但狂神提醒:你别光记名字,得知道它们各自最适合的场景。

  • String:最简单的,存个字符串、整数、浮点数都行,比如缓存个用户信息JSON串、搞个计数器(文章阅读量,点赞数),incr、decr命令原子性的,不用担心并发问题,贼方便。
  • List:就是个链表,两头操作快,可以用来做消息队列(虽然现在有更专业的MQ,但简单场景List够用)、最新消息排行(比如朋友圈动态,lpush+ltrim保持N条)。
  • Set:无序集合,自动去重,可以用来搞共同关注(求交集sinter)、可能认识的人(求差集sdiff)、随机抽奖(srandmember)。
  • Zset:带分数的Set,有序,这是Redis的王牌数据结构之一。排行榜必备!比如游戏积分榜、热搜榜,还可以做范围查找,比如找价格在100-200之间的商品。
  • Hash:类似Java里的Map,适合存对象,比如存用户信息,key是用户ID,value里用field-value存姓名、年龄、城市,这样比把一个用户对象序列化成JSON字符串存String里,要更灵活,可以单独修改某个字段。

狂神说:你把这些场景对应上,就知道该用啥了,比死记命令强。

持久化,别怕,就两种 Redis为啥重启数据不丢?靠持久化,狂神讲得很直白:

  • RDB(快照):相当于拍照,隔一段时间,把内存里的数据整个拍个照存到磁盘上,优点是恢复快,文件小,缺点是可能会丢最后一次拍照之后的数据(比如5分钟拍一次,服务器在第4分59秒挂了,这5分钟的数据就没了)。
  • AOF(日志):相当于写日记,把你所有的写操作命令都记录下来,重启的时候重新执行一遍这些命令就行了,优点是数据安全,最多丢一秒的数据(配置appendfsync为everysec时),缺点是文件会越来越大,恢复起来慢。

狂神建议:生产环境通常两个都开着,用AOF保证数据安全,用RDB做冷备或者快速恢复,别纠结,都开上,让Redis自己折腾去。

缓存问题,面试常客,实战常坑

  • 缓存穿透:狂神打了个比方,就像有人一直用无效的钥匙捅你家的锁(查一个根本不存在的数据),缓存没有,数据库也没有,数据库压力巨大。解决办法:1. 接口层做校验,不合法的key直接拦掉,2. 即使数据库查不到,也写个空值(比如null)到缓存,并设个短点的过期时间,下次再来查这个无效key,缓存里就有东西了,不会直接打到DB。
  • 缓存击穿:一个热点key(比如明星八卦),突然过期了,这时候海量请求同时过来,全部打到数据库,数据库可能瞬间被打垮。解决办法:1. 设置热点key永不过期,2. 用互斥锁(比如Redis的setnx命令),只让一个请求去查数据库重建缓存,其他请求等着。
  • 缓存雪崩:同一时间,大量的key集体过期,或者Redis服务器宕机了,导致所有请求都砸向数据库,数据库扛不住就崩了。解决办法:1. 给key的过期时间加上随机值,别让它们同时失效,2. 做Redis集群,高可用,一台挂了还有别的,3. 也可以像击穿那样加互斥锁,限流,避免数据库暴毙。

狂神说:这几个概念一定要分清,尤其是穿透和击穿,很多面试官喜欢问。

事务,别跟数据库事务混了 Redis也有事务(multi/exec),但狂神强调:Redis的事务不像MySQL那样保证原子性,它只是把一组命令打包,按顺序执行,中间不会被别的命令插队,但不会回滚,比如你命令语法错了(比如incr一个字符串),执行exec时整个事务里的命令都不会执行,但如果是运行时错误(比如你用hincrby对一个Hash字段进行增加,但那个字段存的是字符串),那只有那条命令失败,其他命令照样执行,用Redis事务要小心。

一些零碎的实用Tips

  • Key的命名:别瞎起名,用冒号分隔,形成层级结构,user:10001:nameorder:20231027:list,这样好管理,也好用keys或scan模式匹配。
  • 批量操作:减少网络IO,多用mget、mset、pipeline,尤其是pipeline,能把多个命令一次性发过去,大大提升性能。
  • 不要用Keys命令:狂神大声强调:**生产环境绝对不要用keys *!数据量一大,Redis会卡死,因为它是遍历所有key,要用scan命令**,它不会阻塞服务。
  • 内存大小要设置:在配置文件里一定要设置maxmemory,不然物理内存用完了,Redis就开始用swap,慢成狗,甚至会被系统当异常进程给kill掉,设置了大小后,还要配置淘汰策略(maxmemory-policy),比如LRU(最近最少使用)淘汰掉一些旧数据。
  • 慢查询日志:一定要配置和关注慢查询日志(slowlog),看看哪些命令执行慢了,可能是大Key或者复杂命令导致的,得优化。

狂神最后总结:Redis这东西,入门简单,深究很难,先把这些基础但实用的东西搞明白,能解决80%的业务场景,剩下的20%,等遇到了再去查资料、去深入,完全来得及,别焦虑,干就完了!

Redis狂神那些零散但实用的学习笔记,里面有些话挺接地气也挺管用的