美文网首页
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