一、 Redis 持久化(重点,经常面试)
Redis是一个内存数据库,为了保证数据的持久性,它提供了三种持久化方案:
RDB方式(默认)AOF方式- 混合持久化模式(4.0增加,5.0默认开启-当开启AOF时候,它也开启了)它是AOF的一个补充
1.1 RDB
RDB是Redis默认采用的持久化方式。
RDB方式是通过快照(snapshotting)完成的,当符合一定条件时Redis会自动将内存中的数据进行快照并持久化到硬盘
触发RDB快照的时机
-
符合指定配置的快照规则
-
执行save或bgsave命令 save主线程去快照 bgsave 调用异步线程去快照
主线程是单线程 4.0 I/O操作 已经有多线程概念
-
执行flushall 或flushdb
-
执行主从复制操作
设置快照规则
漏斗型
-
save 多少秒内 数据变了多少
-
save "" : 不使用RDB存储
-
save 900 1 : 表示15分钟(900秒钟)内至少1个键被更改则进行快照。
-
save 300 10 : 表示5分钟(300秒)内至少10个键被更改则进行快照。
-
save 60 10000 :表示1分钟内至少10000个键被更改则进行快照。
RDB快照的实现原理
快照过程
-
Redis调用系统中的fork函数复制一份当前进程的副本(子进程) -
父进程继续接收并处理客户端发来的命令,而子进程开始将内存中的数据写入硬盘中的临时文件。
-
当子进程写入完所有数据后会用该临时文件替换旧的
RDB文件,至此,一次快照操作完成。
fork 是操作系统的函数 linux/ uinx *nux ,作用是调用一个子进程,制作快照,生成RDB文件, 替换掉原来的RDB文件
注意事项
Redis在进行快照的过程中不会修改RDB文件,只有快照结束后才会将旧的文件替换成新的,也就是说任何时候RDB文件都是完整的。- 这就使得我们可以通过定时备份
RDB文件来实现Redis数据库的备份,RDB文件是经过压缩的二进制文件,占用的空间会小于内存中的数据,更加利于传输。
RDB优缺点
- 缺点:使用
RDB方式实现持久化,一旦Redis异常退出,就会丢失最后一次快照以后更改的所有数据。这个时候我们就需要根据具体的应用场景,通过组合设置自动快照条件的方式来将可能发生的数据损失控制在能够接受范围。如果数据相对来说比较重要,希望将损失降到最小,则可以使用AOF方式进行持久化 - 优点:
RDB可以最大化Redis的性能:父进程在保存RDB文件时唯一要做的就是fork出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无需执行任何磁盘I/O操作。同时这个也是一个缺点,如果数据集比较大的时候,fork可以能比较耗时,造成服务器在一段时间内停止处理客户端的请求;
1.2 AOF
AOF介绍
默认情况下Redis没有开启AOF(append only file)方式的持久化。
开启AOF持久化后,每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件,这一过程显然会降低Redis的性能,但大部分情况下这个影响是能够接受的,另外使用较快的硬盘可以提高AOF的性能。
redis.conf:
# 可以通过修改redis.conf配置文件中的appendonly参数开启
appendonly yes
# AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的。
dir ./
# 默认的文件名是appendonly.aof,可以通过appendfilename参数修改
appendfilename appendonly.aof
同步磁盘数据
Redis每次更改数据的时候, aof机制都会将命令记录到aof文件,但是实际上由于操作系统的缓存机制,数据并没有实时写入到硬盘,而是进入硬盘缓存。再通过硬盘缓存机制去刷新到保存到文件。
参数说明:
# 每次执行写入都会进行同步, 这个是最安全但是是效率比较低的方式
appendfsync always
# 每一秒执行(默认)
appendfsync everysec
# 不主动进行同步操作,由操作系统去执行,这个是最快但是最不安全的方式
appendfsync no
最开始的数据它是通过读取内存中的数据,转换成命令。后边的就是每次的更新指令,进行存储
AOF重写原理(优化AOF文件)
Redis可以在AOF文件体积变得过大时,自动地在后台对AOF进行重写。重写后的新AOF文件包含了恢复当前数据集所需的最小命令集合。
AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议(RESP)的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。
优化前
set name zhangsan
set name lisi
set name wangwu
优化后
set name wangwu
优化前
lpush list1 1 2 3
lpush list1 4 5 6
优化后
lpush list1 1 2 3 4 5 6
AOF进行优化时候,并不是读取原来的AOF文件 ,而是读取redis db 进行转化
如何选择RDB和AOF(4.0之前的还需要考虑)
内存数据库 rdb(redis database)+aof 数据不能丢
缓存服务器 rdb
不建议 只使用 aof (性能差)
恢复时: 先aof再rdb
1.3 混合持久化方式
Redis 4.0 之后新增的方式,混合持久化是结合了 RDB 和 AOF 的优点,在写入的时候,先把当前的数据以 RDB 的形式写入文件的开头,再将后续的操作命令以 AOF 的格式存入文件,这样既能保证 Redis 重启时的速度,又能减低数据丢失的风险。
RDB 和 AOF 持久化各有利弊,RDB 可能会导致一定时间内的数据丢失,而 AOF 由于文件较大则会影响 Redis 的启动速度,为了能同时拥有 RDB 和 AOF 的优点,Redis 4.0 之后新增了混合持久化的方式,因此我们在必须要进行持久化操作时,应该选择混合持久化的方式。
查询是否开启混合持久化可以使用 config get aof-use-rdb-preamble 命令,执行结果
127.0.0.1:6379> config get aof-use-rdb-preamble
1) "aof-use-rdb-preamble"
2) "yes"
其中 yes 表示已经开启混合持久化,no 表示关闭,Redis 5.0 默认值为 yes。如果是其他版本的 Redis 首先需要检查一下,是否已经开启了混合持久化,如果关闭的情况下,可以通过以下两种方式开启:
- 通过命令行开启
- 通过修改 Redis 配置文件开启
① 通过命令行开启
使用命令 config set aof-use-rdb-preamble yes
命令行设置配置的缺点是重启 Redis 服务之后,设置的配置就会失效。
② 通过修改 Redis 配置文件开启
在 Redis 的根路径下找到 redis.conf 文件,把配置文件中的 aof-use-rdb-preamble no 改为 aof-use-rdb-preamble yes
配置完成之后,需要重启 Redis 服务器,配置才能生效,但修改配置文件的方式,在每次重启 Redis 服务之后,配置信息不会丢失。
需要注意的是,在非必须进行持久化的业务中,可以关闭持久化,这样可以有效的提升 Redis 的运行速度,不会出现间歇性卡顿的困扰。
混合持久化 是RDB+指令
如果AOF文件过大时候,会重写:把当前数据已RDB格式保存,后续指令用aof