1. Redis过期策略
Redis是一个基于内存的键值对存储数据库,因此需要对键的生命周期进行管理,以免出现过期数据占用大量内存。Redis的过期策略主要有两种:定时删除和惰性删除。
1.1 定时删除
定时删除是Redis默认的过期策略,它会周期性地检查所有设置了过期时间的键,将过期的键删除。在Redis的配置文件redis.conf中,我们可以看到如下配置项:
# 每秒执行10次过期扫描
# Redis过期扫描是通过惰性删除机制,每次从过期字典中随机抽样一部分过期键进行检查,以此来均匀地分摊删除过期键操作的空间和时间复杂度
# 通过这两个参数调整一次淘汰策略执行的键数量,不需要特别调整,如果机器CPU 比较强劲,大部分服务的耗时主要是在 IO 上面,大少这个配置能让每秒清理掉比较多的数据。
# Redis的默认为每秒执行10次键过期扫描 ,可以通过以下两个配置项修改:
# timeout,单位毫秒,指定扫描延迟
# cycle,指定尝试扫描的次数或者键数量
# 定期删除过期键的周期,单位是秒
# 默认值为0,表示禁用定期删除功能
# 在实际使用过程中,建议开启定期删除功能
# 定期删除和惰性删除相结合,能够更好地保证Redis的内存使用率
# (config:redis.conf)
notify-keyspace-events Ex
# 开启AOF持久化后,定期过期扫描可以保证过期键从AOF中及时清除
# (config:redis.conf)
dbfilename dump.rdb
save 900 1
save 300 10
save 60 10000
1.2 惰性删除
惰性删除是指在访问一个已经过期的键时,Redis会将其删除。这种策略可以减少定时删除带来的开销,但是它也带来了一个问题:如果某些键长时间处于出现过期但没有被访问的状态,那么它们就一直占用内存。
为了解决这个问题,Redis引入了一种叫做定期删除的机制。定期删除指的是Redis会每隔一段时间,对一些过期键进行主动的删除。这样就可以保证即使出现一些没有被访问的过期键也能够被及时删除。
2. Redis内存淘汰策略
内存淘汰策略是Redis保证内存使用效率的一个重要手段。Redis提供了多种内存淘汰策略,以便用户根据实际情况选择最适合自己应用场景的策略。
2.1 noeviction
这是Redis的默认策略,如果设置为noeviction,在内存不足以容纳新写入数据时,新写入操作会报错。在某些场景下,这种策略非常有用,比如缓存值的任务,如果在缓存达到上限时,我们可以让新写入操作失败,以便于我们对该场景进行补救措施。
2.2 volatile-lru
volatile-lru策略将会在过期集合根据LRU算法淘汰最近最少使用的一些键(即超过TTL,且空间不足时)。
下面是一个配置文件的例子,使用了volatile-lru淘汰策略:
# 使用100MB淘汰策略只针对过期的键,优先淘汰掉最近最少使用的键
maxmemory 100mb
maxmemory-policy volatile-lru
2.3 allkeys-lru
allkeys-lru和volatile-lru类似,不同的是它针对的是全体键。
# 使用100MB淘汰策略针对所有的键,优先淘汰掉最近最少使用的键
maxmemory 100mb
maxmemory-policy allkeys-lru
2.4 volatile-ttl
volatile-ttl策略将会优先淘汰存活时间较短的键。这种策略适用于过期键很多的场景。
# 使用100MB淘汰策略只针对过期的键,存活时间越短,优先淘汰
maxmemory 100mb
maxmemory-policy volatile-ttl
2.5 volatile-random
这种策略是在已经过期的键中,随机淘汰某个键,如果适用allkeys-random,则是从所有的键中随机淘汰某个。因为是随机淘汰,所以不能保证能够淘汰到最少使用的键,所以不能用于让缓存的命中率更高的场景。
2.6 noexpire(2.8.0版本之后)
noexpire策略表示Redis内存不足时不应该清除任何数据,而是直接拒绝写入操作。
# 只允许访问Redis,不允许写入任何数据
maxmemory 100mb
maxmemory-policy noexpire
3. 总结
通过本文我们了解了Redis的过期策略和内存淘汰策略,这些策略可以让我们更好地控制Redis的内存使用和键的周期。在实际使用过程中,需要根据具体的应用场景来选择合适的策略。