0. 前言
redis作为内存数据库,为什么要持久化?
redis的数据储存到内存里,大部分情景下作为缓存,在快速高效的优点下,也无可避免的会存在特殊情况(断电)下,数据丢失的问题。数据一旦丢失,面临缓存雪崩;在没有redis缓存的情况下,大量请求直接去关系型数据库里查询,数据库就会挂掉。
redis的持久化,顾名思义,将数据保存在磁盘里。目前分为两种持久化机制:RDB (Redis DataBase)和 AOF (Append Only File)。
用自己的服务器,来试验各种功能吧,一天不到三毛钱
【腾讯云】云产品限时秒杀,爆款1核2G云服务器,首年99元
【阿里云】云产品限时秒杀,爆款1核2G云服务器,首年96元
1. RDB(Redis DataBase)
RDB 将数据库的快照(snapshot)以二进制的方式保存到磁盘中。
1.1. 两种手动触发命令
save:阻塞式,同步保存操作,将所有数据保存。
因为会阻塞服务器,不适用正在提供服务的情况,适用于关机维护等。
bgsave:非阻塞式,fork出子进程,客户端可以通过 LASTSAVE 命令查看相关信息,判断 BGSAVE 命令是否执行成功。比save应用场景广泛的多。
1.2. 配置文件自动触发
打开conf文件
282 ################################ SNAPSHOTTING ################################
283 #
284 # Save the DB on disk:
285 #
286 # save <seconds> <changes>
287 #
288 # Will save the DB if both the given number of seconds and the given
289 # number of write operations against the DB occurred.
290 #
291 # In the example below the behaviour will be to save:
292 # after 900 sec (15 min) if at least 1 key changed
293 # after 300 sec (5 min) if at least 10 keys changed
294 # after 60 sec if at least 10000 keys changed
295 #
296 # Note: you can disable saving completely by commenting out all "save" lines.
297 #
298 # It is also possible to remove all the previously configured save
299 # points by adding a save directive with a single empty string argument
300 # like in the following example:
301 #
302 # save "" (不开启自动存储)
303
304 save 900 1 (900s 1条指令)
305 save 300 10 (300s 10条指令)
306 save 60 10000 (60s 10000条指令)
...
339 dbfilename dump.rdb (文件名称)
...
362 dir ./ (dump文件地址)
save <seconds> <changes>
虽然是save,其实是bgsave,非阻塞式保存,会fork出子线程- 参数:每过多少秒,多少个变化,满足其中一个条件就保存
save ""
不开启自动存储- 会将数据dump到rdb文件,在配置文件中配置快照路径,快照名称,存储快照规则。
- 新文件会覆盖旧文件,只会有一个dump文件,如果需要有多个文件(各个时间),需要手动存储。
- 在执行快照命令时,会等待上一个快照完成
redis-cli SHUTDOWN
这种方式是一种安全退出模式,会在退出时生成一份快照
1.3. 优点和缺点
- 优点:存储的是数据文件,宕机恢复快,bgsave是fork的子进程,对性能影响小,可以保留redis内存数据库的优点
- 缺点:丢失数据量较大,只会保存到最近一次备份时间点的数据。
2. AOF(Append Only File)
AOF以日志形式追加每个写操作。将所有执行过的写指令记录下来。
AOF因为是采用文件追加机制,文件会越来越大,RDB的形式恢复时内存时不会溢出的,因为快照的文件是和redis内存数据一致的,但是AOF因为是操作指令,很有可能AOF文件过大
AOF会有一个重写机制,把过期的,重复的,没用的都丢掉,减少磁盘占用量。
2.1. 配置AOF
打开conf
1060 appendonly yes (开启aof)
1064 appendfilename "appendonly.aof" (文件名)
1089 # appendfsync always (每次写入一条数据,就将数据写到磁盘)
1090 appendfsync everysec (每秒将os cache的数据fsync到磁盘)
1091 # appendfsync no (不主动执行,等到os cache自己刷到磁盘)
所有的配置项在配置文件中都有详细的注解
- redis每次接收到一条写命令,就会写入日志文件中,当然是先写入os cache的,然后每隔一定时间再fsync一下
- 即使AOF和RDB都开启了,redis重启的时候,也是优先通过AOF进行数据恢复的,因为aof数据比较完整
- AOF记录的是指令,如果不小心
flushall
命令删除时,且没有rewrite还没发生,可以把AOF文件copy出来,删除此条指令,再放回去,就可以通过恢复机制恢复。
2.2. rewiter重写
- 指令
bgrewiteraof
- 配置文件
1131 auto-aof-rewrite-percentage 100 (AOF文件增长率)
1132 auto-aof-rewrite-min-size 64mb (当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时重写)
- redis4.0以前AOF:删除抵消命令 合并重复的命令 4.0以后:先rdb,再增量
- 触发机制:当前大小>auto-aof-rewrite-min-size&&比例增长>auto-aof-rewrite-min-size
2.3. 优点和缺点
优点:
1.丢失数据量少
2.flushall
命令执行后,只要还没有rewirte,那么可以copy AOF文件,删除flushall命令即可恢复
缺点:
1.AOF文件大
2.AOF开启后,性能降低,QPS会低
3.恢复数据比较慢,需要执行指令
3. RDB与AOF相结合
RDB与AOF对比
RDB | AOF | |
---|---|---|
丢失数据大小 | 两次快照的数据都会丢失 | 根据配置最多是一次oscache数据,最少是一条数据 |
恢复数据速度 | 快(load全量数据) | 慢(需要执行指令) |
备份数据大小 | 每次都是全量 | 所有指令合计,有可能是指数倍(有rewiter之后,备份数据会减少) |
性能 | 非阻塞式保存,fork出子进程 | 性能降低 |
rdb和aof结合:重写的时候先把rdb文件先重写,然后把aof文件追加到重写的文件中,速度较快