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

Redis怎么快速用内存做缓存,背后原理其实挺有意思的,聊聊redis内存工作机制

说到Redis怎么用内存做缓存,咱们得先明白它最核心的一个特点:快,为啥它能那么快?一个主要原因就是它把所有数据都放在内存里操作,你想啊,从内存里读数据,比去硬盘数据库(比如MySQL)里读,那可快了不是一星半点,简直就是从自家书桌上拿东西和跑去图书馆查资料的区别。

但这里就引出一个最直接的问题:内存可比硬盘贵多了,而且一断电,数据就全没了,Redis是怎么解决这两个“命门”的呢?这就是它内存工作机制有意思的地方了。

怎么在有限的内存里放下更多的东西?—— Redis的“精打细算”

Redis怎么快速用内存做缓存,背后原理其实挺有意思的,聊聊redis内存工作机制

Redis可不是把数据往内存里一扔就不管了,为了节省空间,它用了不少巧妙的办法:

  1. “因地制宜”的数据结构:Redis不是只用一种简单的方式来存所有数据,比如你存一个数字,Redis发现这是个整数,它就会用一个特别省空间的结构(int)来存,而不是当成字符串来存,对于哈希(Hash)这种结构,当字段很少的时候,Redis会用一种叫ziplist(压缩列表) 的结构,把所有的键值对紧凑地排在一起,能有效减少内存开销,只有当数据量变大时,才会转换成标准的哈希表,这种根据数据大小和类型动态选择底层结构的能力,是它节省内存的第一招。(来源:Redis官方文档关于内存优化的部分)

  2. “过期”数据的自动清理:缓存数据很多都不是需要永久保存的,Redis允许你给每个键(key)设置一个生存时间(TTL),时间一到,这个键就会被自动删除,释放出内存空间,这就像给超市里的商品贴了个保质期标签,到期就下架,腾出货架给新商品,它主要通过两种方式实现:

    Redis怎么快速用内存做缓存,背后原理其实挺有意思的,聊聊redis内存工作机制

    • 惰性删除:当客户端尝试访问一个键时,Redis才会检查它是否过期了,如果过期就当场删除,这很及时,但如果一个过期的键永远没人访问,它就永远占着地方。
    • 定期删除:Redis会每隔一段时间(默认100毫秒)随机抽取一些设置了过期时间的键进行检查,删除其中已过期的,通过这种主动扫描的方式,来弥补惰性删除的不足。(来源:《Redis设计与实现》一书中关于键过期策略的章节)

内存用完了怎么办?—— Redis的“断舍离”机制

就算再省,服务器的内存总是有限的,当新数据进来,发现内存已经满了,Redis怎么办?它不会直接报错,而是会根据你预先配置的内存淘汰策略(maxmemory-policy) 来决定扔掉哪些旧数据,给新数据腾地方,常见的策略有:

  • allkeys-lru:这是最常用的一种,LRU是“最近最少使用”的意思,Redis会尝试淘汰掉所有键中,最长时间没有被访问过的那个,这很符合缓存的直觉:把最不常用的“冷”数据踢出去。
  • volatile-lru:只从那些设置了过期时间的键中,淘汰最近最少使用的。
  • allkeys-random:随便淘汰一个键,简单粗暴。
  • noeviction:不淘汰任何数据,当内存不足时,新写入的操作会报错,这适合你要求数据绝对不能丢失的场景。

(来源:Redis配置文件中关于maxmemory-policy的详细说明)

Redis怎么快速用内存做缓存,背后原理其实挺有意思的,聊聊redis内存工作机制

这里有个有趣的技术点,实现一个完美的LRU算法需要记录每个键的精确访问时间戳,这会消耗额外内存,所以Redis用了个近似LRU算法:它每次随机挑选几个键,然后从这几个键里淘汰掉那个最久未使用的,虽然不绝对精确,但在实际应用中效果非常好,而且几乎不消耗额外资源,这种在精确度和效率之间的权衡,体现了Redis务实的设计哲学。

断电后数据怎么恢复?—— 持久化机制

为了解决内存数据易失的问题,Redis提供了两种主要的“备份”到硬盘的机制:

  • RDB(快照):在特定的时间点,把当前内存中完整的数据集生成一个快照文件(dump.rdb)保存到硬盘,恢复的时候,直接把这份文件读回内存就行了,速度非常快,缺点是如果服务器在两次快照之间宕机,会丢失最后一次快照之后的数据。
  • AOF(追加日志):把每一个写命令都记录到一个日志文件里,当Redis重启时,会重新执行一遍AOF文件中的所有命令,来恢复数据,这样数据丢失的风险极低(你可以配置成每秒同步一次,甚至每命令同步),缺点是AOF文件通常会比RDB文件大,恢复速度也慢一些。

很多时候,生产环境会两者结合使用,用AOF来保证数据安全,同时定期生成RDB快照用于快速恢复和备份。

所以你看,Redis看似简单,就是往内存里存数据,但背后这一整套机制——从如何高效利用内存、智能淘汰数据,到如何持久化保证数据安全——环环相扣,共同支撑起了它作为高性能缓存的核心能力,它不是在蛮干,而是在内存这个昂贵的资源上,做足了精细化的文章。