一文搞懂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文件进行载入,需要注意的是:
如果当前服务器是Master,那么过期键将会被忽略,不会加载
如果当前服务器是Slave,文件中所有的键,不管是否过期都将被载入
AOF 只追加持久化
写入
数据库中的过期键没有被删除时,不会对AOF文件有任何影响;当过期键被删除以后,程序会向AOF文件中追加一条DEl命令,显示该键已被删除。
重写
AOF是通过将执行的写命令添加到AOF文件的末尾来记录数据的而变化的;未避免文件越来越大,采用了重写机制,REWRITEAOF和BGREWRITEAOF两个命令,其区别也是在于是否阻塞主进程,两个命令都不会将数据控件中的过期键保存到AOF文件中。
主从模式
主从模式下,主服务器用来读写命令,从服务器用来读取命令,分担压力,需要注意的是:
如果当前服务器是Master,当服务器通过某种删除策略得知某个键过期,则将该过期键删除,并同步给其他从服务器让他们也删除该键
如果当前服务器是Slave,如果有读命令获取当前过期键时,不会惰性删除,因为会影响读取性能,因此不会删除,并返回过期键对应的值