每日一句

前提概要

  • Redis的强劲性能很大程度上是由于其将所有数据都存储在了内存中,为了使Redis在重启之后仍能保证数据不丢失,需要将数据从内存中以某种形式同步到硬盘中,这一过程就是持久化。

  • 我们知道redis中缓存的数据都存放在内存中,一旦服务故障,会导致内存中数据丢失,所以需要一种数据持久化的方案,将redis内存中的数据,写入磁盘,当redis重启后,能从磁盘中恢复数据。

Redis服务器的结构

  • 这里有一个问题,因为Redis是一个内存数据库,如果它直接将数据存储到内存中,但是如果不考虑将存储在内存中的数据持久化到硬盘里面,一旦服务器进程退出,那么数据库中的数据也会消失。

  • 数据库的持久化机制主要有两种,一种是RDB机制,另外一种是AOF机制,AOF机制已经在前面的文章中介绍过了,

  • 如果有兴趣可以去看看,而本文主要讲述RDB机制。

RDB持久化方式

RDB机制

  • Redis提供了RDB持久化能力,这个功能可以将Redis在内存中的数据库状态保持在磁盘里面,避免数据意外丢失。

  • RDB持久化机制可以手动执行,也可以根据服务器配置选定定期执行操作,该功能可以将某一个时间点的数据快照进行保存到一个RDB文件中。

RDB优势

  • 一旦采用该方式,那么你的整个Redis数据库将只包含一个文件,这对于文件备份而言是非常完美的。比如,你可能打算每个小时归档一次最近24小时的数据,同时还要每天归档一次最近30天的数据。通过这样的备份策略,一旦系统出现灾难性故障,我们可以非常容易的进行恢复。

  • 对于灾难恢复而言,RDB是非常不错的选择。因为我们可以非常轻松的将一个单独的文件压缩后再转移到其它存储介质上。

  • 性能最大化。对于Redis的服务进程而言,在开始持久化时,它唯一需要做的只是fork出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操作了。

  • 相比于AOF机制,如果数据集很大,RDB的启动效率会更高。

RDB劣势

  • 如果你想保证数据的高可用性,即最大限度的避免数据丢失,那么RDB将不是一个很好的选择。因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。

  • 由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟。

RDB配置规则

备份配置参数

save <seconds> <changes>
save 900 1      #在900秒(15分钟)之后,如果至少有一个key发生变化,则dump内存快照
save 300 10     #在300秒(15分钟)之后,如果至少有10个key发生变化,则dump内存快照
save 60 10000   #在60秒(1分钟)之后,如果至少有10000个key发生变化,则dump内存快照

文件配置参数

# 存放快照的目录
dir ./ # rdb文件存储路径
dbfilename dump.rdb # rdb文件名

压缩配置参数

rdbcompression yes  #Redis默认是开启压缩的。
# yes:压缩,但是需要一些cpu的消耗。
# no:不压缩,需要更多的磁盘空间。

如果没有触发自动快照,需要对Redis执行手动快照操作,save和bgsave命令来手动快照,两个命令是:

  • SAVE:由主进程进行快照,会阻塞其他请求。
  • BGSAVE:通过fork子进程进行快照,不会阻塞其他请求。

快照的过程如下:

  1. Redis使用fork函数复制一份当前进程(父进程)的副本(子进程);
  2. 父进程继续接收并处理客户端发来的命令,而子进程开始将内存中的数据写入硬盘中的临时文件;
  3. 当子进程写入完所有数据后会用该临时文件替换旧的RDB文件,至此一次快照操作完成。(注意:会存在写一部命令压缩缓存区,记录写入rdb文件时候的操作)
快照的过程压缩分析:
快照的读取加载过程:
  • Redis启动后会读取RDB快照文件,将数据从硬盘载入到内存。根据数据量大小与结构和服务器性能不同,这个时间也不同。通常将一个记录一千万个字符串类型键、大小为1GB的快照文件载入到内存中需要花费20~30秒钟

  • 通过RDB方式实现持久化,一旦Redis异常退出,就会丢失最后一次快照以后更改的所有数据。这就需要开发者根据具体的应用场合,通过组合设置自动快照条件的方式来将可能发生的数据损失控制在能够接受的范围。如果数据很重要以至于无法承受任何损失,则可以考虑使用AOF方式进行持久化。

RDB 的优缺点

优点:

  1. 适合大规模的数据恢复。
  2. 如果业务对数据完整性和一致性要求不高,RDB是很好的选择。

缺点:

  1. 数据的完整性和一致性不高,因为RDB可能在最后一次备份时宕机了。
  2. 备份时占用内存,因为Redis 在备份时会独立创建一个子进程,将数据写入到一个临时文件(此时内存中的数据是原来的两倍),最后再将临时文件替换之前的备份文件。
  3. 由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟。(回写和覆盖的时候用的是主进程)。

RDB与AOF二者选择的标准(虽然还没有讲AOF,提前普及)

  • 如果系统是愿意牺牲一些性能,换取更高的缓存一致性(aof)

  • 或者是愿意写操作频繁的时候,不启用备份来换取更高的性能,待手动运行save的时候,再做备份(rdb)。

总结

  • Redis 默认开启RDB持久化方式,在指定的时间间隔内,执行指定次数的写操作,则将内存中的数据写入到磁盘中。

  • RDB 持久化适合大规模的数据恢复但它的数据一致性和完整性较差。

  • Redis 需要手动开启AOF持久化方式,默认是每秒将写操作日志追加到AOF文件中。

09-04 07:28