redis持久化存储
redis有两种存储机制,RDB,AOF
RDB:将数据库的状态以快照形式写入磁盘且用二进制方式存储,相当于数据库的物理备份
AOF:将所有对数据库进行过写入的命令(及其参数)记录到 AOF 文件,以此达到记录数据库状态的目的,相当于数据库的逻辑备份
RDB

三种情况自动触发RDB



3.自动触发条件
我们可以在配置文件里设置触发条件,以触发bgsave
命令
配置文件中相关选项的默认值如下表:
语句格式:配置
seconds
changes
含义
save 900 1
save 300 10
save 60 10000
释义:
每隔 900 秒检查一次,假如至少有 1 条数据改变,就生成新的 RDB 文件
每隔 300 秒检查一次,假如至少有 10 条数据改变,就生成新的 RDB 文件
每隔 60 秒检查一次,假如至少有 10000 条数据改变,就生成新的 RDB 文件
每次检查都会建立一个新的检查点,以便用于下次检查作为参考信息。
AOF

AOF 保存的模式
Redis 目前支持三种 AOF 保存模式,它们分别是:
AOF_FSYNC_NO :不保存。
AOF_FSYNC_EVERYSEC :每一秒钟保存一次。(生产中一般选这种)
AOF_FSYNC_ALWAYS :每执行一个命令保存一次

AOF还原数据的方式
1.创建一个不带网络连接的伪客户端(fake client)。
2.读取 AOF 所保存的文本,并根据内容还原出命令、命令的参数以及命令的个数
3.根据命令、命令的参数和命令的个数,使用伪客户端执行该命令。
4.执行 2 和 3 ,直到 AOF 文件中的所有命令执行完毕。
5.完成第 4 步之后, AOF 文件所保存的数据库就会被完整地还原出来。
注意, 因为 Redis 的命令只能在客户端的上下文中被执行, 而 AOF 还原时所使用的命令来自于 AOF 文件, 而不是网络, 所以程序使用了一个没有网络连接的伪客户端来执行命令。
当程序读入这个 AOF 文件时, 它首先执行 SELECT 0 命令(选择数据库) —— 这个 SELECT 命令是由 AOF 写入程序自动生成的, 它确保程序可以将数据还原到正确的数据库上。
注意:
为了避免对数据的完整性产生影响, 在服务器载入数据的过程中, 只有和数据库无关的订阅与发布功能可以正常使用, 其他命令一律返回错误。
AOF重写机制
我们为什么要进行AOF重写?
上面我们已经知道,aof是通过记录redis命令行的形式来记录数据,但随着时间的增长,这个文件会越来越大(就比如对同一个键重复赋值,列表的重复改变),
RPUSH list 1 2 3 4 // [1, 2, 3, 4]
RPOP list // [1, 2, 3]
LPOP list // [2, 3]
LPUSH list 1 // [1, 2, 3]
那我们的重写机制就是直接读取命令,然后用适当的命令来记录,就像上面的命令我们完全可以用一条命令来代替RPUSH 1 2 3
重写的步骤以及两种方式
for 遍历所有数据库:
if 如果数据库为空:
那么跳过这个数据库
else:
写入 SELECT 命令,用于切换数据库
for 选择一个库后,遍历这个库的所有键
if 如果键带有过期时间,并且已经过期,那么跳过这个键
if 根据数据的类型,进行相关操作。
AOF 重写的两种实现方式

特点:不需要重启服务,不便于统一管理


特点:需要重启服务,便于进行统一管理
aof_current_size 和 aof_base_size 可以通过命令 info persistence 查看到

对于上图有四个关键点补充一下:
在重写期间,由于主进程依然在响应命令,为了保证最终备份的完整性;因此它依然会写入旧的AOF file中,如果重写失败,能够保证数据不丢失。当然这个是可以通过配置来决定在重写期间是否进行主进程普通的 AOF 操作。
为了把重写期间响应的写入信息也写入到新的文件中,因此也会为子进程保留一个buf,防止新写的file丢失数据。
重写是直接把当前内存的数据生成对应命令,并不需要读取老的AOF文件进行分析、命令合并。
AOF文件直接采用的文本协议,主要是兼容性好、追加方便、可读性高可认为修改修复。
注意:无论是RDB还是AOF都是先写入一个临时文件,然后通过 rename 完成文件的替换工作。

配置文件解析/etc/redis.conf
// 要想使用 AOF 的全部功能,需要设置为 yes
appendonly yes
// AOF 文件名
appendfilename "appendonly.aof"
// 平常普通的 AOF 的策略
appendfsync everysec
// 当执行 AOF 重写时,是否继续执行平常普通的 AOF 操作。
// 这里设置文件 yes , 表示不执行
// 因为假如,同时执行,两种操作都会对磁盘 I/O 进行访问,造成
// I/O 访问量过大,产生性能衰减
no-appendfsync-on-rewrite yes
// AOF 文件容量的增长率
auto-aof-rewrite-percentage 100
// AOF 文件的最低容量,就是当前文件的大小大于此值时,就会进行重写。当然这只是其中一个条件。
auto-aof-rewrite-min-size 64mb
也可进入redis查看配置
[root@s1 ~]# redis-cli
127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "no"
127.0.0.1:6379> config set appendonly yes
OK
127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "yes"