九又四分之三站台

0%

Redis持久化

简介

Redis是内存型据库,它的数据是存在内存中的,但是如果只能存在内存中的话,当服务器进程出现问题,那么内存中的数据就会丢失。为了解决这个问题,Redis提供了持久化功能。Redis持久化分为RDB持久化和AOF持久化两种。

RDB

创建RDB文件命令

RDB持久化生成的RDB文件是一个二进制文件,创建RDB文件有两个命令,一个是SAVE,另一个是BGSAVE。

  • SAVE命令会导致Redis服务器阻塞,阻塞期间不能执行其它命令
  • BGSAVE命令会fork一个子进程,由子进程创建RDB文件,父进程可以继续处理其它命令

BGSAVE时服务器状态

BGSAVE命令的保存工作是有子进程执行的,所有服务器还可以执行其它命令,但是在BGSAVE执行期间,BGSAVE、SAVE和BGREWRITEAOF三个命令的方式会和平常不用。

  1. 在BGSAVE执行期间,服务器会拒绝SAVE命令,因为同时进行的话两个进程会同时进行rdbSave调用,产生竞争
  2. 在BGSAVE执行期间,新的BGSAVE会被拒绝,因为同时执行也会竞争
  3. BGSAVE执行时,BGREWRITEAOF会被延迟到BGSAVE执行结束; BGREWRITEAOF执行时,BGSAVE会被拒绝。 两个命令无竞争,但是都是写入操作会影响性能

用户通过可配置多个保存条件,只要满足一个,BGSAVE就会执行

1
2
3
4
5
save 900 1           #在900秒(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发BGSAVE命令创建快照。

save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生变化,Redis就会自动触发BGSAVE命令创建快照。

save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,Redis就会自动触发BGSAVE命令创建快照。

AOF

简介

除了RDB持久化以为,Redis还提供了AOF(append only file)持久化。RDB持久化保存的是数据库中的键值对记录,AOF持久化则是通过保存Redis服务器执行的写命令,如set这类的操作。

被写入的AOF文件的命令都是以Redis的命令请求协议格式保存的,即文本格式。

持久化方式

1
2
3
appendfsync always    #每次有数据修改发生时都会写入AOF文件,这样会严重降低Redis的速度
appendfsync everysec #每秒钟同步一次,显示地将多个写命令同步到硬盘
appendfsync no #让操作系统决定何时进行同步

AOF重写

AOF持久化是通过被执行的写命令来保存数据库状态的,这样依赖AOF文件会越来越大,使用AOF文件来还原数据库的时间也更长。所以Redis提供了AOF重写来生成新的体积更小的AOF文件替换掉旧文件。

AOF的重写主要是对写操作的合并优化,举个例子,比如 set key这个操作接连进行了十次,那么在AOF文件中会记录十条语句,而在AOF重写后就只会记录保存最终状态的一条语句(不是最后一条语句)。

AOF后台重写

AOF重写会调用aof_write函数进行写操作,由于Redis是单线程的在此期间服务器无法处理其他命令。 所以Redis的重写是在子进程中进行,使用子进程而不是线程是为了避免使用锁的情况下保证数据安全性。

不过使用子进程还有另一个问题需要解决,在AOF后台重写的过程中,可能会有新的写操作进行,这样会导致重写后的AOF文件保存的数据库状态与当前状态不一致。为了解决这个问题,Redis设置了AOF重写缓冲区,当有写命令执行完后,会把这个写命令同事发送给AOF缓冲区和AOF重写缓冲区。