数据淘汰与内存回收
redis的内存满了,会进行内存的回收
回收的对象:
- key过期了,会回收,采用过期策略
- 当redis使用的内存达到了设置的max_memory,会触发内存回收(淘汰)策略
过期策略
定时过期:到了key的过期时间,立即删除(为每个设定了过期时间属性的key创建一个定时器,过期了马上删除),会大量占用cpu的字段,影响redis的响应时间和吞吐量
惰性过期:key被访问的时候才判断是否过期,过期则删除。会节省cpu资源,但是会占用大量内存
定期过期:每隔一段时间,清除一定数量的过期的key
淘汰策略
redis内存上限设置
在conf文件中设置值maxmemory,不设置或者0,在64位系统中是不限制的,在32位 系统中最多为3G内存
或者在客户端执行config set maxmemory2GB
LRU/LFU
LRU:Least Recently Used 最近最少使用,根据最后被使用的时间,时间最远的先淘汰
LFU:Least Frequently Used 最不常用的数据,根据一定时间内的访问频率,将使用最少的淘汰
random:随机在设置了过期时间,即将过期的key中选一些key进行删除
ttl:设置了过期时间的key,优先删除即将过期的key
noeviction:没有淘汰策略
volatile/allkeys
volatile 有过期时间属性的key
allkeys 所有key
volatile-lru
allkeys-lru
volatile-lfu
allkeys-lfu
volatile-random
allkeys-random
volatile-ttl
noeviction
默认是不淘汰的
推荐用volatile-lru
LRU
传统实现:链表+HashMap实现
如果访问key,将key放到链表的头部,当长度不够时,优先删除链表末尾的节点
Redis中采用随机采样的方式
maxmemory-samples 5
从数据库中随机选取5个值,将热度最低的值淘汰
redis中,所有的key都有一个LRU的属性字段,用了保存时间戳的值
这个LRU为全局变量 server.lruclock拿到的值
serverCron 会每隔100ms更新一次server.lruclock
热度计算是取LRU属性和server.lruclock差值,差值越大,说明越久没有被访问
LFU
- key最后被访问的时间
- key被访问的频率(计数器counter)增长不是每次访问都加一,有增加因子决定,在redis中是配置中的lfu-log-factor,lfu-log-factor越大,counter增加的越慢。lfu-decay-time衰减因子,单位是分钟,默认是1,表示1分钟没有被访问,counter就减一(配置在redis.conf中)
持久化机制
RDB:Redis DataBase
AOF:Append Only File
RDB
默认方案 ,在满足一定条件的时候,redis里的数据会写入到RDB文件中,系统重启的时候,根据RDB文件将数据恢复的redis中
-
配置规则触发/shutdown触发/flushall触发
通过redis.conf中的save配置自动触发的规则
save 900 1 :900代表秒数,1代表key的数量,表示900秒之内至少有1个key修改了,就会触发一次
文件生成路径在dir配置,文件名称在dbfilename配置
rdbcompression 如果开启了,会通过LZF算法对rdb文件进行压缩,会消耗一定cpu的计算时间,但会节省存储空间
rdbchecksum 如果开启,会用CRC64的的算法,对RDB文件的完整性进行校验
shutdown时会触发写入
flushall 触发会清空rdb文件
-
手动触发:save/bgsave
在客户端执行save指令,在生成快照时会阻塞服务器,redis就不能处理其他客户端的数据了
bgsave=backgroud save,redis会在后台异步的进行生成快照的操作,此时服务端可以响应客户端的请求
服务启动时会找rdb文件,恢复数据
特点
- 内容紧凑,保存redis在某个时间节点的全部数据集
- 不影响主进程,会用子进程处理
- 恢复大数据集时速度快
- 同步频率,不能实时持久化,不能秒级持久化,在持久化之前宕机,会导致数据丢失
AOF
默认不开启
使用日志的形式记录操作,追加到文件中
回复数据时,将AOF记录的日志从头到尾执行一次
AOF的开关是redis.conf中的appendonly
文件名在appendfilename配置
目录与rdb相同
AOF不会实时写入,会先放入到系统磁盘的缓存
appendsync everysec/always/no
no表示在某些情况下触发这个操作,把系统缓存写到AOF文件中,速度最快,但是不安全
always表示每次操作都会执行一次,效率低
everysec表示每秒钟执行一次
重写机制
当AOF文件大小超过一定阈值的时候,redis会对AOF文件进行压缩,只会保留用来恢复数据的最小指令集
可以通过bgrewriteaof命令来手动触发重写
在配置中通过两个参数来配置
auto-aof-rewrite-percentace 100
在上一次重写之后,如果当前AOF文件达到了上次文件重写之后大小的100倍会自动触发重写
auto-aof-rewrite-min-size 64mb
如果文件到达了多少大小的时候就会进行重写,如果到达了百分比的比例,但是没有到达最小大小的,也不会触发重写
开启了AOF后,会优先使用AOF恢复数据,不会用到RDB
如果AOF是空的,其实重启服务,会清空redis的数据,所以执行重启前,先执行AOF的重写
特点
- 同步频率,最多丢失1秒的数据
- 文件大小,aof的体积比rdb更大
- 性能,高并发的情况下,rdb的性能比aof更好,如果可以忍受一部分数据丢失,可以使用RDB恢复,一般是同时使用的