redis的数据在运行期间都是保存在内存中,当服务器重启时,redis服务器会从磁盘中加载之前已经持久化到磁盘中的数据。而且,redis服务器突然宕机,保存在内存中的数据就会丢失,显得redis的持久化机制更为重要。redis提供了两种持久化机制。

第一种是RDB方式。

默认情况下,你没有做任何配置的话,redis就是使用这种方式进行持久化。基本的原理就是将当前内存中的所有数据进行快照,然后写入磁盘中。

打开reids安装目录下的redis.conf文件。dir属性指定了持久化文件的位置,dbfilename属性指定了持久化文件的名称,默认叫dump.rdb。打开这个rdb文件看一眼,发现完全看不懂,因为这是经过压缩的二进制文件,这个文件记录了内存中的所有的数据(快照那一刻的)。每 进行一次快照,就会用新的rdb文件代替旧的。下面说一下哪些情况下,redis会进行快照。

1. 还看redis.conf文件,有几个save属性。

save 900 1
save 300 10
save 60 10000

默认是三行,第一行的意思是900秒内有1次写的操作时就会快照一次;第二行的意思是,300秒内有10次写的操作就会快照一次;第三行不说了。这三个条件是或的关系。如果你喜欢,可以再添加几行,也可以全部删掉他们。如果你全部删掉的话,这种通过规定时间内检测写操作次数来进行快照的功能就丢掉了。

2. 执行save命令,这个命令可以手动告诉服务器快照一次,但这个是这个阻塞操作,在快照结束之前,其他线程是无法访问服务器的,可以用bgsave命令代替save命令,这个命令可以在后台快照。

3. 服务器正常关闭时。

第二种是AOF方式。

显然,经过刚才的介绍,大家肯定担心,万一redis还没来得及快照,突然宕机了,那最后一次快照至宕机这段时间内的数据是不是就丢了。是的,确实就丢了。如果你觉得这个问题不可忍受的话,可以用AOF方式来解决这个问题。

AOF方式的原理是,每执行一次写操作,redis就会向一个持久化文件中追加几行命令来记录这次写操作。这样,问题解决了,但是效率却降低了。刚才已经说过,AOF方式默认是不开启的,需要修改配置文件,还是redis.conf文件,修改appendonly属性为yes就可以开启AOF,AOF的持久化文件的路径和名称是通过dir和appendfilename指定的,默认名称叫做appendonly.aof。

*2
$6
SELECT
$1
0
*3
$3
set
$1
a
$1
a
*2
$6
SELECT
$1
0
*3
$3
set
$14
dffkjdasdjflda
$67
dkjjfdkjdkafjs;ja;sfdjfdas;fdsa;fjdasj;fjas;dfdsajf;jdasjfdsjfijasd

这个文件大概可以看明白,主要看set这个单词就可以了。每个set代表一次写操作。你可能会说,如果我反复的设置同一个键的值,redis会追加几条命令呢。答案是redis在追加时不做检查,冗余就冗余吧。但是每当满足一定条件时,redis就会去删除这些冗余的命令。你不能指望redis每次执行写操作都要去删除冗余的命令,这样效率太低了。我们可以通过设置下面两个属性,来控制redis什么时候去删除冗余的命令,这里不做过多介绍了。

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

另外,如果你开启了AOF方式的话,当服务器重启时,就会从AOF的持久化文件中加载数,不会再找RDB的快照持久化文件了。

关于AOF方式持久化的两个坑,大家看一下,不要再跳进去了。

第一个我给大家演示以下。

第一步,就使用默认的RDB方式,存入几个键值对。然后正常关闭服务器。这时候,数据已经持久化到rdb文件中了。正常开启服务器的化,这些数据可以正常加载回来。不信的话你可以试一下。

第二步,编辑redis.conf文件,开启AOF方式。然后开启服务器,你会发现刚才存的数据都丢了。

这一点都不意外,我不解释了。

第二个是,不要以为开启了AOF,数据就不会丢失了,这里有一个缓存的概念。

当执行写操作时,redis确实向磁盘发出了写的命令。但是磁盘会将这些命令缓存起来,每隔一段时间才向磁盘同步一下数据。这样,仍然存在数据丢失的风险。可以在redis.conf中设置一下。

appendfsync always
# appendfsync everysec
# appendfsync no

第一个的意思是,不需要缓存,也就是redis要求操作系统马上执行写的操作;第二个是使用缓存,但是每秒钟同步一下数据;第三个就是默认使用缓存。