Redis教程(二)——Redis的持久化
ok,今天我们来整理下Redis持久化这个知识点,Redis的持久化对于分布式缓存来说是必不可少的一个部分,试想,一个高流量的系统,如果突然某些原因导致系统宕机,那么怎么样才能将缓存中的数据重新找回呢?这时Redis的持久化就派上用场了。
在了解Redis持久化之前,我们还是带着问题去学习:
- Redis持久化有什么意义,为什么需要持久化
- Redis持久化的方式,以及各个方式的特点和使用方法
- 持久化方式的区别
- 企业级的持久化方案
Redis持久化
对于生产数据而言,在系统服务的过程中,由于某些原因系统宕机,从而导致系统数据丢失,这绝对是一次生成事故,是大灾难,那么有没有一种方法能在不影响系统性能的前提下,能将生产数据实时备份下来呢?答案肯定是有的,而且Redis进行很好的支持这个方法。
Redis通过持久化这个功能将生产数据有计划、实时的保存到磁盘中,等Redis服务端重启的时候,将数据再重新写入到Redis中,这样能最大限度的保证生产数据的完整性;So,总结来说,Redis的持久化就是为了数据备份,数据备份也是为了数据恢复。
Redis持久化的方式
Redis提供两种持久化的方式:RDB和AOF,这两种方式是可以同时使用的
RDB
RDB是Redis默认支持的持久化方式,就是当前进程的数据生产快照存入到磁盘中。RDB保存到文件中的数据是二进制数据流,RDB提供配置固定的时间间隔对数据进行快照存储。
## RDB主要涉及redis.conf下的几个配置项
## 1.持久化时间间隔设置,多条配置只要有一条满足就会执行持久化操作
## 每900秒钟里redis数据库有1条数据被修改则触发RDB
save 900 1
## 每300秒钟里redis数据库有10条数据被修改则触发RDB
save 300 10
## 每60秒钟里redis数据库有10000条数据被修改则触发RDB
save 60 10000
## 持久化文件名称
dbfilename "dump.rdb"
## 持久化数据文件保存路径,默认是/usr/local/redis-5.0.5/src下,实际生产过程中需要配置其他的目录下
dir ./
这里有必要说明下RDB的原理:
Redis在触发持久化后,会fork一个子进程,此时父进程和子进程同在
子进程将目前Redis进程的全部数据写入到一个临时文件RDB中
当子进程完成对新RDB文件的写入时,Redis用新的RDB的文件覆盖旧的RDB文件
- 触发RDB机制有两种:手动触发和自动触发
- 手动触发:通过命令来触发持久化
- 直接输入save命令就可以持久化,也可以查看通过命令查看当前的持久化方式:
- bgsave:使用该命令Redis会fork一个子进程来负责RDB的持久化,完成持久化后自动结束子进程,相当于异步的,所以阻塞只发生在fork的阶段
## 查看redis持久化配置
CONFIG GET save
## 修改redis持久化配置
CONFIG SET save "60 10000"
注意:一般不使用save方法来持久化,我们知道Redis是单线程的,所以一旦执行save命令,则Redis就会调用主进程来执行内存数据持久化到文件中,这里为什么使用主进程,主要是后面介绍的bgsave正好相反,主进程被调用,则会阻塞进程,特别是数据量特别大的时候更是如此。
- 自动触发:自动触发是在redis.conf中配置持久化的策略来生效的,其实默认调用的也是命令机制里的bgsave机
- RDB持久化的优点:
- RDB会生成一个数据文件,这个数据文件都代表某个特定时间段的文件,可以在linux服务其中采用定时备份的机制来实现数据的冷备。
- RDB通过bgsave来执行持久化对Redis的对外服务影响比较小,因为是通过fork一个子进程来实现数据的持久化,所以对主进程的影响就比较小了,这也是为什么Redis默认提供RDB的持久化方式
- 相对于AOF的持久化机制来说,直接一句RDB来持久化的数据来重启和恢复Redis数据的速度更快
- RDB持久化的缺点:
- RDB持久化是基于时间间隔的机制的,也就意味着,如果Redis突然暂停服务了,则数据的丢失程度比较大,比如在企业生产过程中一般按照五分钟一次的持久化数据(这个按照不同的业务需求来配置持久化的时间间隔),如果一旦Redis服务宕机,则会丢失5分钟的数据
- RDB每次在fork子进程,每次持久化的是当前Redis中的全部的数据,如果当数据量比较大的时候,可能会导致对客户端数提供的服务暂停数毫秒甚至是数秒
AOF
AOF持久化就是以独立的日志来记录每次的写命令,然后Redis重启的时候 ,重新执行AOF的命令来完成Redis数据的恢复,这里的日志记录是每次的写命令而不是二进制数据流
这里有必要说明下AOF的实现原理:
所有的命令都会被追加到aof_buf这个缓冲区中
接着AOF缓冲区根据对应的同步策略想磁盘中做同步操作,此处的同步策略可以通过redis.conf中的appendfsync进行配置
随着AOF文件变大,可以通过rewrite机制来压缩Redis中的数据
Redis服务器重启会加载AOF文件用来恢复数据
- AOF必须手动开启,在redis.conf中设置如下参数
## 开启AOF持久化,默认关闭
appendonly yes
## AOF文件名称(默认)
appendfilename "appendonly.aof"
## AOF持久化策略 有三个值 always、everysec和no 默认是everysec 建议设置成everysec
appendfsync everysec
## AOF自动重写的文件大小跟上一次重写的文件的百分比
auto-aof-rewrite-percentage 100
## AOF自动重写的文件的最小值
auto-aof-rewrite-min-size 64mb
其中appendfsync
的配置如下:
可配置的值 | 配置说明 |
---|---|
always | 服务器会在每执行一个事件就把AOF缓冲区的内容强制性的写入硬盘上的AOF文件里, 可以看成你每执行一个redis写入命令就往AOF文件里记录这条命令, 这保证了数据持久化的完整性,但效率是最慢的,却也是最安全的 |
everysec | 服务端每执行一次写操作(如set、sadd、rpush)也会把该条命令追加到一个单独的AOF缓冲区的末尾, 并将AOF缓冲区写入AOF文件,然后每隔一秒才会进行一次文件同步把内存缓冲区里的AOF缓存数据真正 写入AOF文件里,这个模式兼顾了效率的同时也保证了数据的完整性, 即使在服务器宕机也只会丢失一秒内对redis数据库做的修改 |
no | redis数据库里的数据就算丢失你也可以接受, 它也会把每条写命令追加到AOF缓冲区的末尾,然后写入文件, 但什么时候进行文件同步真正把数据写入AOF文件里则由系统自身决定, 即当内存缓冲区的空间被填满或者是超过了设定的时限后系统自动同步。 这种模式下效率是最快的,但对数据来说也是最不安全的 |
- AOF的优点
- 通过配置同步策略就能实现实时持久化数据,可以同时兼顾性能和数据安全
- AOF只进行文件追加操作,并且redis官方提供redis-check-aof修复命令,这样当系统突然宕机,写入命令不完整时,可以修复数据,最大程度的保证数据的完整性
- AOF是有序的将写入的命令保存起来,数据文件可以清晰的读懂,对于数据分析对比来说比较有优势
- AOF日志文件以append-only模式写入,所以没有任何磁盘寻址的开销,写入性能非常高
- AOF的缺点
- 相对于RDB来说,AOF的文件通常比较大
- AOF恢复数据的速度比RDB的要慢
- AOF开启后,支持的写QPS会比RDB支持的写QPS低,因为AOF一般会配置成每秒fsync一次日志文件,当然,每秒一次fsync,性能也还是很高的
Redis持久化操作
我们通过上面的redis.conf配置文件的修改,开启RDB和AOF持久化的机制,然后再Redis中设置好对应的键值
为了测试RDB的持久化效果,我们可以设置1秒内有1条数据变化就执行RDB持久化
首先添加数据
查看是否生成备份文件
image
查看AOF的备份数据文件
image
查看RDB的备份数据文件
image
RDB和AOF的区别
比较项 | RDB | AOF |
---|---|---|
文件大小 | 小 | 大 |
备份频率 | 低 | 高 |
数据恢复速度 | 快 | 慢 |
写QPS | 高 | 低 |
支持重写 | 否 | 是 |
Redis企业级数据持久化
- 不要仅仅使用RDB,因为那样会导致你丢失很多数据
- 也不要仅仅使用AOF,因为那样有两个问题,第一,你通过AOF做冷备,没有RDB做冷备,来的恢复速度更快; 第二,RDB每次简单粗暴生成数据快照,更加健壮,可以避免AOF这种复杂的备份和恢复机制的bug
- 综合使用AOF和RDB两种持久化机制,用AOF来保证数据不丢失,作为数据恢复的第一选择; 用RDB来做不同程度的冷备,在AOF文件都丢失或损坏不可用的时候,还可以使用RDB来进行快速的数据恢复
AOF的重写机制
AOF重写的原理:
- 先是将当前Redis数据库中的数据读取出来,然后fork一个子进程,子进程会携带主进程的数据(数据为主进程上的所有的数据)副本将数据写入到新的AOF备份数据文件。
- 对于新执行的写入命令,主进程会将其写入到一个缓存中,一边将改动追加到现有的AOF文件中,这个缓存在fork出子进程之后开始启用
- 当子进程完成重写工作时,他会给主进程发送一个信号,主进程收到这个信号后,会将缓存中的所有的数据写入到新的AOF文件中,同时将该AOF文件重新替换原有的AOF文件
流程图表示