vlambda博客
学习文章列表

一文搞懂Redis缓存的三大策略(过期、内存淘汰、删除)

作为社会主义接班人,我们在项目中避免不了要使用Redis来做缓存。Redis简单易上手,用起来那是相当的可以。但是基于内存的Redis,使用成本也是相当的可以。


我们在使用的时候有没有想过:

使用过程中内存不够了会怎么样?

我们能怎么做?

Redis会怎么做?


故,吾等须知其

过期策略、内存淘汰策略、删除策略

一文搞懂Redis缓存的三大策略(过期、内存淘汰、删除)

过期策略

FIFO (First In First Out)先进先出原则

最先进入的缓存数据在缓存空间不够的情况下(超出最大元素限制时)会首先被清理出去

LFU (Less Frequently Uesd)最少使用原则

一直以来最少被使用的元素会被清理掉。意味着,要求缓存的元素有一个hit属性,在缓存空间不够的情况下,hit值最小的将会被清理出去

LRU (Least Recently Used)最近最少使用原则

缓存的元素有个时间戳,当缓存容量满了,而又要腾出新地方来缓存新的元素的时候,则现有缓存元素中时间戳离当前时间最远的元素将被清除出去

内存淘汰策略

no-eviction(默认使用)

当内存达到阈值之后,所有申请内存的操作都会报错

allkeys-lru

在所有键中,选取一个最近最少使用的key淘汰掉

allkeys-random

在所有键中,随机选取一个进行淘汰

volatile-lru

在设置了过期时间的键中,选取最近最少使用的key淘汰掉

volatile-random

在设置了过期时间的键中,随机选取一个key淘汰掉

volatile-ttl

在设置了过期时间的键中,选取一个即将过期的key淘汰掉

删除策略

定时删除

在设置键的过期时间的同时,设置一个定时器,让定时器在键的过期时间到达的时候,立刻执行对该键的删除操作

  • 优点

    对内存友好。通过定时器可以保证过期的键能尽快地被删除,释放其占用的空间

  • 缺点

    对CPU不友好。在过期键较多的情况下,定时器也会很多,删除操作将过多占用CPU资源

惰性删除

放任键过期不管,每次从键空间获取键时,都检查取到的键的过期时间,如果过期,则删除

  • 优点

    对CPU友好。过期键只有在程序读取时才判断是否过期并删除,且只会删除当前键。

  • 缺点

    对内存不友好。如果多个键都已经过期了,而这些键又恰好没有被访问到,那么这部分内存就不会被释放。

定期删除

每隔一段时间就对数据库进行一次检查,删除过期键

  • 优点

    定时删除与惰性删除的折中处理。每隔一段时间处理一次过期键,并通过限制操作执行的时长与频率来减少删除操作对CPU时间的影响,并有效的减少内存浪费。

  • 缺点

    难点在于间隔时长,需要根据自身业务情况来进行设置

Redis的删除策略

惰性删除 + 定期删除

持久化的删除策略

RDB 快照持久化

  • 创建

    RDB是通过创建快照获取内存中的数据在某一时间点上的副本集;通过SAVE和BGSAVE来创建RDB文件,区别在于是否阻塞进程去创建。这两个命令都不会将数据空间中的过期键给保存到RDB文件中

  • 载入

    在启动redis服务器时(可能距离RDB文件已有一段时间),如果服务器开启了RDB文件,那么服务器就会对RDB文件进行载入,需要注意的是:

    1. 如果当前服务器是Master,那么过期键将会被忽略,不会加载

    2. 如果当前服务器是Slave,文件中所有的键,不管是否过期都将被载入

AOF 只追加持久化

  • 写入

    数据库中的过期键没有被删除时,不会对AOF文件有任何影响;当过期键被删除以后,程序会向AOF文件中追加一条DEl命令,显示该键已被删除。

  • 重写

    AOF是通过将执行的写命令添加到AOF文件的末尾来记录数据的而变化的;未避免文件越来越大,采用了重写机制,REWRITEAOF和BGREWRITEAOF两个命令,其区别也是在于是否阻塞主进程,两个命令都不会将数据控件中的过期键保存到AOF文件中。

主从模式

主从模式下,主服务器用来读写命令,从服务器用来读取命令,分担压力,需要注意的是:

  • 如果当前服务器是Master,当服务器通过某种删除策略得知某个键过期,则将该过期键删除,并同步给其他从服务器让他们也删除该键

  • 如果当前服务器是Slave,如果有读命令获取当前过期键时,不会惰性删除,因为会影响读取性能,因此不会删除,并返回过期键对应的值

一文搞懂Redis缓存的三大策略(过期、内存淘汰、删除)