由于笔者一直对redis三种持久化方式存有疑惑,所以抽空来整理和实践下,本篇文章不会涉及到太多理论知识,主要从实践的角度带大家认识下redis的三种持久化方式。
1. Redis 三种持久化方式
1.rdb 适合全量备份,文件支持压缩,二进制格式,相比于aof来说占用空间比较小,加载的速度更快
2.aof 它是一种文本格式的文件,相对rdb占用空间比较大,可以开启aof重写
3.混合模式 结合rdb和aof两种持久化方式的优点,默认是开启的(aof-use-rdb-preamble = yes)
2. 实践
2.1 RDB 持久化
需要声明的是笔者实践的环境是Centos7+Redis5.0.7
首先我们关闭aof持久化方式和混合模式持久化方式
appendonly no ; //关闭aof(不过默认是关闭的)
aof-use-rdb-preamble = no ;//关闭混合模式持久化方式
设置完成后,我们先关闭redis,
redis-cli > shutdown
接着我们删除已有的一些持久化文件,笔者这里是dump.rdb和appendonly.aof ,小伙伴们就根据具体的配置文件名来删除对应的文件就好了。
然后我们重启启动redis
redis-server redis.conf
服务器启动并不会生成dump.rdb,小伙伴们可以进入到数据目录查看下,接下来我们设置几条数据
redis-cli > set name 'xiaoming'
redis-cli > set age 28
redis-cli > set sex 1
设置成功后,我们进入到对应的数据目录查看是否生成了持久化文件,知道rdb持久化原理的小伙伴肯定知道是不会生成的,为啥呢?
我们查看下配置文件里面触发rdb持久化的条件就知道了
save 900 1
save 300 10
save 60 10000
这几行的意思在配置文件的注释里面也给了比较详细的描述,大概的意思是:
save 900 1:如果15分钟内至少有1个key发生了改变(可以理解为新增,修改,删除),就会触发一次持久化,举个简单的例子,比如你在15.40分钟新增了一个key,那么这个key在15.55分后将被持久化到rdb文件中,当然这中间可以修改多个key,这些key也将会被持久化。其他两个的意思这里就不展开说了,小伙伴们依次类推就好了。
大约隔了15分钟,我们查看数据目录,发现dump.rdb已经有了,我们查看下dump.rdb,由于这是个二进制文件我们之间打开将会是下面这种效果:

我们可以借助于一些工具来查看,笔者这里使用的是hexedit工具,小伙伴们可以yum install hexedit -y 进行安装,下面使用hexedit 工具打开看下文件的内容:

看到里面很多的16进制数据。
不过,另外补充一点就是rdb持久化触发除了上面的save m,n 以外,还有其他一些触发方式,比如: 执行shutdown命令;又或者是主从复制的时候,如果从节点执行全量复制操作,则主节点会执行bgsave命令,并将rdb文件发送给从节点。
2.2 AOF持久化方式
我们再次关闭redis服务器和删除对应的文件,另外关闭混合模式持久化,这个时候我们开启appendonly yes ,我们分别来试下以下两种情况:
- 不开启rdb
- 开启rdb
如果选择不开启rdb的话我们需要设置save ""
下面我们先来试下不开启rdb持久化,即设置 save "",这里同样删除已有的持久化文件。
我们再次启动redis,发现在数据目录下就已经生成了appendonly.aof文件。下面我们查看下这个文件,不过里面什么都没有。下面我们来设置几条数据
redis-cli > set name 'xiaoming'
当刚设置完就发现已经被持久化了。

由此也可以看出aof这种持久化方式比rdb要实时多了,当然这里笔者还要说明的一个配置项是aof持久化的策略:
# appendfsync always
appendfsync everysec
# appendfsync no
always 总是将aof_buf缓冲区中的所有内容写入并同步到磁盘,可以简单的理解为每写一条命令都会同步到磁盘,效率是最慢的一个
everysec 每隔一秒钟在子线程中同步一次(同步到磁盘),所以当机器出现故障,数据库也只丢失一秒的命令数据,效率相对always来说效率高一点
no 这个同步到磁盘就由操作系统来决定,这个效率是最高的,但是安全性也是最差的,如果服务器宕机将有比较多的数据丢失。
注意: everysec 是默认的一种方式,如果你不太清楚要选择哪种持久化方式就选择everysec。
下面我们来开启下rdb方式再次进行测试
同样的,我们先关闭redis服务器,然后删除持久化aof文件
再次启动redis服务器,同样的启动完成后发现已经生成了aof持久化文件,不过里面是什么都没有。
我们设置几条数据
redis-cli > set name xiaoming
这个时候我们发现aof文件里面已经有了我们刚设置的那台命令:

不过此时还没生成rdb文件,我们猜测大概要隔15分钟才能生成,静静等待。。
大约隔了15分钟,dump.rdb文件已生成,查看下里面的内容

2.3 混合模式持久化
我们先来说下混合模式产生的背景,通过上面的实验我们可以了解到rdb这种持久化方式不是很实时,可能会丢失比较多的数据,aof这种持久化方式虽然实时性比较高,但是文件随着时间会越来越大,如果单独使用aof这种持久化方式,对于数据的重新加载效率是比较低的。那有人就提出使用一种混合模式,那混合模式的工作原理是怎样的呢?
混合模式持久化开启,系统根据策略触发aof rewrite时,fork一个子线程将内存数据以RDB二进制格式写入AOF文件头部,那些在重写执行之后的Redis命令,则以AOF持久化追加到AOF文件的末尾。
下面笔者从网上找了一些流程图来帮助大家理解:

测试来简单体验下:
下面我们先打开aof-use-rdb-preamble = yes,这里我们先删除之前的rdb和aof文件,关闭redis服务器后重新启动服务器,重启后我们发现很快就生成了一个aof文件,不过这个文件没有内容。接下来我们使用redis-cli登录到redis 后我们设置几个key.
redis-cli > set name xiaoming
OK
redis-cli > set age 18
OK
redis-cli > set sex 1
OK
这个时候我们发现很快就会生成aof文件,并且里面的内容就是刚刚设置的几个key
那接下来我们手动执行写aof rewrite 操作,
redis-cli > bgrewriteaof
Background append only file rewriting started
下面我们来接着再设置几个key
redis-cli > set color red
OK
redis-cli > set time 13421
OK
大概隔一小会我们再次查看aof
cat appendonly

我们发现这个文件前面多了一串以REDIS0009dis-ver5.0.7edis-bitsctime¢开通的二进制字符串,然后下面一部分是我们刚刚手动aof rewrite 后设置的几条命令。
其中二进制字符串是使用的rdb持久化的方式,生成的一串二进制数据。从这个实验我们可以比较清楚的了解混合模式持久化方式的工作方式。
总结:
- rdb持久化方式是一个全量的持久化,满足配置文件里面的条件即可触发持久化,不过这种方式不过实时,如果在服务器设置了很多key后还没来得及持久化,而这个时候刚好宕机了,就会导致很多数据的丢失;另外就是rdb是全量持久化的,所以当数据量比较大的时候效率不是很好。
- aof持久化方式,这种持久化方式属于增量型的,也就是说每次有修改数据的操作就会追加到文件的末尾,其中同步到磁盘文件的方式有3种,可以根据需求去配置,不过默认情况下我们会使用每秒同步一次磁盘,所以这种方式的实时性相对来说是高一些的,当服务器宕机或者出现一些其他的故障时不会导致大量的数据丢失;不过它有一定的弊端,一方面这种方式是以文本的方式记录每条修改数据库的命令,如果反复操作就会导致大量重复的命令,最终使得持久化文件很大,所以服务器会按照一定的策略,对aof持久化文件进行重写,不过需要注意的是这个重写不是对原来文件的重写,而是参照当前数据库的情况,写入对应的命令。另外一方面就是在服务器启动加载持久化文件的时候,如果是使用aof文件的话,如果文件比较大的话效率是比较低的,因为服务器要每条每条命令的执行,所以相对来说rdb方式加载数据的方式更快,因为它是直接加载键值对数据到内存。
3.混合模式持久化方式,这种方式是结合了上面两种方式的优点,不过这种方式是针对aof文件重新的时候,在没有重写的时候还是会使用之前的持久化方式,所以在开启混合模式持久化方式的同时,我们至少要开启aof和rdb两种持久化方式的其中一种,否则会导致数据丢失。
不过,最后有一个问题就是,当我们同时开启了rdb和aof持久化方式,那服务器加载数据的时候会使用哪种方式呢?
可以肯定的是在我们开启了混合模式的情况下是会使用aof文件的,那如果没有开启混合模式,redis会使用哪种文件来加载数据呢,答案是aof,原因是aof文件数据比较完整。
网友评论