美文网首页
redis(四) 持久化

redis(四) 持久化

作者: 万事万物 | 来源:发表于2021-06-16 12:56 被阅读0次

前言

Redis主要是工作在内存中。内存本身就不是一个持久化设备,断电后数据会清空。所以Redis在工作过程中,如果发生了意外停电事故,如何尽可能减少数据丢失?那么就需要持久化,redis中的共有两种持久化方式 RDB和AOF。

Redis 持久化

redis 提供了不同级别的持久化方式:

  1. RDB持久化方式能够在指定的时间间隔能对数据进行快照存储。
  2. AOF持久化方式记录每次对服务器写操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾,redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大。
  3. 如果只希望数据在服务器运行的时候存在,也可以不使用任何持久化方式。
  4. 可以同时开启两种持久化方式,在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。

RDB[默认:开启]

方式:每隔一段时间将redis内存中的数据落盘保存
优点:
1.RDB保存的是直接的数据,占用的存储空间相对于AOF比较少。
2.RDB因为保存的是数据,恢复起来比AOF更快,一般用于容灾恢复(占用空间比较小,可以方便上传到云服务器,即使本地磁盘损坏,也不会对数据产生影响)。
缺点:
由于RDB是每隔一段时间才进行数据落盘,这样可能造成最后最后一段时间内的数据丢失。
RDB有两种持久化方式:

  1. 主动备份(命令的方式)
  • FLUSHALL:清空所有数据后再保存,所以并没有真正的保存数据。
127.0.0.1:6379> set k1 22
OK
127.0.0.1:6379> FLUSHALL
OK
4540:M 16 Jun 11:31:09.131 * Background saving started by pid 4709
4709:C 16 Jun 11:31:09.137 * DB saved on disk
4709:C 16 Jun 11:31:09.137 * RDB: 6 MB of memory used by copy-on-write
4540:M 16 Jun 11:31:09.240 * Background saving terminated with success
4540:M 16 Jun 11:31:15.463 * DB saved on disk

重新启动

127.0.0.1:6379> keys *
(empty list or set)
  • SHUTDOWN SAVE
127.0.0.1:6379> set k1 333
OK
127.0.0.1:6379> SHUTDOWN SAVE
4764:M 16 Jun 11:38:03.872 # User requested shutdown...
4764:M 16 Jun 11:38:03.872 * Saving the final RDB snapshot before exiting.
4764:M 16 Jun 11:38:03.872 * DB saved on disk
4764:M 16 Jun 11:38:03.872 * Removing the pid file.
4764:M 16 Jun 11:38:03.872 # Redis is now ready to exit, bye bye..

重新启动

[admin@hadoop102 redis]$ redis-server redis.conf
[admin@hadoop102 ~]$ redis-cli -a 123321
127.0.0.1:6379> get k1
"333"

既然有 SHUTDOWN SAVE 就会有 SHUTDOWN NOSAVE

  • SAVE
127.0.0.1:6379> set k2 222
OK
127.0.0.1:6379> save
OK
  • BGSAVE
127.0.0.1:6379> set k3 333
OK
127.0.0.1:6379> bgsave
Background saving started

总结
共有四种命令能够手动触发 RDB 。

  • FLUSHALL [\color{red}{禁用}]
  • SHUTDOWN SAVE 或者 SHUTDOWN [\color{red}{禁用}]
  • SAVE
  • BGSAVE

RDB持久化原理
会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。
SAVE 与 BGSAVE 区别
SAVE :复制的进程独享资源,专门进行持久化,会占用主进程资源,此时主进程无法进行客户端的读写。
BGSAVE:复制的进程与主进程共享资源,主进程可以正常完成客户端的读写。
简单说明:SAVE 是同步操作,BGSAVE是异步操作。

  1. 被动备份(配置文件)
    save time change [在time时间范围内操作change次就自动触发RDB持久化。]
#   save ""
save 900 1 # 表示 900 秒内 只要有1次对key的写操作就会触发持久化
save 300 10 # 表示 300 秒内 只要有10次对key的写操作就会触发持久化
save 60 10000 # 表示 60 秒内 只要有10000 次对key的写操作就会触发持久化
... # 可以自定义规则,格式:save time change

save "" :表示关闭RDB持久化
RDB 相关文件配置:

是否在备份出错时,继续接受写操作[如果用户开启了RDB快照功能,那么在redis持久化数据到磁盘时如果出现失败,默认情况下,redis会停止接受所有的写请求]

stop-writes-on-bgsave-error yes

是否开启文件压缩[如果开启压缩,那么redis会采用LZF算法进行压缩]

rdbcompression yes

是否进行数据校验[redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗]

rdbchecksum yes

RDB 持久化文件名:

dbfilename dump.rdb

RDB快照保存的目录[必须是一个目录,不能是文件名。最好改为固定目录。默认为./代表执行redis-server命令时的当前目录!]

dir ./

AOF[默认:关闭]

方式:将写操作指令以日志的形式保存
如何开启AOF?
打开配置文件,修改配置

# 是否开启 aof 持久化 no/yes
appendonly no
# aof持久化文件 保存到当前文件。
appendfilename "appendonly.aof"

AOF持久化触发条件

# appendfsync always 
appendfsync everysec
# appendfsync no

appendfsync always:将每一个写操作进行持久化,
好处:最多只丢失一条指令数据
坏处:频繁的操作会带来额外的资源开销。
appendfsync everysec:按秒进行持久化
好处:保证数据安全的情况下,一定程度上减少资源开销。
坏处:若服务器出现问题,依旧会丢失一秒的数据。
appendfsync no:不持久化,交给系统来完成

优势

  1. AOF相对于RDB而言丢失数据更少,
  2. 恢复起来更加容易

缺点

  1. 由于AOF 保存的是操作指令,相对于RDB而已,需要更多存储空间。

AOF使用

  1. 插入三条数据
127.0.0.1:6379> set k22 v22
OK
127.0.0.1:6379> set k33 v33
OK
127.0.0.1:6379> set k44 v44
OK
  1. 查看 appendonly.aof 文件
[admin@hadoop102 redis]$ cat appendonly.aof 
*2
$6
SELECT
$1
0
*3
$3
set
$3
k22
$3
v22
*3
$3
set
$3
k33
$3
v33
*3
$3
set
$3
k44
$3
v44

选择的是0号库

$6 #表示 SELECT 长度
SELECT
$1 # 表示 0 的长度
0

对key 设值

$3 # set 的字符长度
set
$3 # k22 字符的长度
k22
$3 # v22 字符的长度
v22

其他的意思都差不多。
由此可以更加明显的看出AOF 存储的是写的指令,对于读操作是不会持久化化的。如 get ...
读操作

127.0.0.1:6379> mget k22 k33 k44
1) "v22"
2) "v33"
3) "v44"

重新查看 appendonly.aof 文件

[admin@hadoop102 redis]$ cat appendonly.aof 
*2
$6
SELECT
$1
0
*3
$3
set
$3
k22
$3
v22
*3
$3
set
$3
k33
$3
v33
*3
$3
set
$3
k44
$3
v44

由于RDB进行了压缩,所以没办法查看(及时关闭了压缩,也看不了)。

[admin@hadoop102 redis]$ cat dump.rdb 
REDIS0007   redis-ver3.2.5
redis-bits󿿀򳨭eused-memHþ񁩳k2k1ÿЇTU©[atguigu@hadoop102 redis]$ XshellXshellXshell

既然AOF 存储的是命令,那么我们去修改一下可以吗?
比如:k22 对应 v22 ,修改 appendonly.aof 改成了v22update看看效果。
修改appendonly.aof,

[admin@hadoop102 redis]$ cat appendonly.aof |grep v22
v22update

重启redis服务
重新连接redis服务:get k22

127.0.0.1:6379> get k22
"v22update"

有什么用呢?试想一下万一不小心执行了FLUSHALL指令,可以直接将FLUSHALL相关的操作在appendonly.aof 中删除就可以完成数据恢复了。可以试一下
清除数据

127.0.0.1:6379> keys *
1) "k44"
2) "k33"
3) "k22"
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> keys *
(empty list or set)

cat appendonly.aof

*2
$6
SELECT
$1
0
*3
$3
set
$3
k22
$9
v22update
*3
$3
set
$3
k33
$3
v33
*3
$3
set
$3
k44
$3
v44
*2
$6
SELECT
$1
0
*1
$8
flushall

删除这一段,即可完成数据恢复

*2
$6
SELECT
$1
0
*1
$8
flushall

重启并重新连接

127.0.0.1:6379> keys *
1) "k33"
2) "k44"
3) "k22"

关于AOF与RDB优缺点https://www.jianshu.com/p/257d520003e9
最后
如果AOF文件中出现了残余命令,会导致服务器无法重启。此时需要借助redis-check-aof工具来修复!
命令: redis-check-aof --fix 文件

相关文章

网友评论

      本文标题:redis(四) 持久化

      本文链接:https://www.haomeiwen.com/subject/cgdxyltx.html