Redis持久化策略

Redis内存数据库

单机Redis默认有16个数据库,名字就是编号0到15,用redis-cli进入时默认用0号数据库。可以自己切换数据库,当前在哪个数据库会直接显示在命令行。如下:

1
2
3
4
5
6
127.0.0.1:6379> select 1 -- 切换到1号数据库
OK
127.0.0.1:6379[1]> -- 编号显示[1],当前在1号数据库
127.0.0.1:6379[1]> select 0 -- 切换到0号数据库
OK
127.0.0.1:6379> -- 回到0号

数据库之间时完全隔离的,但也可以用一个命令同时清空所有数据库的数据(不推荐)。

集群模式的Redis,每个Redis服务器只有一个数据库。

Redis所有数据基本上都存在内存中,所以读写的速度很快。对比一下,Mysql的数据存在硬盘中,如果用的是 MyISAM 存储引擎,每次都要从硬盘中取数据。【如果是 InnoDB 引擎,会先从缓存中取数据,比 MyISAM 效率更高

Redis是内存数据库,所有数据保存在内存中,所以读写效率高。内存数据在计算机断电后不保存。对比一下,Mysql的数据存在硬盘中,如果用的是MyISAM存储引擎,每次都要从硬盘中取数据。

Redis持久化就是把内存数据保存到硬盘中,机器断电后也不会丢失,用于故障恢复。

Redis提供了两种持久化策略:RDB和AOF。默认使用RDB。

内存、缓存、磁盘、硬盘
硬盘就是磁盘,电脑中的“本地磁盘C”“本地磁盘D”就是硬盘的分区。
内存是硬盘和CPU沟通的桥梁,计算机运行程序时,必须将磁盘中的内容加载到内存中,不加载是不能运行程序的。在内存中有一部分数据存的是磁盘的缓存,这样做可以加速磁盘访问速度。内存在计算机断电后不保存数据。
缓存种类有一级、二级、三级缓存,作用是CPU要读取一个数据时,首先从缓存中查找,缓存没有CPU再从内存查找。
另外,虚拟内存,是指把磁盘中的一部分作为假想的内存使用。

持久化策略

RDB

RDB策略是,把当前时间,数据库中所有数据保存在文件中,重启Redis时会自动加载这个文件,恢复数据。RDB是默认的持久化方式。

存储数据的文件是二进制文件,文件名默认为 dump.rdb。文件过大时,可以设置是否压缩存储。

实现方法:

  1. save命令
  2. bgsave命令
  3. 配置自动保存

save 和 bgsave 的区别是,save 是占用主进程来保存,即保存期间Redis服务器不能处理其他请求,导致阻塞。bgsave 是调用操作系统方法生成一个子进程,子进程负责保存,主进程不阻塞(只有在生成子进程时阻塞)。

PS: Redis在Linux系统中调用fork()函数生成子进程,该函数的作用是创建一个与主进程基本相同的子进程。Windows系统中类似函数是createProcess()。

通过在Redis配置文件中添加配置save N M,实现“当N秒内至少有M个KEY被改动,就触发bgsave保存”的功能。因为是bgsave,所以不会阻塞主进程。

AOF

AOF策略是,把所有写命令保存在文件中,重启Redis时会自动加载这个文件,逐条执行文件中的命令,恢复数据。

存储命令的文件不是二进制文件,是可以直接打开读的,文件名默认为 appendonly.aof。

PS: 当rdb和aof文件同时存在时,若Redis配置文件中设置开启了AOF,重启时只加载aof文件。仅当设置AOF关闭时,重启时才会加载rdb文件。

在Redis配置文件中添加appendonly yes,就开启了AOF持久化。

AOF持久化流程:

  1. 所有的写命令都会追加到AOF缓冲区中
  2. 使用3种不同的策略将AOF缓冲区中的命令写到aof文件中

3种不同的策略分别是:

  1. appendfsync always
    每输入一条写命令,就把这条命令写入文件
  2. appendfsync everysec
    每秒种执行,这这一秒内增加的写命令写入文件
  3. appendfsync no
    由操作系统决定何时写入文件,不可控

注意,Redis把命令从缓冲区写到文件中时,是同步的。所以如果是用always策略,性能会很低,一般使用everysec策略。

由于AOF文件一般会很大,因此可以在配置文件中,配置当aof文件大小达到某个阈值时,开始AOF文件重写。重写时,是调用操作系统方法生成一个子进程,子进程负责重写,主进程不阻塞。子进程复制原AOF文件进行重写,完毕后通知主进程。重写过程中,新增的命令除了追加到AOF缓冲区,还会追加到AOF重写缓冲区,AOF缓冲区中的命令在AOF策略调度时写入原AOF文件,当子进程通知重写完毕后,主进程把AOF重写缓冲区的命令写到AOF缓冲区,并用新文件替换旧文件,那些在重写过程中新增的命令,会在下一次AOF策略调度时写入新的aof文件。

重写后的aof文件会变小,但产生的数据不变。例如下面两条命令:

1
2
3
4
127.0.0.1:6379> set cys ccc -- 增
OK
127.0.0.1:6379> del cys -- 删
(integer) 1

结果相当于没有新增任何key,因此重写时就可以删除原aof文件中的这两天命令。

优缺点

RDB和AOF相比,优势在于,rdb文件一般较小,因为直接存储数据,所以恢复较快。劣势在于,在子进程持久化的过程中,主进程新增的数据不会保存到文件,若此时Redis挂掉会造成一段时间内的数据丢失。

AOF和RDB相比,优势在于,aof调度策略紧凑,最多丢失一秒内的数据。劣势在于,数据量大时,恢复速度比rdb文件慢。