Redis持久化

HeJin大约 6 分钟数据库技术Redis

面试和工作,持久化是重点。

Redis是内存数据库,如果不能内存中的数据库状态保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会消失。所以Redis提供了持久化功能。

持久化之RDB

Redis DataBase

image-20201230170746412
image-20201230170746412

指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存中。

Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的。这就确保了极高的性能。如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式比AOF方式更加地高效。RDB地缺点是最后一次持久化后的数据可能丢失。我们默认的就是RDB方式 ,一般情况下不需要修改这个配置。

有时候在生产环境我们会将这个文件备份。

rdb保存的文件是 dump.rdb

image-20201230162501461
image-20201230162501461

测试

image-20201230162944684
image-20201230162944684

触发机制

  • save的规则满足的情况下,会自动触发rdb规则。
  • 执行flushdb(第一次会)或者flushall命令。
  • 退出redis,也会产生rdb文件。

备份就会自动生成一个dump.rdb文件。

image-20201230164326860
image-20201230164326860

如何恢复rdb文件

  • 只需要将rdb文件放在我们redis启动目录下就可以了。redis启动的时候会自动检查dump.rdb文件。恢复其中的数据。

  • 查看需要存放的位置

    127.0.0.1:6379> config get dir
    1) "dir"
    2) "/usr/local/bin"
    

几乎默认的配置就够用了,但是还是需要我们去学习。

优点

  • 适合大规模的数据恢复。
  • 对数据的完整性要求不高。

缺点

  • 需要一定的时间间隔进行操作。如果redis意外宕机了,最后一次修改的数据就没了。
  • fork进程的时候,会占用一定的内存空间。

持久化之AOF

AOF Append Only File

image-20201231141225524
image-20201231141225524

在主从复制中,RDB就是备用的。从机上面。将我们的所有命令都记录下来,恢复的时候就把这个文件全部再执行一遍。

以日志的形式来记录每个写操作,将Redis执行过的所有指令记录下来(读操作不记录)。只允许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据。换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。

aof保存的文件是 appendonly.aof

APPEND ONLY MODE

image-20201231130300533
image-20201231130300533

默认是不开启的,需要手动进行配置。改为yes就开启了。

# Please check http://redis.io/topics/persistence for more information.

appendonly yes # 默认是不开启的,需要手动进行配置。改为yes就开启了

# The name of the append only file (default: "appendonly.aof")

appendfilename "appendonly.aof"

# appendfsync always
appendfsync everysec
# appendfsync no

重启,redis就可以生效了。

image-20201231130815841
image-20201231130815841

破环appendonly.aof文件。redis就启动不了。

[root@iz2ze88y8n1wfg7e488dbkz bin]#redis-server hconfig/redis.conf 
[root@iz2ze88y8n1wfg7e488dbkz bin]#redis-cli -p 6379
Could not connect to Redis at 127.0.0.1:6379: Connection refused
not connected> exit
[root@iz2ze88y8n1wfg7e488dbkz bin]#ps -ef|grep redis
root     29533 29183  0 13:12 pts/1    00:00:00 grep --color=auto redis

修复appendonly.aof文件

image-20201231131346481
image-20201231131346481
[root@iz2ze88y8n1wfg7e488dbkz bin]#redis-check-aof --fix appendonly.aof 
0x              a8: Expected prefix '*', got: 'j'
AOF analyzed: size=185, ok_up_to=168, diff=17
This will shrink the AOF from 185 bytes, with 17 bytes, to 168 bytes
Continue? [y/N]: y
Successfully truncated AOF

然后重启redis,成功,数据也恢复了。

[root@iz2ze88y8n1wfg7e488dbkz bin]#redis-server hconfig/redis.conf 
[root@iz2ze88y8n1wfg7e488dbkz bin]#redis-cli -p 6379
127.0.0.1:6379> ping
(error) NOAUTH Authentication required.
127.0.0.1:6379> auth ******
OK
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> keys *
1) "k3"
2) "k5"
3) "k1"
4) "k4"
5) "k2"
127.0.0.1:6379> 

重写规则

AOF默认是文件的无限制追加,文件就会越来越大。

image-20201231132631397
image-20201231132631397

如果AOF文件大于64mb,太大了。就会fork一个新的进程来将我们的文件进行重写。

# Please check http://redis.io/topics/persistence for more information.

appendonly yes # 默认是不开启的,需要手动进行配置。改为yes就开启了

# The name of the append only file (default: "appendonly.aof")

appendfilename "appendonly.aof"

# appendfsync always
appendfsync everysec
# appendfsync no

优点

  • 每一次修改都同步,文件的完整性会更加好。
  • 每秒同步一次,可能会丢失1秒的数据。
  • 从不同步,效率是最高的。

缺点

  • 相对于数据文件来说,AOF远远大于RDB,修复的速度也比RDB慢。
  • AOF运行效率也要比RDB慢,所以我们Redis默认的配置就是RDB持久化。

扩展

  • RDB持久化方式能够在指定的时间间隔内对你的数据进行快照存储。
  • AOF下持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据。AOF命令以Redis协议追加保存每次写的操作到文件末尾。Redis还能对AOF文件进行后台重写,使得AOF的体积不至于过大。
  • 只做缓存。入股你希望你的数据在服务器运行的时候存在,也可以不使用任何持久化。
  • 同时开启两种方式
    • 在这种情况下,当Redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。
    • RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件,那要不要只使用AOF呢?作者建议不要,因为RDB更适合用户备份数据库(AOF在不断变化不好备份)。快速重启,而且不会有AOF潜在的bug,留着作为一个万一的手段。
  • 性能建议
    • 因为RDB文件只用作后备用途,建议只在Slave上持久RDB文件,而且只要15分钟备份一次就够了。只保留save 900 1这条规则。
    • 如果Enale AOF,好处是在最恶劣情况下也只会丢失不超过2秒数据,启动脚本较简单只load自己的AOF文件就可以了。代价一是带来了持续的IO,二是AOF rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite,AOF重写的基础大小默认64MB太小了。可以设到5G以上。默认超过原大小100%大小重写可以改到适当的数据
    • 如果不Enable AOF,仅靠Master-Slave Replication实现高可用性也可以,能省掉一大笔IO,也减少了rewrite是带来的系统波动。代价是如果Master/Slave同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个Master/Slave中的RDB文件,载入较新的那个。微博就是这种架构。