最近有幸学一下后台,因为redis搞得后台同学非常头疼,顾学一下redis看看是不是真的难,确实挺难的,单这个持久化机制就研究了很久,所以记录一下。
其实就是在一段时间内生成redis的一个快照文件,并且写入磁盘(这样下次启动就直接把这份快照数据读入redis内存即可)
我们可以打开redis.conf文件(估计是在根目录或者conf目录下,我用的是windows,所以直接是在根目录中找到redis.window.conf,如下图2-1所示。linux系统的redis配置文件叫redis.conf)
图2-1
打开redis.window.conf(或者redis.conf),我们可以搜索图2-2的代码,看到对应的注释,大概意思就是可以通过save [seconds] [changes]来配置RDB快照触发的时间,意思就是在seconds秒内,
如果存储的redis的key的值发生了变化或者多了或少了某个key(增删改),就会触发生成RDB快照了
图2-2
当然,也可以直接在服务端执行bgsave命令直接生成快照,一般比较少用到
这里节省时间,直接引用别人的图了,如图3-1所示。
图3-1
这里要注意的是,如果主进程比较大的时候,第二个步骤容易阻塞,也是影响RDB这种机制性能的点。
那么有人会问,为什么第三步需要先创建RDB文件呢?主要是,马上创建一个文件到硬盘,这样如果突然遇到断电也不慌(试想一下,如果不先建立文件,而是先把数据写入缓冲区,待到缓冲区满了再写入文件,那么第一次写入就可能因为断电等原因,导致文件没生成,然后就没记录下缓冲区的数据了。我们的宗旨是应该尽量记录下更多的redis的快照数据才对。)
这个内容不是很重要,我大概只记得,RDB文件前五个字节固定是REDIS。然后就是如下图4-1所示了。存储的形式都是二进制格式的。所以文件相对比较少,主从复制时会比较快。
图4-1
优点:
缺点:
AOF全称append only file,就是把redis执行过的所有命令和参数都记录在一个文件内,如果redis宕机重启后,就会执行该文件的所有写命令,这样就可以保持redis的持久化了。
可以在redis.conf(redis.window.conf)中,找到图3-2-1的代码:
图3-2-1
首先直接扔一张流程图:,比较复杂,不要紧。这里涉及三个进程,一个主进程和两个子进程。
先说下主进程:
AOF文件的保存模式(执行上面流程的时机)有以下三种:
以上是主进程的执行过程,接下来讲一下图3-2-1的最后一个子进程的作用。
AOF重写不是真正的重写,而是在一段时间内,redis对AOF文件进行瘦身。
举个例子,如下图3-3-3所示,redis对同一个key执行了3次set操作,所以最终s1的值为33,而前两次的set操作其实不需要记录在AOF文件中的,于是,就有了一个子进程进行对AOF文件的瘦身的操作。
图3-3-3
AOF重写时使用的是fork的子进程的好处:
但是子进程要处理的问题是,当AOF文件重写的时候,主进程会在处理新的客户端请求(可能会有新的读写操作),这些新的读写操作怎么写入新的AOF文件当中呢?步骤如下:
所以AOF的重写不会导致主进程的阻塞
那么,AOF重写机制如何配置呢?我们可以找到redis.conf(redis.window.conf)文件,然后看到下面这两个配置参数:
# 表示当前aof文件大小超过上一次aof文件大小的百分之多少的时候会进行重写。如果之前没有重写过,以
启动时aof文件大小为准
auto-aof-rewrite-percentage 100
# 限制允许重写最小aof文件大小,也就是文件大小小于64mb的时候,不需要进行优化
auto-aof-rewrite-min-size 64mb
当然,执行bgrewriteaof命令也可以触发重写机制(一般比较少用到)
因为RDB和AOF各有优缺点,所以也可以将两者混合使用,只需要在redis.conf(redis.window.conf)文件中配置如下代码段即可。
aof-use-rdb-preamble yes
开启混合持久化机制后,RDB文件的内容会写道AOF文件的头部,如下图所示
当真的遇到redis宕机重启时,重启会优先加载AOF文件:
如果没有配置AOF机制,就会使用读取RDB文件
RDB | AOF | |
优点 | 1、除了根据主子程fork子进程这个步骤,其他都不会阻塞主线程处理客户端的请求 2、占用空间小,主从备份快 3、性能比AOF高 |
1、可以尽量保持数据完整性 2、设置每秒触发一次AOF文件机制,不会阻塞主进程 |
缺点 | 1、不能最大程度保持数据完整性(只能保持最后一次快照) | 1、性能比较慢 2、文件占用空间较大 |