手把手带你搞懂Redis那些核心原理,别再只会用不懂背后逻辑了
- 问答
- 2026-01-11 15:13:15
- 2
综合自多位资深技术博主如“程序员小灰”、“小林coding”的公开文章及《Redis设计与实现》一书的核心观点)
你是不是经常遇到这种情况?面试官问你Redis为啥这么快,你只能说出“内存操作”和“单线程”这两个词,再往下问就卡壳了?或者线上出了缓存问题,只能重启大法好,根本不清楚背后的原因?别担心,这篇文章就是来解决这个问题的,我们不扯那些高大上的专业术语,就用人话把手伸进Redis的肚子里,摸摸它的五脏六腑是怎么工作的。
Redis为啥这么快?真就只是“内存”和“单线程”吗?
你说对了开头,但没说完,内存操作意味着不用去慢吞吞的硬盘里翻数据,这当然是基础,但“单线程”这个点,很多人理解有偏差。
- 单线程的真面目:Redis的“单线程”指的是处理网络请求和执行命令的核心模块(我们叫它“主线程”)是单线程的,你想想,如果多个线程同时改一个数据,是不是得加锁?一加锁,线程之间抢来抢去,性能就下去了,Redis直接用单线程干,避免了复杂的锁问题,简单粗暴,但极其有效。
- 快的关键:多路复用:这才是精髓!单线程怎么同时处理成千上万个客户端的连接请求呢?难道要排队吗?不是的,Redis用了叫“I/O多路复用”的技术(别怕这个名字),你可以把它想象成一个超级高效的“前台小哥”,这个小哥同时盯着所有客户(网络连接),哪个客户有活要干(比如发来了一个
GET key命令),小哥就马上记下来,然后交给后厨(主线程)去处理,后厨一次只做一道菜(执行一个命令),但因为它不用自己跑去门口等客户,全靠前台小哥通知,所以效率极高,这样,单线程就能轻松处理海量并发连接了。(来源:小林coding《Redis 单线程模型》)
数据是怎么存“没”的?内存淘汰策略不是你想的那样
你的Redis内存满了,为什么有些数据莫名其妙就消失了?这是因为Redis设置了“内存淘汰策略”,这可不是随机删的,它有好几种算法,就像仓库管理员的清理规则:
- LRU(最近最少使用):这是最常用的,它认为“最近一段时间都没人用的东西,以后用的可能性也小,先扔了”,Redis会记录每个key最后一次被访问的时间,内存不够时,就挑那些最久没被访问的key淘汰掉。
- LFU(最不经常使用):这个是看“访问次数”,它认为“从来没啥人用的东西才是垃圾”,比如一个热点新闻被访问了100万次,一个配置信息只被访问了1次,内存满了就先淘汰那个配置信息。
- 随机淘汰:简单粗暴,随便挑几个key干掉。
你可以在配置文件里指定用哪种策略,下次发现数据没了,别先怪Redis,去看看你的淘汰策略是啥,是不是有些“冷数据”该被清掉了。(来源:《Redis设计与实现》第9章)

持久化:Redis怎么保证重启后数据不丢?
内存断电就没了,Redis咋保证数据安全?它有两个“大招”,相当于给内存数据拍照片和记日记。
- RDB(快照):就像给整个数据库拍一张全景照片(Snapshot),然后把照片存到硬盘上,优点是这张照片很紧凑,恢复起来快,缺点是两次拍照的间隔里,如果服务器宕机,间隔期间的数据就丢了,这就像是“定时备份”。
- AOF(追加日志):它不拍照,而是像写日记一样,把每一个写命令(比如
SET name zhangsan)都记录下来,追加到一个文件里,重启的时候,把日记里的命令重新执行一遍,数据就恢复了,优点是数据安全,最多丢一秒的数据(可以配置),缺点是日记文件会越来越大,恢复起来比RDB慢。
那用哪个呢?生产环境通常两个都开启,用AOF来保证数据安全,用RDB来做冷备份和快速恢复,Redis还有个“AOF重写”机制,会自动把旧的、冗余的日记压缩成一条最新的命令,防止日记无限膨胀。(来源:程序员小灰《漫画:什么是RDB和AOF?》)
缓存雪崩、穿透、击穿:这三个“刺客”你分得清吗?

这是面试必问,也是线上最容易出的问题。
-
缓存雪崩:同一时间,大量的缓存key集体过期了,瞬间,所有请求都绕开失效的缓存,直接砸到数据库上,数据库扛不住,就“雪崩”了。
- 对策:给不同的key设置随机的过期时间,让它们别在同一时刻崩掉。
-
缓存穿透:用户疯狂请求一个数据库中根本不存在的数据(比如id=-1的商品),这个数据缓存里肯定没有,每次请求都会穿透缓存去查数据库,给数据库造成巨大压力,这可能是恶意攻击。
- 对策:如果查不到,也在缓存里存一个空值(比如
SET key-null),并设置一个短的过期时间,下次再来请求这个不存在的数据,直接返回null,别再去查库了。
- 对策:如果查不到,也在缓存里存一个空值(比如
-
缓存击穿:这是一个热点key的问题,这个key非常火,访问量巨大,在它过期的那一刻,大量请求同时涌来,发现缓存没了,于是这些请求同时去查数据库,就像一颗子弹击穿了缓存,直接打爆数据库。
- 对策:用“互斥锁”,第一个发现缓存失效的请求,先去拿到一个锁,然后由它一个人去数据库加载数据,加载完再放进缓存,其他请求要么等待,要么直接返回默认值,这样就能避免集体攻击数据库。
总结一下
你看,当我们不只是敲命令,而是去理解Redis为什么这么设计的时候,很多问题就豁然开朗了,单线程避免了锁的竞争,多路复用解决了高并发IO问题;内存淘汰策略让你能精细控制数据留存;持久化机制是数据的保险绳;理解了雪崩、穿透、击穿的区别,你才能写出真正健壮的缓存代码,下次再有人问你Redis,你就能把这些背后的逻辑讲得头头是道,而不是只停留在“set和get”的表面了。
本文由钊智敏于2026-01-11发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/78757.html
