本文主要是介绍Redis持久化及过期删除策略,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、Redis 持久化之RDB和AOF
1.1 RDB 详解
RDB 是 Redis 默认的持久化方案。在指定的时间间隔内,执行指定次数的写操作,则会将内存中的数据写入到磁盘中。即在指定目录下生成一个dump.rdb文件。Redis 重启会通过加载dump.rdb文件恢复数据。
从配置文件了解RDB
打开 redis.conf 文件,找到 SNAPSHOTTING 对应内容
- RDB核心规则配置(重点)
save <seconds> <changes>
# save ""
save 900 1
save 300 10
save 60 10000
解说:save <指定时间间隔> <执行指定次数更新操作>,满足条件就将内存中的数据同步到硬盘中。官方出厂配置默认是 900秒内有1个更改,300秒内有10个更改以及60秒内有10000个更改,则将内存中的数据快照写入磁盘。
若不想用RDB方案,可以把 save “” 的注释打开,下面三个注释。
- 指定本地数据库文件名,一般采用默认的 dump.rdb
dbfilename dump.rdb
- 指定本地数据库存放目录,一般也用默认配置
dir ./
- 默认开启数据压缩
rdbcompression yes
解说:配置存储至本地数据库时是否压缩数据,默认为yes。Redis采用LZF压缩方式,但占用了一点CPU的时间。若关闭该选项,但会导致数据库文件变的巨大。建议开启。
触发RDB快照
- 在指定的时间间隔内,执行指定次数的写操作
- 执行save(阻塞, 只管保存快照,其他的等待) 或者是bgsave (异步)命令
- 执行flushall 命令,清空数据库所有数据,意义不大。
- 执行shutdown 命令,保证服务器正常关闭且不丢失任何数据,意义…也不大。
注意:
save备份过程:save备份是同步的,如果备份的数据量过大的话,服务器会暂停几百毫秒甚至是1秒
bgsave备份过程:bgsave备份会单独创建一个子进程,将备份的数据写入一个临时文件
RDB数据还原
找到备份临时文件的指令是 config get dir
指令执行成功以后将备份临时文件的目录拷贝到Redis的安装目录下
然后重新启动Redis服务就成功还原数据了
通过RDB文件恢复数据
将dump.rdb 文件拷贝到redis的安装目录的bin目录下,重启redis服务即可。在实际开发中,一般会考虑到物理机硬盘损坏情况,选择备份dump.rdb 。可以从下面的操作演示中可以体会到。
RDB 的优缺点
优点:
- 适合大规模的数据恢复。
- 如果业务对数据完整性和一致性要求不高,RDB是很好的选择。
缺点:
- 数据的完整性和一致性不高,因为RDB可能在最后一次备份时宕机了。
- 备份时占用内存,因为Redis 在备份时会独立创建一个子进程,将数据写入到一个临时文件(此时内存中的数据是原来的两倍哦),最后再将临时文件替换之前的备份文件。
所以Redis 的持久化和数据的恢复要选择在夜深人静的时候执行是比较合理的。
1.2 AOF 详解
AOF :Redis 默认不开启。它的出现是为了弥补RDB的不足(数据的不一致性),所以它采用日志的形式来记录每个写操作,并追加到文件中。Redis 重启的会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
从配置文件了解AOF
打开redis.conf
文件,找到 APPEND ONLY MODE 对应内容
- redis 默认关闭,开启需要手动把no改为yes
appendonly yes
- 指定本地数据库文件名,默认值为 appendonly.aof
appendfilename "appendonly.aof"
- 指定更新日志条件
# appendfsync always
appendfsync everysec
# appendfsync no
解说:
- always:同步持久化,每次发生数据变化会立刻写入到磁盘中。性能较差当数据完整性比较好(慢,安全)
- everysec:出厂默认推荐,每秒异步记录一次(默认值)
- no:不同步
- 配置重写触发机制
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
解说:当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。一般都设置为3G,64M太小了。
1.2.2 触发AOF快照
根据配置文件触发,可以是每次执行触发,可以是每秒触发,可以不同步。
根据AOF文件恢复数据
正常情况下,将appendonly.aof 文件拷贝到redis的安装目录的bin目录下,重启redis服务即可。但在实际开发中,可能因为某些原因导致appendonly.aof 文件格式异常,从而导致数据还原失败,可以通过命令redis-check-aof --fix appendonly.aof 进行修复 。从下面的操作演示中体会。
AOF的重写机制
前面也说到了,AOF的工作原理是将写操作追加到文件中,文件的冗余内容会越来越多。所以聪明的 Redis 新增了重写机制。当AOF文件的大小超过所设定的阈值时,Redis就会对AOF文件的内容压缩。
重写的原理:Redis 会fork出一条新进程,读取内存中的数据,并重新写到一个临时文件中,并没有读取旧文件,最后替换旧的aof文件。
触发机制:当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。这里的“一倍”和“64M” 可以通过配置文件修改。
AOF 的优缺点
- 优点:数据的完整性和一致性更高
- 缺点:因为AOF记录的内容多,文件会越来越大,数据恢复也会越来越慢。
1.3 总结
- Redis 默认开启RDB持久化方式,在指定的时间间隔内,执行指定次数的写操作,则将内存中的数据写入到磁盘中。
- RDB 持久化适合大规模的数据恢复但它的数据一致性和完整性较差。
- Redis 需要手动开启AOF持久化方式,默认是每秒将写操作日志追加到AOF文件中。
- AOF 的数据完整性比RDB高,但记录内容多了,会影响数据恢复的效率。
- Redis 针对 AOF文件大的问题,提供重写的瘦身机制。
- 若只打算用Redis 做缓存,可以关闭持久化。
- 若打算使用Redis 的持久化。建议RDB和AOF都开启。其实RDB更适合做数据的备份,留一后手。AOF出问题了,还有RDB。
二、Redis 过期删除策略
Redis有三种不同的删除策略:
立即删除
:在设置键的过期时间时,创建一个回调事件,当过期时间达到时,由时间处理器自动执行键的删除操作。惰性删除
:键过期了就过期了,不管。每次从dict字典中按key取值时,先检查此key是否已经过期,如果过期了就删除它,并返回nil,如果没过期,就返回键值。定时删除
:每隔一段时间,对expires字典进行检查,删除里面的过期键。
可以看到,第二种为被动删除,第一种和第三种为主动删除,且第一种实时性更高。下面对这三种删除策略进行具体分析
2.1 立即删除
立即删除
能保证内存中数据的最大新鲜度,因为它保证过期键值会在过期后马上被删除,其所占用的内存也会随之释放。但是立即删除对cpu是最不友好的。因为删除操作会占用cpu的时间,如果刚好碰上了cpu很忙的时候,比如正在做交集或排序等计算的时候,就会给cpu造成额外的压力。
而且目前redis事件处理器对时间事件的处理方式–无序链表,查找一个key的时间复杂度为O(n),所以并不适合用来处理大量的时间事件。
2.2 惰性删除
惰性删除
是指,某个键值过期后,此键值不会马上被删除,而是等到下次被使用的时候,才会被检查到过期,此时才能得到删除。所以惰性删除的缺点很明显:浪费内存。dict字典和expires字典都要保存这个键值的信息。
举个例子,对于一些按时间点来更新的数据,比如log日志,过期后在很长的一段时间内可能都得不到访问,这样在这段时间内就要拜拜浪费这么多内存来存log。这对于性能非常依赖于内存大小的redis来说,是比较致命的。
2.3 定时删除
从上面分析来看,立即删除会短时间内占用大量cpu,惰性删除会在一段时间内浪费内存,所以定时删除是一个折中的办法。
定时删除
是:每隔一段时间执行一次删除操作,并通过限制删除操作执行的时长和频率,来减少删除操作对cpu的影响。另一方面定时删除也有效的减少了因惰性删除带来的内存浪费。
2.4 redis使用的策略
redis使用的过期键值删除策略是:惰性删除加上定期删除,两者配合使用。
20240108补充
常见错误:
org.springframework.data.redis.RedisSystemException: Error in execution; nested exception is
io.lettuce.core.RedisCommandExecutionExceptiocurrently not able to persist on disk. Commands that may modify the data set are disabled, because
this instance is configured to report esave-error option). Please check the Redis logs for details about the RDB error.
... ...
Caused by: io.lettuce.core.RedisCommandExecutionException: MISCONF Redis is configured to save RDB snapshots, but it is currently not
ableisabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option)
解决办法
先排查一下磁盘空间是否已经满了
df -h
或者
du -sh *
删除一些多余的文件后可以再执行下面的命令
1. redis-cli
2. config set stop-writes-on-bgsave-error no
参考:
https://www.cnblogs.com/itdragon/p/7906481.html
https://blog.csdn.net/jiangchunhui2009/article/details/81504073
这篇关于Redis持久化及过期删除策略的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!