企业级Redis开发运维从入门到实践 (16)— RDB

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zx711166/article/details/82858772

什么是RDB

  • Redis通过一条命令将内存中的数据完整的保存一个创建的二进制的RDB文件(快照)。
  • 当需要对Redis进行恢复,将加载RDB文件,恢复某时某刻的数据。
  • RDB文件还是一个复制媒介,可以使用RDB实现主从复制。

在这里插入图片描述

何时、怎么样复盘

  1. 当Redis重新启动时,会从本地磁盘加载之前持久化的文件。
  2. 当恢复完成之后,再受理后续的请求操作。当恢复完成之后,再受理后续的请求操作。

触发机制 — 主要三种方式

save(同步)
  1. 客户端发送save命令;
  2. redis将创建一个RDB文件。
    在这里插入图片描述
redis> save
OK

由于save是一个同步命令,在做大数据量的快照时会造成Redis的阻塞,其他的客户端的请求造成阻塞。
在这里插入图片描述

文件策略
在这里插入图片描述

复杂度
在这里插入图片描述

bgsave(异步)
  1. 客户端发送bgsave命令;
  2. Redis使用linux的fork()函数生成一个Redis的子线程;
  3. 由子线程去创建RDB文件;
  4. 当创建并存储数据成功将向Redis主线程返回保存成功。
    在这里插入图片描述
redis> bgsave
Backgroud saving started

fork()一般都是非常快的,但是当fork()非常慢时,将会阻塞Redis主线程。
在这里插入图片描述

文件策略
在这里插入图片描述

save与bgsave比较
命令 save bgsave
IO类型 同步 异步
阻塞? 是(阻塞发生在fork)
复杂度 O(n) O(n)
优点 不会消耗额外内存 不阻塞客户端命令
缺点 阻塞客户端命令 需要fork,消耗内存
自动生成RDB

从下往上看,如果在60s中改变了10000条数据,会自动做RDB的生成,剩下以此类推。
缺点在于无法控制RDB文件的生成频率。
在这里插入图片描述
除此之外的RDB配置

# 设置RDB文件名字
dbfilename dump.rdb

# 文件存储路径(默认存在当前目录)
dir ./

# bgsave时发生错误停止写入(默认是yes)
stop-writes-on-bgsave-error yes

# RDB文件是否采用压缩格式(默认是yes)
rdbcompression yes

# RDB文件是否校验和的检验(默认是yes)
rdbchecksum yes

最佳配置

# 自动save(关闭自动save配置)
# save 900 1
# save 300 10
# save 60 10000

# 设置RDB文件名字
# 设置对应的端口号,在充分引用多核的情况下避免文件冲突覆盖
dbfilename dump-${port}.rdb

# 文件存储路径
# 选择一个比较大的硬盘路径、或者分盘
dir /bigdiskpath

# bgsave时发生错误停止写入(默认是yes)
stop-writes-on-bgsave-error yes

# RDB文件是否采用压缩格式(默认是yes)
rdbcompression yes

# RDB文件是否校验和的检验(默认是yes)
rdbchecksum yes

触发机制 — 不容忽视方式

  1. 全量复制,在没有选择使用save、bgsave、自动生成中任何一个策略时,主从之间进行复制时也将会生成RDB文件。
  2. debug reload(debug级别的重启,不需要将内存清空的重启)时也会生成RDB文件。
  3. shutdown(关闭)时存在shut save参数,负责执行RDB文件的生成。

验证

save阻塞
  1. 执行 redis-cli 进入客户端(准备好5百万条数据)。
  2. 执行 set hello world 写入数据
  3. 执行 save 进行同步快照。
  4. 立即执行 get hello 获取 key 值是 hello 的数据,此时将可以看到获取数据被阻塞。
  5. 根据设置的RDB文件路径去查看是否生成RDB文件。
redis> dbsize
(integer) 5000000

redis> info memory
# Memory
used_memory:948306016
used_memory_human:904.38M
used_memory_rss:1031897088
used_memory_peak:981827104
used_memory_peak_human:936.34M
used_memory_lua:36864
mem_fragmentation_ratio:1.09
mem_allocator:libc

# 在save前进入redis-cli,并且set hello world写入数据
redis> save
OK
(8.94s)


[root@localhost ~]# redis-cli
redis> set hello world
OK

# 在save后立即执行get hello
redis> get hello
"world"
(6.43s)

redis>
bgsave
  1. 执行 bgsave 命令,然后再执行 get hello,将发现没有被阻塞。
  2. bgsave还在执行过程中,执行 ps -ef | grep redis- | grep -v “redis-cli” | grep -v “grep” 命令,可以看到 redis-rdb-bgsave *:6379 这个子线程,bgsave 执行完后子线程被收回。
  3. 执行 tail -f 6379.log 查看日志,在 bgsave 成功后可以看到 Background saving terminated with success。
  4. bgsave还在执行过程中,立即在RDB文件路径下执行 ll 命令查看,可以看到 temp-36985.rdb 临时文件,bgsave 执行完后替换旧的 RDB 文件。
# 执行bgsave
redis> bgsave
Background saving started
[root@localhost ~]# redis-cli

# 在bgsave后立即执行get hello
redis> get hello
"world"

redis> exit

# 在执行bgsave后,立即查看是否产生redis-rdb-bgsave子线程
[root@localhost ~]#  ps -ef | grep redis- | grep -v "redis-cli" | grep -v "grep"
501 36775         1 0 10:22下午 ??     0:17.91 redis-server *:6379
501 36954 36775 0 10:28下午 ??     0:02.81 redis-rdb-bgsave *:6379

# 查看日志bgsave是否执行,以及执行情况
[root@localhost ~]#  tail -f 6379.log
...
36775:M  06  Oct 22:25:59.485  *  DB saved on disk
36775:M  06  Oct 22:27:52.955  *  Background saving started by pid 36910
36910:C  06  Oct 22:28:02.647  *  DB saved on disk
36775:M  06  Oct 22:28:02.779  *  Background saving terminated with success
...

# 在执行bgsave后,立即在RDB文件路径下执行 ll 命令查看
[root@localhost ~]#  ll
total 1126064
-rw-r--r--   1  carlosfu    staff      1.9K     10   6   22:29   6379.log
-rw-r--r--   1  carlosfu    staff     459M    10   6    22:28   dump-6379.rdb
-rw-r--r--   1  carlosfu    staff       90M    10   6    22:29   temp-36985.rdb
自动生成RDB
  1. 配置文件总开启自动save设置,设置 save 60 5(60s内执行5次修改将自动生成快照)。
  2. 关闭 Redis 服务,执行 redis-cli 命令查看客户端,发现服务已经停止。
  3. 执行 redis-server redis-6379.conf 重启服务,执行 redis-cli 命令连接客户端,执行 dbsize 数据量,返回是0条。
  4. 在一分钟内执行 set 命令5次以上。
  5. 执行 exit 退出客户端,执行 tail -f 6379.log 命令查看日志文件,可以看到 5 changes in 60 seconds. Saving…,此时说明已经触发了自动快照机制。
# 关闭redis服务
[root@localhost ~]#  redis-cli shutdown

# 连接redis客户端
[root@localhost ~]#  redis-cli
Could not connect to Redis at 127.0.0.1:6379: Connection refused not connected>exit

# 重启redis服务
[root@localhost ~]#  redis-server redis-6379.conf

# 连接redis客户端
[root@localhost ~]#  redis-cli

# 查看数据量
redis> dbsize
(integer) 0

# 执行一分钟内修改五次
redis> set hello world
OK
redis> set a b
OK
redis> set c d
OK
redis> set e f
OK
redis> set g h
OK
redis> set i j
OK
redis> exit

# 查看日志文件,可以看到 5 changes in 60 seconds. Saving...
[root@localhost ~]#  tail -f 6379.log
...
37500:M  06  Oct 22:25:59.485  *  5 changes in 60 seconds. Saving...
37500:M  06  Oct 22:27:52.955  *  Background saving started by pid 37536
37536:C  06  Oct 22:28:02.647  *  DB saved on disk
37500:M  06  Oct 22:28:02.779  *  Background saving terminated with success
...

RDB总结

  1. RDB是Redis内存到硬盘的快照,用于持久化。
  2. save通常会阻塞Redis。
  3. bgsave不会阻塞Redis,但是会fork新进程。
  4. save自动配置满足任一条件会被执行。
  5. 有些触发机制不容忽视。

猜你喜欢

转载自blog.csdn.net/zx711166/article/details/82858772