redis持久化

redis持久化

redis提供了两种不同的持久化方式:RDB(redis database)和AOF(append only file)

RDB

RDB是redis默认采用支持持久化的方式,通过快照(snapshotting)实现持久化

触发条件

当满足一定条件时,RDB将对内存中的所有数据生成快照,并存放到硬盘中,默认存放在当前执行redis服务的根目录的dump.rdb中。

1.配置文件

RDB相关的配置通常在redis.conf中标识有SNAPSHOTTING注释的模块下,我们可以在该配置文件中设置触发快照生成的情况:

save <seconds>  <changes>

save 3600 1     当3600秒内有1个key被修改

save 300  100   当300秒内有100个key被修改

save 60   10000 当60秒内有10000个key被修改

save ""         禁用快照,不将数据同步到快照文件中

其他相关的配置说明:

stop-writes-on-bgsave-error yes 当后台最后一次保存出错,停止redis的写操作。

rdbcompression yes              当进行持久化时,是否对数据使用LZF算法进行压缩。

rdbchecksum yes                 在存储快照后,是否使用CRC64算法进行数据校验。

dbfilename dump.rdb             指定生成的快照文件名为dump.rdb。

dir ./                          存储快照文件的路径,./表示当前路径,可以在进入redis服务后通过config get dir查看。

2.执行save、bgsave、flushall、shutdown命令

save和bgsave命令这两个命令都是针对RDB持久化的,只要执行这两个命令中的其中一个都会将内存中的数据以RDB持久化的形式进行保存到磁盘上,不管你的redis服务中没有没开启RDB持久化。

save命令是让redis仅有的一个主进程来完成工作,此时redis处于堵塞状态不再响应其他客户端请求,需谨慎使用。

bgsavg命令执行后,会立刻返回OK,Redis会fork一个子进程,原来的redis主进程继续执行后续操作,新fork的子进程负责将数据保存到磁盘,然后退出。在fork子进程过程中redis主进程是堵塞的,不能响应客户端请求。redis自动快照就是使用bgsave完成的。

flushall用于清空数据库,当使用该命令清空数据时,redis也会对快照文件进行清空,就会触发bgsave

shutdown:redis在关闭之前为了防止数据丢失,会将所有数据全部保存下来,以便下次启动快速启动

3.从节点SYNC

redis主从复制中,从节点执行全量复制操作,主节点会执行bgsave命令,并将rdb文件发送给从节点

工作方式

在这里插入图片描述

  • redis主进程收到命令并判断是否在执行bgrewriteaof(AOF文件重写过程),如果此时正好在执行则bgsave直接返回,不fork子进程,如果没有执行,进入下一个阶段

  • 主进程调用fork方法创建子进程,在创建过程中redis主进程堵塞,不能响应客户端请求。

  • 子进程创建完成后,bgsave命令返回"Background saving started",此时redis可以正常响应客户端请求。

  • 子进程根据主进程的内存副本创建临时快照文件,当快照完成以后对原快照文件进行替换。

  • 子进程发送信号给redis主进程完成快照操作,主进程更新统计信息,子进程退出。

AOF

在AOF模式下,redis会将每一个收到的写命令(包括flushall命令)都通过write函数追加到文件appendonly.aof的末尾,当 Redis 重新启时, 程序就可以通过重新执行 AOF 文件中的命令来达到重建数据集的目的。

工作方式

redis将每一条写命令以redis通讯协议的方式添加至缓冲区aof_buf,在大量写请求的场景可以利用缓冲区暂存一部分命令,根据appendfsync配置的策略一次性写入磁盘,这样可以减少磁盘的I/O,提高性能。

触发条件

默认情况下redis并没有开启AOF,AOF相关的的配置一般都在在redis.conf中注释为APPEND ONLY MODE的模块里:

appendonly no 默认,如果要开启AOF,需要将no改为yes

appendfsync指定了redis进行aof持久化的时机:

appendfsync everysec  默认
  • always:每次收到写命令就立即fsync方法强制写入磁盘,性能最低,但是最能保证数据的完整性,不推荐使用

  • everysec:使用fsync每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐

  • no: 不使用fsync方法同步,而是交给操作系统write函数去执行同步操作,性能最好,不能保证数据的完整性。linux大约30s刷一次缓冲。这种情况,缓冲区数据同步不可控,在大量的写操作下,aof_buf缓存区堆积会越来越严重,一旦redis出现故障,数据会丢失

日志重写

随的时间推移aof文件越来越大,当aof文件大小超过所设定的阈值时,redis会启动aof文件的内容压缩,只保留可以恢复数据的最小指令集。

举个例子,如果你对一个计数器调用了 100 次 INCR , 那么仅仅是为了保存这个计数器的当前值, AOF 文件就需要使用 100 条记录(entry)。然而在实际上, 只使用一条 SET 命令已经足以保存计数器的当前值了, 其余 99 条记录实际上都是多余的。

重写时,重复或者无效的命令不写入文件、过期的数据不再写入文件、多条命令合并写入(当多个命令能合并一条命令时候会对其优化合并作为一个命令写入 如:rpush list1 a rpush list b 合并为"rpush list1 a b")

重写触发

可以使用命令bgrewriteaof手动重写,也可以在redis.conf中配置的自动重写:

auto-aof-rewrite-min-size 64mb    最小重写值,当aof文件大于设置值才可能重写

auto-aof-rewrite-percentage 100   当前aof文件大小和上一次重写时的增长率

以上默认配置:当aof文件大小超过上次重写后大小的100%(2倍)且文件大于64mb时触发

重写过程

在这里插入图片描述

aof文件重写过程与rdb快照basave工作过程类似,都是通过fork子进程,由子进程完成响应的操作,同样的在fork子进程简短的时间内,redis是堵塞的。

  • 开始bgrewriteaof,判断当前有没有bgsave命令/bgrewriteaof在执行,有等这些命令执行完在执行。

  • 主进程fork出子进程,这个极短的过程中redis是堵塞的。

  • 主进程fork完子进程继续接受客户端请求,所有写命令依然写入aof文件缓冲区并根据appendfsync策略同步到磁盘,保证原有aof文件完整和正确。由于fork的子进程仅仅只共享主进程fork时的内存,因此redis采用重写缓冲区机制保存fork之后的客户端的写请求,防止新的aof文件生成期间丢失这部分数据。此时,客户端的写请求不仅仅写入原来aof_buf缓冲,还写入重写缓冲区。

  • 子进程通过内存快照,按照命令重写策略写入到新的aof文件

    • 子进程写完新的aof文件后,向主进程发信号,父进程更新统计信息

    • 主进程把aof_rewirte_buf中的数据写入到新的aof文件(避免写文件数据丢失)

  • 使用新的aof文件覆盖旧的aof文件,标志aof重写完成

RDB与AOF比较

RDB优点:

rdb是一个非常紧凑的文件,体积小,传输速度快,适合灾难恢复。

rdb可以最大化redis性能,父进程在保存rdb文件时只需fork子进程,子进程就会进行保存操作,父进程无需执行任何磁盘I/O操作。

rdb在恢复大数据集速度比aof快。

RDB缺点:

rdb是快照过程,无法完成保存所有数据,特别在数据量大的时候,发生故障丢失的数据更多。

当redis数据量大,rdb需要对数据进行完成拷贝并生成快照文件,fork子进程会消化cpu,数据量越大,耗时越多。

rdb文件是特定的格式,阅读性差,因格式固定,可能会存在不兼容情况

AOF优点:

数据更完整,秒级数据丢失(取决于fsync策略设置)

兼容性好,aof文件是明文,基于reids通讯协议而形成的命令追加方式,阅读性好

AOF缺点:

数据文件体积较大,即使有重写机制,在相同的数据集,aof文件比rdb大

aof速度比rdb慢,数据量大的时候,恢复速度也比rdb慢

aof由于要频繁将命令同步到文件中,对性能的影响也比rdb大,但这种影响可接受

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值