Redis与持久化

182 阅读4分钟

Redis是基于内存的,但是也提供了持久化技术,用于避免数据丢失的问题,有两种手段对数据进行持久化,分别是

  • AOF日志
  • RDB快照

一、AOF日志

AOF(Append only file):简单理解就是redis会将执行过的每条命令,以追加的形式保存到一个文件中,如果出现数据丢失,那只需要按这个文件的命令重新跑一遍就能恢复数据了。redis默认没有开启AOF持久化。

//redis.conf
appendonly yes
appendfilename "appendonly.aof

aof文件详解

下面给出一个aof文件的部分内容作为示例,帮助大家理解。

*3
$3
set
$4
name
$7
wuwentao

*+数字: 表示写命令由三个部分组成(set,name wuwentao)

$+数字:表示有下一个部分有多少个字节,set占3个字节,name占4个字节

tips:

1、aof只记录写命令,因为是用于恢复数据的,所以读命令就没有必要记录了

redis是先执行命令,在记录aof的,主要有两个好处:

  • 保证aof中记录的是正确合理的命令
  • 不会阻塞当前写命令

同样也有两个风险:

  • 数据丢失:执行完写命令,还没写日志,redis挂了,那这部分数据就丢失了
  • 阻塞下一条写命令:redis执行命令和写日志都由主线程完成

aof写回策略

要介绍写回策略,就要先了解aof文件写入硬盘的过程,主要有三个步骤:

  • redis执行完写操作命令后,会将命令追加到server.aof_buf缓冲区
  • 然后通过write()系统调用,将server.aof_buf缓冲区写入到AOF文件,此时数据并没有写入到硬盘,而是拷贝到了内核缓冲区page_cache,等待内核将数据写入硬盘
  • 内核缓冲区page_cache写入硬盘

其中第三步page_cache写入硬盘时就是写回策略生效的地方,主要有三种策略

  • Always:执行完写命令,就会将AOF日志写回磁盘
  • Everysec:每秒将AOF日志写回磁盘
  • No:不由redis控制,由操作系统控制

下面给出三种策略的优缺点对比,大家根据场景需要选用合适的策略

  • 高性能选择No策略
  • 高可靠选择Always策略
  • 高性能与高可靠折中就选择EverySec

image.png

aof重写机制

简单理解就是随着执行的写命令的增加,aof文件会越来越大,超过设定的阈值,redis机会对aof进行重写,通过省略一些中间过程,直接记录最终值。

tips:aof重写时,会先生成新的aof文件,然后重写完成再替换旧的aof文件

set a 1;
set a 2;
set a 3;
set a 4;

//重写会省略掉前面的步骤,直接记录最终值
set a 4;

二、RDB快照

RDB快照其实也是一种日志文件,区别于aof记录的写命令,rdb记录的是二进制数据,是某一时刻内存中的数据,是实际的数据。

tips:恢复数据的时候rdb的效率比aof高,因rdb记录的是实际的数据,只需要读入内存就可以了。

RDB的使用

Redis提供了两个命令来使用RDB,分别是save和bgsave,二者的区别就是是否在主线程执行。

redis可以通过配置文件设置bgsave,默认配置如下

# 900s内至少有一次请求
save 900 1 
# 300s内至少有10次请求
save 300 10
# 60s内至少有10000次请求
save 60 10000

tips:rdb是全量快照,如果执行频率较高则会对性能产生影响,如果执行频率较低,那发生数据丢失时,丢失的数据就是间隔时间内的所有数据,所以要设置合适的执行频率

Copy-on-write

三、混合持久化日志

前面介绍了aof和rdb,可以发现二者各有优缺点,aof可以秒级记录数据,数据丢失少,但是数据恢复慢,rdb数据恢复快,但是发生意外时,数据丢失比较多。 所以可以综合采用两种持久化方式,取长补短。

启用混合持久化

修改配置文件:

aof-use-rdb-preamble yes

混合持久化的过程发生在aof日志重写过程。当使用了混合持久化,aof文件的前半部分是rdb格式的全量数据,后半部分是aof格式的增量数据,这样就兼顾了两种持久化方式的优点。