redis-rdb

redis-rdb

起男 685 2020-12-09

redis-rdb

redis的读写都是在内存中的,所有它的性能较高,但在内存中的数据会随着服务器的重启而丢失,为了保证数据不丢失,我们需要将内存中的数据存储到硬盘,以便redis重启时能够从磁盘中恢复原有的数据,而整个过程就叫做redis持久化

redis持久化也是redis和memcached的主要区别之一,因为memcached不具备持久化功能

持久化的方式

  1. 快照方式(rdb,redis data base):将某一个时刻的内存数据,以二进制的方式写入磁盘
  2. 文件追加方式(aof,append only file):记录所有的操作命令,并以文本的形式追加到文件中
  3. 混合持久化方式:redis4.0之后新增的方式,混合持久化是结合了rdb和aop的优点,在写入的时候,先把当前的数据以rdb的形式写入文件的开头,再将后续的操作命令以aof的格式存入文件,这样既能保证redis重启的速度,又能减少数据丢失的风险

简介

rdb是将某一时刻的内存快照,以二进制的方式写入磁盘的过程

触发

手动触发

save命令

在客户端执行save命令,就会触发redis的持久化,但同时也使redis处于阻塞状态,直到rdb持久化完成,才会响应其它客户端发来的命令,所以在生产环境一定要慎用。

bgsave命令

bgsave(background save)既后台保存的意思,它和save命令最大的区别就是bgsave会fork一个子进程来执行持久化,整个过程中只有在fork子进程时有短暂的阻塞,当子进程被创建之后,redis的主进程就可以响应其它客户端的请求了,相对于给整主进程都阻塞的save命令来说,显然bgsave命令更适合我们使用。

自动触发

save m n

指在m秒内,如果有n个键发生改变,则触发持久化。

参数m和n可以在redis的配置文件中找到,例如save 60 1则表明在60秒内,至少有一个键发生改变,就会触发rdb持久化。

自动触发本质是redis通过判断,如果满足设置的触发条件,自动执行一次bgsave命令

注意:如果有多个save m n时,满足任意一个条件都会触发持久化

flushall

flushall命令用于清空redis数据库,当redis执行了flushall命令之后,则触发自动持久化,把rdb文件清空

主从同步触发

在redis主从复制中,当从节点执行全量复制操作时,主节点会执行bgsave命令,并将rdb文件发送给从节点,该过程会自动触发redis持久化

配置

save参数

它是用来配置触发rdb持久化条件的参数,满足保存条件时将会把数据持久化到硬盘

默认配置:

  • save 900 1:表示900秒内如果至少有1个key值变化,则把数据持久化到硬盘
  • save 300 10:表示300秒内如果至少有10个key值变化,则把数据持久化到硬盘
  • save 60 100000:表示60秒内如果至少有100000个key值变化,则把数据持久化到硬盘

rdbcompression参数

它的默认值是yes,表示开启rdb文件压缩

redis会采用lzf算法进行压缩

如果不想消耗cpu性能来进行文件压缩的话,可以设置为关闭此功能,这样的缺点是需要更多的磁盘空间来保存文件

rdbchedksum参数

它的默认值为yes,表示写入文件和读取文件时是否开启rdb文件检查,检查是否有损坏,如果在启动时发现损坏,则停止启动

查询

可以使用config get 参数名的方式查看当前配置的参数

设置

  • 手动修改redis配置文件
  • 使用命令:config set 参数名 参数值

注意:

手动修改redis配置文件的方式是全局生效的,即重启redis服务器设置参数也不会丢失,

而使用命令修改的方式,在redis重启之后就会丢失。

但手动修改redis配置文件,想要立刻生效需要重启redis服务器,

而兵力的方式则不需要重启redis服务

优缺点

优点

  • rdb的内容为二进制的数据,占用空间更小,更紧凑,更适合做为备份文件
  • rdb对灾难恢复非常有用,它是一个紧凑的文件,可以更快的传输到远程服务器进行redis服务恢复
  • rdb可以更大程度的提高redis的运行速度,因为每次持久化时redis主进程会fork一个子进程,进程数据持久化到磁盘,redis主进程并不会执行磁盘I/O等操作
  • 与aof格式的文件相比,rdb文件可以更快的重启

缺点

  • 因为rdb只能保存某个时间间隔的数据,如果中途redis服务被意外终止了,则会丢失一段时间内的redis数据
  • rdb需要经常fork才能使用子进程将其持久化在磁盘上。如果数据集很大,fork可能很耗时,并且如果数据集很大且cpu性能不佳,可能导致redis停止为客户端服务几毫秒甚至一秒