版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zx711166/article/details/82858772
什么是RDB
- Redis通过一条命令将内存中的数据完整的保存一个创建的二进制的RDB文件(快照)。
- 当需要对Redis进行恢复,将加载RDB文件,恢复某时某刻的数据。
- RDB文件还是一个复制媒介,可以使用RDB实现主从复制。
何时、怎么样复盘
- 当Redis重新启动时,会从本地磁盘加载之前持久化的文件。
- 当恢复完成之后,再受理后续的请求操作。当恢复完成之后,再受理后续的请求操作。
触发机制 — 主要三种方式
save(同步)
- 客户端发送save命令;
- redis将创建一个RDB文件。
redis> save
OK
由于save是一个同步命令,在做大数据量的快照时会造成Redis的阻塞,其他的客户端的请求造成阻塞。
文件策略
复杂度
bgsave(异步)
- 客户端发送bgsave命令;
- Redis使用linux的fork()函数生成一个Redis的子线程;
- 由子线程去创建RDB文件;
- 当创建并存储数据成功将向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
触发机制 — 不容忽视方式
- 全量复制,在没有选择使用save、bgsave、自动生成中任何一个策略时,主从之间进行复制时也将会生成RDB文件。
- debug reload(debug级别的重启,不需要将内存清空的重启)时也会生成RDB文件。
- shutdown(关闭)时存在shut save参数,负责执行RDB文件的生成。
验证
save阻塞
- 执行 redis-cli 进入客户端(准备好5百万条数据)。
- 执行 set hello world 写入数据
- 执行 save 进行同步快照。
- 立即执行 get hello 获取 key 值是 hello 的数据,此时将可以看到获取数据被阻塞。
- 根据设置的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
- 执行 bgsave 命令,然后再执行 get hello,将发现没有被阻塞。
- bgsave还在执行过程中,执行 ps -ef | grep redis- | grep -v “redis-cli” | grep -v “grep” 命令,可以看到 redis-rdb-bgsave *:6379 这个子线程,bgsave 执行完后子线程被收回。
- 执行 tail -f 6379.log 查看日志,在 bgsave 成功后可以看到 Background saving terminated with success。
- 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
- 配置文件总开启自动save设置,设置 save 60 5(60s内执行5次修改将自动生成快照)。
- 关闭 Redis 服务,执行 redis-cli 命令查看客户端,发现服务已经停止。
- 执行 redis-server redis-6379.conf 重启服务,执行 redis-cli 命令连接客户端,执行 dbsize 数据量,返回是0条。
- 在一分钟内执行 set 命令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总结
- RDB是Redis内存到硬盘的快照,用于持久化。
- save通常会阻塞Redis。
- bgsave不会阻塞Redis,但是会fork新进程。
- save自动配置满足任一条件会被执行。
- 有些触发机制不容忽视。