Redis的RDB方式

Posted 一颗心

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis的RDB方式相关的知识,希望对你有一定的参考价值。

今天我们来聊一聊Redis持久化的方式RDB。

我们知道Redis相对于传统的缓存技术最大的特点之一就是支持数据的持久化。Redis会定期对内存数据快照写入磁盘,当内存数据丢失(如服务重启、宕机导致)时,可以加载磁盘中的数据快速恢复到内存。

RDB即Redis Database,其持久化方式是将内存数据以二进制的方式存储到磁盘上,避免服务器意外宕机时仍然可以从磁盘找回数据。存储的文件默认为dump.rdb。

RDB持久化操作过程

  • Redis fork一个子进程
  • 子进程拥有主进程的内存数据副本,子进程将内存副本数据写入临时的rdb文件中
  • 子进程写入完成后,用新的rdb文件替换掉原有的rdb文件,同时删除旧的文件

其实子进程被fork出来后,会同时拷贝一份主进程的内存引用,而非完整的内存副本集。这就利用了操作的系统的写时复制功能,只有在父进程的内存发生修改时才会真实的复制一份内存给子进程使用,而且复制是以页为单位进行的。这样就大大减少了内存的使用空间,提升了效率。
整个持久化过程中只有fork过程会发送阻塞,子进程rdb文件的存储过程是异步的。

RDB是如何触发的
Redis提供命令来手动触发rdb操作:save和bgsave。两者的区别是save是同步操作,执行过程中会阻塞Redis对外服务。尤其在大数据量的save时,会导致服务较长时间的服务中断。而bgsave则是fork一个子进程来异步处理持久化,持久化的过程完全不影响Redis服务,生产上也是常用。

Redis提供了参数来配置RDB的自动触发,定义 m秒内n次键值发生改动。例如

save 900 1
save 300 10
save 60 10000

60秒内出现10000次键值变更
300秒内出现10次键值改变
900秒内1次键值改变
表示当满足上述三种情况的任一种时,都将触发一次bgsave操作。

另外有一点补充说明一下,在执行save或bgsave操作时,如果发现系统有正在执行的save操作,而且未超过2秒

自动存储的实现细节
redisServer维护了自动触发的配置信息,同时维护了一个dirty计数器和上次执行完save的时间。

struct redisServer {
    // 自动保存的配置信息
    struct saveparam *saveparams; 
    
    long dirty;//修改计数器
    time_t lastsave;//上一次执行save的时间
    // ...
};
struct saveparam {
    time_t seconds;//秒数
    int changes;//修改次数
};
  • dirty计数器 redis每执行一次写入操作时,dirty值+1,
  • lastsave 记录最近一次成功执行完save/bgsave操作的时间(Unix时间戳

serverCron是redis中的周期执行函数,默认100ms执行一次(可通过redis.config修改执行频率),其中一个检查就是查看是否满足了RDB自动执行条件。对于单个 save m n来说,只有当同时满足以下两个条件时,才会触发一次持久化

now - lastsave > m
dirty >= n

这里的n次变更是指服务端的变更,而不是执行客户端请求的写入命令操作数。即,当执行一条 sadd myset a b c, dirty的值会增加3。

RDB相关的配置

  • save m n m秒内发生n次变更则执行一次bgsave。出现save配置后,redis会启用rdb持久化
  • dir /usr/local/redis-5.0.7/data 快照文件路径
  • dbfilename dump.rdb 快照文件名,默认为dump.rdb。生产环境一般会加入端口信息,命名为:dupm.6379.rdb
  • stop-writes-on-bgsave-error yes 当bgsave执行出现异常时,是否停止接收客户端的写入请求。
  • rdbcompression yes 启用rdb文件压缩。启用压缩后会节省磁盘空间,但增加CPU的消耗资源
  • rdbchecksum yes 启用rdb文件一致性校验

使用RDB恢复数据

  1. 获取快照文件目录。可以使用 config get dir 获取快照目录
  2. 停止redis服务。 执行shudown命令
  3. 将快照文件dump.rdb拷贝到config get dir输出的目录下
  4. 重新启动redis服务
    值得说明的一点是当使用rdb文件启动加载内存数据时,会造成服务的阻塞,直到完全加载完成才能对外提供服务。因此在服务启动时常用aof方式来恢复内存数据。

RDB持久化方式的优劣

  • rdb文件保存的非常紧凑的二进制文件,占用的磁盘空间小,内存恢复速度快
  • 便于数据快照的备份,可以根据需要定时备份rdb文件即可

缺点

  • RDB持久化是有一定频率的,而且不适合高频率持久化,这样当意外停机时,可能出现较长时间段内的数据丢失
  • 持久化时虽然子进程可以异步进行,但每次都是全量数据的IO刷盘,造成IO负载加重,当数据量很大时可能出现IO瓶颈
  • fork过程也会造成阻塞,而且fork的时间和内存的大小有关,过大的内存fork时导致较长时间的阻塞

以上是关于Redis的RDB方式的主要内容,如果未能解决你的问题,请参考以下文章

Redis数据持久化方式RDB和AOF的区别

08_Redis持久化——RDB方式

Redis篇Redis持久化方式AOF和RDB

理解与权衡Redis的两种持久化方式(RDB-AOF)

redis持久化的方式

Redis持久化,RDB和AOF