redis内存管理
Redis中,它的key的类型都是String,大小为512M;而value的类型的大小又不太相同:
- String类型,一个String类型的value最大可以存储512M;
- Lists类型,list的元素个数最多为2^32-1个,也就是4294967295个
- Sets类型,元素个数最多为2^32-1个,也就是4294967295个
- Hashes类型,键值对个数最多为2^32-1个,也就是4294967295个
Redis最大内存设置
我们在启动Redis服务的时候,可以在它的配置文件redis.conf中来配置它的最大内存阈值
和达到阈值的执行策略
,配置如下:
#最大内存控制
maxmemory 1GB
# 达到最大阈值的淘汰策略(下边为默认的删除策略,再次插入会报错)
maxmemory-policy noeviction
Redis内存压缩
Redis配置文件中可以配置相关数据结构类型的压缩选项,例如:
#配置hash类型压缩的条件是元素最多为512个,超过512个则不进行压缩
hash-max-zipmap-entries 512
#配置hash类型value最大为64字节
hash-max-zipmap-value 64
#list中的压缩条件是元素最多为512
list-max-zipmap-entries 512
#配置list类型value最大为64字节
list-max-zipmap-value 64
#set/zset配置类似,在此省略
如果大小超出压缩范围,溢出后Redis将自动将其转换为正常大小
过期数据的处理策略
Redis中的数据可以设置过期时间,那么Redis服务器可以对这些过期的数据进行处理,具体的方式有两种:
主动处理(Redis主动触发检测key是否过期),每秒执行10次。
主动处理的过程如下:
- 从具体相关过期的密钥集中测试20个随机密钥
- 删除找到的所有已过期密钥
- 如果超过25%的密钥已过期,重新执行步骤1
被动处理
每次访问key的时候,发现超时后清理掉
数据恢复阶段过期数据的处理策略
- RDB方式
过期的key不会被持久化到文件中,载入时过期的key,会通过Redis的主动和被动方式清理掉。 - AOF方式
当Redis使用AOF方式持久化时,每次遇到过期的key,Redis会追加一条DEL
命令到AOF文件,也就是说只要我们顺序载入执行AOF命令文件就会删除过期的键。
这里要注意一点,过期数据的计算和计算机本身的时间是有直接联系的!
Redis的回收策略
Redis中的内存满了之后,就会根据具体的淘汰策略来对内存进行管理,具体有两种配置方式:
- redis.conf配置文件中配置
maxmemory-policy noeviction
- 通过命令动态调整
config set maxmemory-policy noeviction
具体的回收策略有:
- noeviction -- 客户端尝试执行会让更多内存被使用的命令直接报错
- allkeys-lru -- 所有的key里执行LRU算法
- volatile-lru -- 在所有已过期的key里执行LRU算法
- allkeys-lfu -- 使用近似LFU逐出任何键
- volatile-lfu -- 使用过期集在密钥中使用近似LFU进行驱逐
- allkeys-random -- 在所有key里随机回收
- volatile-random -- 在已经过期的key里随机回收
- volatile-ttl --回收已过期的key,并且优先回收存活时间(TTL)较短的键
淘汰算法的介绍
LRU算法
LRU(Least recently used,最近最少使用),根据数据的历史访问记录来进行数据淘汰。
- 核心思想:如果数据最近被访问过,那么将来被访问的几率也更高。
- 注意:Redis的LRU算法并非完整的实现,因为这样会占用太多的内存。
- 方法:通过对少量key进行取样(50%),然后回收其中一个符合条件的key。
- 配置方法:
maxmemory-sample 5
LFU算法
LFU(Least Frequently Used),根据数据的历史访问频率来进行淘汰。
- 核心思想:如果数据过去被访问多次,那么将来被访问的频率也更高。
- 注意:Redis实现的是近似的实现,每次对key进行访问时,用基于概率的对数计数器来记录访问次数,同时这个计数器会随着时间的推移而减小(这样能在考虑频率的同时也兼顾时间因素)。
- 启用LFU算法后,可以使用热点数据分析功能。(命令为
redis-cli --hotkeys
)
具体的LFU采用Morris counter算法,参考Morris counter算法