docker. k8s小白学架构之路

redis持久化存储

2019-11-25  本文已影响0人  夜醉梦紅尘

redis有两种存储机制,RDB,AOF

RDB:将数据库的状态以快照形式写入磁盘且用二进制方式存储,相当于数据库的物理备份
AOF:将所有对数据库进行过写入的命令(及其参数)记录到 AOF 文件,以此达到记录数据库状态的目的,相当于数据库的逻辑备份

RDB

image.png

三种情况自动触发RDB

主动执行save命令
发生阻塞的情况
主动执行bgsave命令

3.自动触发条件
我们可以在配置文件里设置触发条件,以触发bgsave命令
配置文件中相关选项的默认值如下表:

语句格式:配置 seconds changes 含义

save 900 1
save 300 10
save 60 10000

释义:
每隔 900 秒检查一次,假如至少有 1 条数据改变,就生成新的 RDB 文件
每隔 300 秒检查一次,假如至少有 10 条数据改变,就生成新的 RDB 文件
每隔 60 秒检查一次,假如至少有 10000 条数据改变,就生成新的 RDB 文件
每次检查都会建立一个新的检查点,以便用于下次检查作为参考信息。

AOF

AOF 文件保存了 Redis 的数据库状态, 而文件里面包含的都是符合 Redis 通讯协议格式的命令文本。

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

AOF_FSYNC_NO :不保存。
AOF_FSYNC_EVERYSEC :每一秒钟保存一次。(生产中一般选这种)
AOF_FSYNC_ALWAYS :每执行一个命令保存一次

image.png

AOF还原数据的方式

1.创建一个不带网络连接的伪客户端(fake client)。
2.读取 AOF 所保存的文本,并根据内容还原出命令、命令的参数以及命令的个数
3.根据命令、命令的参数和命令的个数,使用伪客户端执行该命令。
4.执行 2 和 3 ,直到 AOF 文件中的所有命令执行完毕。
5.完成第 4 步之后, AOF 文件所保存的数据库就会被完整地还原出来。

注意, 因为 Redis 的命令只能在客户端的上下文中被执行, 而 AOF 还原时所使用的命令来自于 AOF 文件, 而不是网络, 所以程序使用了一个没有网络连接的伪客户端来执行命令。

当程序读入这个 AOF 文件时, 它首先执行 SELECT 0 命令(选择数据库) —— 这个 SELECT 命令是由 AOF 写入程序自动生成的, 它确保程序可以将数据还原到正确的数据库上。

注意:
为了避免对数据的完整性产生影响, 在服务器载入数据的过程中, 只有和数据库无关的订阅与发布功能可以正常使用, 其他命令一律返回错误。

AOF重写机制

我们为什么要进行AOF重写?
上面我们已经知道,aof是通过记录redis命令行的形式来记录数据,但随着时间的增长,这个文件会越来越大(就比如对同一个键重复赋值,列表的重复改变),

RPUSH list 1 2 3 4      // [1, 2, 3, 4]

RPOP list               // [1, 2, 3]

LPOP list               // [2, 3]

LPUSH list 1            // [1, 2, 3]

那我们的重写机制就是直接读取命令,然后用适当的命令来记录,就像上面的命令我们完全可以用一条命令来代替RPUSH 1 2 3

重写的步骤以及两种方式

for  遍历所有数据库:
      if  如果数据库为空:
             那么跳过这个数据库
      else:
            写入 SELECT 命令,用于切换数据库
            for  选择一个库后,遍历这个库的所有键
                   if 如果键带有过期时间,并且已经过期,那么跳过这个键
                   if 根据数据的类型,进行相关操作。

AOF 重写的两种实现方式

bgrewriteaof

特点:不需要重启服务,不便于统一管理

image.png
image.png

特点:需要重启服务,便于进行统一管理

aof_current_size 和 aof_base_size 可以通过命令 info persistence 查看到

image.png

对于上图有四个关键点补充一下:

在重写期间,由于主进程依然在响应命令,为了保证最终备份的完整性;因此它依然会写入旧的AOF file中,如果重写失败,能够保证数据不丢失。当然这个是可以通过配置来决定在重写期间是否进行主进程普通的 AOF 操作。
为了把重写期间响应的写入信息也写入到新的文件中,因此也会为子进程保留一个buf,防止新写的file丢失数据。
重写是直接把当前内存的数据生成对应命令,并不需要读取老的AOF文件进行分析、命令合并。
AOF文件直接采用的文本协议,主要是兼容性好、追加方便、可读性高可认为修改修复。

注意:无论是RDB还是AOF都是先写入一个临时文件,然后通过 rename 完成文件的替换工作。

RDB 和 AOF的区别

配置文件解析/etc/redis.conf

// 要想使用 AOF 的全部功能,需要设置为  yes
appendonly yes

// AOF 文件名
appendfilename "appendonly.aof"

// 平常普通的 AOF 的策略
appendfsync everysec


// 当执行 AOF 重写时,是否继续执行平常普通的 AOF 操作。
// 这里设置文件  yes , 表示不执行
// 因为假如,同时执行,两种操作都会对磁盘 I/O 进行访问,造成
// I/O 访问量过大,产生性能衰减
no-appendfsync-on-rewrite yes

// AOF 文件容量的增长率
auto-aof-rewrite-percentage 100

// AOF 文件的最低容量,就是当前文件的大小大于此值时,就会进行重写。当然这只是其中一个条件。
auto-aof-rewrite-min-size 64mb

也可进入redis查看配置

[root@s1 ~]# redis-cli
127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "no"
127.0.0.1:6379> config set appendonly yes
OK
127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "yes"

上一篇下一篇

猜你喜欢

热点阅读