目录
方式一:RDB
方式二:AOF
AOF重写可能出现的问题及解决方案
方式三:RDB-AOF混合持久化
Redis持久化:Redis是基于内存数据库,宕机后和数据会消失,当Redis用作DB 时,DB数据要完整,所以一定要有一个完整的数据源文件,在系统启动时,从这个完整的数据源中将数据load到 Redis内存中,完成提供持久化机制。
redis持久化方式:RDB、AOF、RDB-AOF混合持久化
方式一:RDB
RDB:在指定的时间间隔内,形成当前数据集的时间点快照。将快照信息保存到磁盘的RDB文件中。
自动触发RDB:
在redis.conf中有如下配置,配置 save 参数即可自动触发rdb,一般RDB快照信息保存在dump.rdb文件中,文件名可以修改。
# Unless specified otherwise, by default Redis will save the DB:
429 # * After 3600 seconds (an hour) if at least 1 change was performed
430 # * After 300 seconds (5 minutes) if at least 100 changes were performed
431 # * After 60 seconds if at least 10000 changes were performed
432 #
433 # You can set these explicitly by uncommenting the following line.
434 #
435 # save 3600 1 300 100 60 10000#情况1:五秒内若有两次修改,生成rdb文件
#情况2:超过五秒,生成rdb文件
436 save 5 2
手动触发RDB:save 和 bgsave 命令
save:在主程序中执行会阻塞当前redis服务器,在执行save命令期间,不能执行其他命令,直到持久化工作完成。
bgsave:fork 出一个子进程,在后台异步进行快照操作,不会阻塞主进程。
RDB优势:
- RDB可以最大化redis的性能,父进程在保存RDB文件的时候唯一要做的就是fork出一个子进程,由子进程完成接下来的操作。
- RDB文件是经过压缩的二进制文件,占用空间很小,它保存了redis某个时间点的数据集,很适合做备份
- 适合大规模的数据恢复
- 按照业务定时备份
- 对数据的完整性和一致性要求不高
- RDB文件在内存中的加载速度要比AOF快得多
RDB劣势:
- 在一定时间间隔后做一次备份,如果redis在这段时间内宕机的话,这段时间的数据并没有保存快照,就会丢失从当前至最后一次保存快照期间的数据。设置save 5 2,如果五秒内没有两次修改,那要在五秒之后才生成dump.rdb文件,若是在这五秒内redis宕机的话,最多会丢失五秒内的数据。
- 内存数据的全量同步,如果数据量太大的话会导致I/O严重影响服务器的性能。
- RDB依赖与主进程的fork,在更大的数据集中,这可能会导致服务器请求的瞬间延迟,fork的时候内存中的数据被克隆了一份,会导致两倍的膨胀性,刚 fork 时,主进程和子进程共享内存,但是随着主进程需要处理写操作,主进程需要将修改的页面拷贝一份出来,然后进行修改。极端情况下,如果所有的页面都被修改,则此时的内存占用是原先的2倍。
哪些情况下会触发RDB?
- 配置文件中默认的save配置
- 手动触发
- 执行flushdb/flushall命令也会产生dump.rdb文件,只不过是空的
- 执行shutdown且没有开启AOF持久化
- 主从复制,主节点自动触发
方式二:AOF
AOF:以日志的形式来记录每个写操作,将每个redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件,完成数据的恢复。默认情况下,redis没有开启AOF(append only file),开启AOF功能需要设置配置:appendonly yes
AOF保存的是appendonly.aof文件
AOF持久化工作流程:命令追加、写入磁盘文件(文件写入和文件同步)
当服务器执行完一个写命令后,会将该命令以追加的方式写到服务器的aof_buf(aof缓冲区)的末尾,再将aof_buf中的数据写入到磁盘中的aof文件中(需要两步操作:文件写入和文件同步)。
文件写入和文件同步:操作系统为了提高性能,使用了页缓存机制(page cache),在将aof_buf中的数据写入到磁盘中时,并不是一步到位,而是先将aof_buf中的数据写入到page cache中,再由操作系统实现文件同步,将page chahe 中的数据同步到磁盘文件(aof文件)中。
AOF缓冲区三种写回策略:
always:每执行完一个写命令后立刻将该命令写入并同步到磁盘aof文件中
everysec:每秒写回,每个命令执行完,只是先把日志写到aof_buf中,每隔一秒(距离上一次同步间隔一秒)再将aof_buf中的内容写入并同步到磁盘aof文件中。
no:由操作系统控制文件的同步。即每个命令执行完,将日志写到aof缓冲区,再将aof_buf中的内容写入到page cache中,具体什么时候同步到磁盘文件中,由操作系统来决定。
AOF优点:
- 更好的保护数据不丢失,比RDB更可靠,设置不同的写回策略,默认是always。everysec和no的写回策略,最多也就丢失一秒钟的数据。
- 当AOF文件太大时,redis提供了AOF重写机制,减小AOF 文件的大小。
AOF缺点:
- 相同数据集,AOF文件一般比RDB文件大。
- 根据所使用的写回策略,AOF的速度可能慢于RDB。
AOF重写:
当AOF文件越来越大,使用AOF 文件来进行数据的还原所需的时间就越来越多,AOF重写就是用来减小AOF文件体积。redis生成新的aof文件代替旧的aof文件。
比如:有如下命令,set k1 1,set k1 2,set k1 3,set k1 4,这样最终的结果是k1 4 ,实际上只需要记录set k1 4就行,没必要记录前三条命令,AOF重写 就是启动AOF 文件内容压缩,只保留可以恢复数据集的最小指令集。
自动触发AOF 重写:
AOF重写默认配置:
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
同时满足上面两个配置项才会触发AOF重写:①根据上次重写后的AOF文件大小,判断当前AOF文件大小是否增长了一倍②当前AOF文件大小超过64mb
手动触发:
执行命令:bgrewriteaof
AOF重写可能出现的问题及解决方案
1、重写阻塞主进程
解决:使用子进程进行重写,
2、子进程重写的过程中,主进程仍然会有后续的写命令要记录日志,这样会导致最终重写后的新aof文件与旧的出现数据不一致问题。
解决:redis引入了AOF重写缓冲区,此缓冲区在fork出子进程后开始使用,当redis服务器执行完每一个写命令后,他会同时将命令追加到AOF重写缓冲区和AOF缓冲区。这样,当子进程完成重写工作后,通知主进程,主进程会将AOF重写缓冲区的新增的写命令追加到新的AOF文件中,然后用新的AOF文件代替旧的AOF文件就完成了AOF文件的重写。
3、若AOF重写缓冲区内容过多,导致主进程出现阻塞(AOF重写缓冲区的内容是由主进程追加到新AOF文件的)。
解决:在进行 AOF 后台重写时,Redis 会创建一组用于父子进程间通信的管道,同时会新增一个文件事件,该文件事件会将写入 AOF 重写缓冲区的内容通过该管道发送到子进程。在子进程重写结束后,子进程会通过该管道尽量从父进程读取更多的数据,每次等待可读取事件1ms,如果一直能读取到数据,则这个过程最多执行1000次,也就是1秒。如果连续20次没有读取到数据,则结束这个过程。
方式三:RDB-AOF混合持久化
结合RDB和AOF 两种持久化方式
结论:RDB做全量持久化,AOF做增量持久化
先使用RDB进行快照存储,时候使用AOF持久化记录所有写操作,当重写策略满足或是手动触发重写时,将最新的数据存储为新的RDB记录。这样的话,重启服务时会从RDB和AOF两部分恢复数据,既提高了数据完整新,又提高了恢复数据的性能。文章来源:https://www.toymoban.com/news/detail-565826.html
整体格式:[RDB file][AOF tail]文章来源地址https://www.toymoban.com/news/detail-565826.html
到了这里,关于Redis持久化(RDB和AOF)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!