redis有几种持久化机制?

Redis是一种高级key-value数据库,数据存储在内存中,速度很快是优势,但是紧接着带来的则是数据变化瞬息万变,数据该如何保存呢?这就是今日总结的Redis持久化机制。

文章目录

  • 一、何为持久化?
  • 二、RDB(snapshot)
    • (1)自动触发
    • (2)手动触发-save命令
    • (3)手动触发-bgsave命令
    • (4)save VS bgsave
  • 三、AOF(append-only file)
    • (1)开启AOF持久化
    • (2)查看aof文件
    • (3) 文件写入与保存
    • (4)AOF保存模式
    • (5)保存模式对性能和安全性的影响
    • (6)AOF重写
  • 四、RDB VS AOF
  • 五、混合持久化

一、何为持久化?

正常redis数据是保存在内存中的,若遇到redis宕机或者需要重启等场景,数据就会丢失,所以需要将数据存储,将数据备份到磁盘的过程就叫做redis持久化。

redis安装完成之后,所有的配置都是在redis.conf文件中,里面保存了RDB和AOF两种持久化机制的各种配置。

二、RDB(snapshot)

全称redis database,在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,保存在名字为dump.rdb的二进制文件中。它恢复时 直接将快照文件直接读到内存里;

  • 如何开启?

(1)自动触发

1、在redis.conf配置文件中,搜索关键字save 则会看到RDB的持久化方式,如下图:
redis有几种持久化机制?_第1张图片

如上图则就是RDB触发的机制,默认值是如上三种情况:

触发条件 说明
save 900 a 如果900秒内至少1个key发生变化(CUD),则重写rdb文件
save 300 10 如果300秒内至少10个key发生变化(CUD),则重写rdb文件
save 60 10000 如果60秒内至少10000个key发生变化(CUD),则重写rdb文件

若不想开启,则直接把几个注释掉即可。

除了自动触发,也可以选择手动触发的方式

(2)手动触发-save命令

直接执行save命令,则保存成功。每次执行命令都会将所有的redis内存快照到一个新的rdb文件里,覆盖原有的rdb快照文件。默认的是bgsave方式,异步操作。

# huoyajing @ huoyajingdeMBP in /usr/local/redis-6.0.15 [9:49:44] C:127
$ redis-cli
127.0.0.1:6379> save
OK

看RDB的更新时间,如图:
redis有几种持久化机制?_第2张图片
在这里插入图片描述

(3)手动触发-bgsave命令

COW机制
Copy-On-Write顾名思义,在生成快照的同时,依旧可以正常的处理写命令。
进行rdb文件生成的并非是主进程,而是由主进程fork生成的子进程完成的。主进程依旧是执行数据操作命令。

# huoyajing @ huoyajingdeMBP in /usr/local/redis-6.0.15 [10:26:47] C:127
$ redis-cli
127.0.0.1:6379> bgsave
Background saving started

redis有几种持久化机制?_第3张图片

(4)save VS bgsave

命令 save bgsave
IO类型 同步 异步
是否阻塞redis其他命令 yes no(在生成子进程调用fork函数会有短暂阻塞)
复杂度 O(n) O(n)
优点 不会消耗额外内存 不阻塞客户端命令
缺点 阻塞客户端命令 需要fork子进程,消耗内存
  • 如何关闭?
    直接注释掉对应的save命令即可。

三、AOF(append-only file)

RDB,快照功能并不是非常耐久,如果Redis宕机,服务器肯定就会丢失最近写入且未保存到快照中的数据,所以则多了一种新的持久化方式,记录到appendonly.aof中(先写入os cache,定期写到磁盘)

(1)开启AOF持久化

redis.conf文件中,appendonly yes/no 修改为yes即可。
重启redis,则会发现aof文件。
PS:若重启了依旧未发现,则执行如下两个命令:

# huoyajing @ huoyajingdeMBP in /usr/local/redis-6.0.15 [11:43:03]
$ redis-cli config set appendonly yes
OK
# huoyajing @ huoyajingdeMBP in /usr/local/redis-6.0.15 [11:43:20]
$ redis-cli config set save ""
OK

redis有几种持久化机制?_第4张图片

(2)查看aof文件

我们执行一个set huo 111的命令,然后查看aof文件:

# huoyajing @ huoyajingdeMBP in /usr/local/redis-6.0.15 [11:47:09]
$ redis-cli
127.0.0.1:6379> set huo 111
OK
# huoyajing @ huoyajingdeMBP in /usr/local/redis-6.0.15 [11:47:29]
$ cat appendonly.aof
*3
$3
set
$3
huo
$3
111

这是一种resp协议格式数据,*后边代表的数字表示该命令有多少参数;
$后边代表的数字代表这个参数有几个字符。

(3) 文件写入与保存

每当服务器常规任务函数被执行、 或者事件处理器被执行时, aof.c/flushAppendOnlyFile 函数都会被调用, 这个函数执行以下两个工作:

  • WRITE:根据条件,将 aof_buf 中的缓存写入到 AOF 文件。
  • SAVE:根据条件,调用 fsync 或 fdatasync 函数,将 AOF 文件保存到磁盘中。

两个步骤都需要根据一定的条件来执行, 而这些条件由 AOF 所使用的保存模式来决定, 以下小节就来介绍 AOF 所使用的三种保存模式, 以及在这些模式下, 步骤 WRITE 和 SAVE 的调用条件。

(4)AOF保存模式

Redis 目前支持三种 AOF 保存模式,它们分别是:

命令 说明
appendfsync always 有新命令就执行一次,非常慢但是也非常安全
appendfsync everysec 每秒fsync一次,足够快,一般情况下不超过两秒钟的数据
appendfsync no 从不fsync,将数据交由操作系统处理,更快,但是更不安全,不采纳

可以通过配置来决定多久fsync到磁盘一次,配置命令依旧再redis.conf中。

# appendfsync always
appendfsync everysec
# appendfsync no

(5)保存模式对性能和安全性的影响

模式 对服务器主进程的阻塞情况
AOF_FSYNC_NO 写入和保存都由主进程执行,两个操作都会阻塞主进程
AOF_FSYNC_EVERYSEC 写入操作由主进程执行,阻塞主进程。保存操作由子线程执行,不直接阻塞主进程,但保存操作完成的快慢会影响写入操作的阻塞时长。
AOF_FSYNC_ALWAYS 写入和保存都由主进程执行,两个操作都会阻塞主进程

(6)AOF重写

AOF 文件通过同步 Redis 服务器所执行的命令, 从而实现了数据库状态的记录, 但是, 这种同步方式会造成一个问题: 随着运行时间的流逝, AOF 文件会变得越来越大。

想象有这样一种场景,比如string的原则性操作,incr

# huoyajing @ huoyajingdeMBP in /usr/local/redis-6.0.15 [11:59:45]
$ redis-cli
127.0.0.1:6379> incr huocount
(integer) 1
127.0.0.1:6379> incr huocount
(integer) 2
127.0.0.1:6379> incr huocount
(integer) 3
127.0.0.1:6379> incr huocount
(integer) 4
127.0.0.1:6379> incr huocount
(integer) 5
# huoyajing @ huoyajingdeMBP in /usr/local/redis-6.0.15 [12:00:22]
$ cat appendonly.aof
$3
huo
$3
111
*2
$4
incr
$8
huocount
*2
$4
incr
$8
huocount
*2
$4
incr
$8
huocount
*2
$4
incr
$8
huocount
*2
$4
incr
$8
huocount

最快的方式不就是设置huocount=5就OK了。也有对应的配置来控制AOF自动重写频率。

#aof文件至少要达到64才会自动重写,文件太小恢复速度本来就很快,重写的意义不大
auto-aof-rewrite-percentage 100
#aof文件自上一次重写后文件大小增长了100%则再次触发重写
auto-aof-rewrite-min-size 64mb

重写进程依旧是主进程fork出一个子进程来执行,不会对redis这种正常命令有太多影响。文件太小也就无所谓重写不重写了,自动重写需要条件符合,所以也肯定就有手动重写的命令: bgrewriteaof
PS :以下会讲述混合模式,我是6.0redis演示,混合模式默认是开启的,所以当我执行了重写命令,aof文件会变为二进制模式,无法再cat查看

四、RDB VS AOF

命令 RDB AOF
启动优先级
体积
恢复速度
数据安全性 容易丢失数据 根据策略决定

五、混合持久化

各自了解了两种持久化的优缺点,发现混合使用效果更好。Redis 4.0则采用了混合持久化方式。

aof-use-rdb-preamble yes/no

混合持久化AOF文件结构如下:
redis有几种持久化机制?_第5张图片
新操作的命令则会继续以AOF的样式在aof文件中存储,之前的则以RDB的二进制文件存储着。

# huoyajing @ huoyajingdeMBP in /usr/local/redis-6.0.15 [14:15:50]
$ cat appendonly.aof
REDIS0009�	redis-ver6.0.15�
redis-bits�@�ctime�w�!aused-mem�po�
                                   aof-preamble���huo�huocount��g�r�ÁwJ*2
*3
$3
set
$6
huohuo
$3
232

你可能感兴趣的:(分布式,redis,redis持久化,RDB,AOF,AOF启动)