麦克斯仇
Think different
159
文章
27970
阅读
首页
INDEX
文章
ARTICLE
关于
ABOUT
Redis数据持久化:RDB与AOF
创建日期:
2021/05/17
修改日期:
2022/10/10
Redis
> 本文档整理自教程: 1. Redis官方文档:[Redis Persistence](https://redis.io/topics/persistence) 2. 尚硅谷视频:[尚硅谷_Redis6](http://www.atguigu.com/download_detail.shtml?v=323) 3. PS:关于如何恢复数据本文未介绍,请看尚硅谷视频 # 介绍 > Redis提供了不同范围的持久性选项: - **RDB** (Redis Database): RDB持久化在指定的时间间隔执行数据集的时间点快照。 - **AOF** (Append Only File): AOF持久化记录服务器接收到的每个写操作,在服务器启动时再次播放,重建原始数据集。命令记录使用与Redis协议本身相同的格式,以一种仅附加的方式。当日志变得太大时,Redis能够在后台重写日志。 - **No persistence**: 如果希望数据在服务器运行期间一直存在,那么可以完全禁用持久性。 - **RDB + AOF**: 在同一个实例中可以同时使用AOF和RDB。注意:在这种情况下,当Redis重启时,AOF文件将被用来重建原始数据集,因为它被保证是最完整的。 要理解的最重要的事情是RDB和AOF持久性之间的不同权衡。 # RDB ## 简介 在指定的**时间间隔**内将内存中的数据集**快照**写入磁盘,它恢复时是将快照文件直接读到内存里。 `Redis`会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。 整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能。 如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。 ![](https://cdn2.maxqiu.com/upload/3bde20985cb34843b5017a7273c944dc.png) ## 使用 > 备份文件位置和文件名称 在`redis.conf`配置文件中修改如下设置 - `dbfilename dump.rdb`:默认情况下,RDB备份文件名为`dump.rdb` - `dir ./`:默认情况下,文件备份在当前路径下(启动脚本时的当前路径),一般修改为指定路径 > 自动快照配置 默认情况下Redis会按照如下策略自动保存: - 在3600秒(一小时)后,如果至少有一个键发生了变化 - 在300秒(5分钟)后,如果至少有100个键发生了变化 - 在60秒后,如果至少有10000个键发生了变化 也可以在`redis.conf`配置文件中通过`save <seconds> <changes>`手动修改,例如 ```ini save 3600 1 save 300 100 save 60 10000 ``` PS:如需禁用快照,需要在配置文件中添加如下内容 ```ini save "" ``` > 手动备份 使用`save`和`bgsave`指令均会触发保存 - `save`:save时只管保存,其它不管,全部阻塞。不建议。 - `bgsave`:Redis会在后台异步进行快照操作, 快照同时还可以响应客户端请求。 通过`lastsave`命令获取最后一次成功执行快照的时间 PS:执行`flushall`命令也会刷新`dump.rdb`文件,文件内容为空 ## 其他配置 - `stop-writes-on-bgsave-error yes`:当Redis无法写入磁盘的话,直接关掉Redis的写操作。推荐yes,这样就会发现服务器存在问题 - `rdbcompression yes`:对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩。如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能。推荐yes - `rdbchecksum yes`:在存储快照后,还可以让redis使用CRC64算法来进行数据校验,这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。推荐yes ## 优劣势 ### 优势 - 适合大规模的数据恢复 - 对数据完整性和一致性要求不高更适合使用 - 节省磁盘空间 - 恢复速度快 ### 劣势 - Fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑 - 虽然Redis在fork时使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能。 - 在备份周期在一定间隔时间做一次备份,所以如果Redis意外down掉的话,就会丢失最后一次快照后的所有修改。 # AOF ## 简介 以日志的形式来记录每个写操作(增量保存),将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,Redis启动之初会读取该文件重新构建数据,换言之,Redis重启之后就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作 > 流程 1. 客户端的请求写命令会被append追加到AOF缓冲区内 2. AOF缓冲区根据AOF持久化策略[always,everysec,no]将操作同步到磁盘的AOF文件中 3. AOF文件大小超过重写策略或手动重写时,会对AOF文件rewrite重写,压缩AOF文件容量 4. Redis服务重启时,会重新加载AOF文件中的写操作达到数据恢复的目的,AOF和RDB同时开启,系统默认取AOF的数据(数据不会存在丢失) ![](https://cdn2.maxqiu.com/upload/8704014fe88d43f59fccac65c2e3ef70.png) ## 使用 > 开启AOF 默认情况下,`AOF`未开启,需要在配置文件中打开,如下: ```ini appendonly no ``` > 备份文件位置和文件名称 在`redis.conf`配置文件中修改如下设置 - `appendfilename "appendonly.aof"`:默认情况下,AOF备份文件名为`appendonly.aof` - `dir ./`:使用和`RDB`相同的配置项 > AOF同步评率 `Redis`将根据`appendfsync`配置来决定何时将日志写入文件,有如下三种模式 - `appendfsync always`:始终同步,每次Redis的写入都会立刻记入日志;性能较差但数据完整性比较好 - `appendfsync everysec`:每秒同步,每秒记入日志一次,如果宕机,最后一秒内的数据可能丢失。 - `appendfsync no`:Redis不主动进行同步,把同步时机交给操作系统。 ## 其他配置:Rewrite压缩 > 是什么 AOF采用文件追加方式,文件会越来越大,为避免出现此种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。可以使用命令`bgrewriteaof`手动调用 > 重写原理,如何实现重写 AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再rename),redis4.0版本后的重写,实际上就是把rdb的快照,以二级制的形式附在新的aof头部,作为已有的历史数据,替换掉原来的流水账操作。 > 触发机制,何时重写 Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发,重写虽然可以节约大量磁盘空间,减少恢复时间。但是每次重写还是有一定的负担的,因此设定Redis要满足一定条件才会进行重写。 例如:文件达到70MB开始重写,降到50MB,下次什么时候开始重写?100MB 系统载入时或者上次重写完毕时,Redis会记录此时AOF大小,设为`base_size`,如果Redis的AOF当前大小`>=base_size+base_size*100%`(默认)且当前大小`>=64mb`(默认)的情况下,Redis会对AOF进行重写。 > 重写流程 1. `bgrewriteaof`触发重写,判断是否当前有`bgsave`或`bgrewriteaof`在运行,如果有,则等待该命令结束后再继续执行。 2. 主进程fork出子进程执行重写操作,保证主进程不会阻塞。 3. 子进程遍历redis内存中数据到临时文件,客户端的写请求同时写入`aof_buf`缓冲区和`aof_rewrite_buf`重写缓冲区保证原AOF文件完整以及新AOF文件生成期间的新的数据修改动作不会丢失。 4. 子进程写完新的AOF文件后,向主进程发信号,父进程更新统计信息。 5. 主进程把`aof_rewrite_buf`中的数据写入到新的AOF文件。 6. 使用新的AOF文件覆盖旧的AOF文件,完成AOF重写。 ![](https://cdn2.maxqiu.com/upload/97592f62945a47588380b108808507fb.png) > 配置项 - `no-appendfsync-on-rewrite`: - `no-appendfsync-on-rewrite=yes`,不写入aof文件只写入缓存,用户请求不会阻塞,但是在这段时间如果宕机会丢失这段时间的缓存数据。(降低数据安全性,提高性能) - `no-appendfsync-on-rewrite=no`,还是会把数据往磁盘里刷,但是遇到重写操作,可能会发生阻塞。(数据安全,但是性能降低) - `auto-aof-rewrite-percentage`:设置重写的基准值,文件达到100%时开始重写(文件是原来重写后文件的2倍时触发) - `auto-aof-rewrite-min-size`:设置重写的基准值,最小文件64MB。达到这个值开始重写。 ## 优劣势 ### 优势 - 备份机制更稳健,丢失数据概率更低。 - 可读的日志文本,通过操作AOF稳健,可以处理误操作。 ### 劣势 - 比起RDB占用更多的磁盘空间。 - 恢复备份速度要慢。 - 每次读写都同步的话,有一定的性能压力。 - 存在个别Bug,造成恢复不能。 # 总结: ## 用哪个? 官方推荐两个都启用!!! ## 实战 配置文件如下(其他保持默认): ```ini # 开启RDB,并设置每小时备份一次(会关闭默认的其他配置) save 3600 1 # 文件位置(自定义) dir /usr/local/redis/ # 开启AOF appendonly yes ```
7
全部评论