Redis为了内部数据的安全考虑,会把本身的数据以文件形式保存到硬盘中一份,在服务器重启之后会自动把硬盘的数据恢复到内存(redis)的里边,数据保存到硬盘的过程就称为“持久化”效果。
redis有两种持久化功能,一种是“快照持久化(RDB)”,一种是“AOF持久化”。
一、RDB持久化
Redis数据持久化是将内存中的数据保存到磁盘里,避免数据意外丢失。RDB持久化会生成一个RDB文件,这个RDB文件是一个经过压缩的二进制文件。通过该文件可以还原出Redis数据库中的数据。RDB的持久化可以手动执行,也可以根据服务器配置项定期自动执行。
有两个命令可以创建RDB文件,一个是SAVE,另一个是BGSAVE。
执行SAVE命令会阻塞Redis服务器进程,直到RDB文件创建完成为止,在服务器进程被阻塞期间,服务器不能处理任何命令请求。
执行BGSAVE命令会派生出一个子进程,然后由子进程负责创建RDB文件,服务器父进程继续处理命令请求。
SAVE命令和BGSAVE命令的底层调用的函数都是同一个函数rdbSave,只不过SAVE命令是直接调用这个函数,而BGSAVE会fork()出子进程来调用这个函数。
RDB文件的载入工作是在服务器启动时自动执行的,只要Redis服务器在启动时检测到RDB文件存在,就会自动载入RDB文件。值得一提的是,Redis服务器在载入RDB文件的期间,会一直处于阻塞状态,直到载入工作完成为止。
BGSAVE命令在不阻塞服务器进程的情况下执行,所以Redis允许用户通过设置服务器的save选项来让服务器每隔一段时间自动执行一次BGSAVE命令
二、AOF持久化
除了RDB持久化之外,Redis还提供了AOF持久化功能,两者的实现方式有着很大的不同。RDB持久化是通过保存数据库中的键值对来记录数据库状态,而AOF持久化是通过保存Redis服务器所执行的写命令来记录记录数据库状态。
AOF持久化是如何实现的呢?AOF持久化分文三个步骤:命令追加、文件写入、文件同步。
命令追加:当AOF持久化功能打开时,服务器在执行完一个写命令后,会以一定的格式将被执行的写命令追加到服务器中的aof缓冲区中。aof缓冲区是redisServer结构体维护的一个SDS结构的属性。
文件写入:文件写入是指从Redis的aof缓冲区写入到操作系统的内存缓冲区。这个过程是为了提高文件的写入效率,但是带来的风险是服务器出现故障时,内存缓冲区中的数据会丢失掉。
文件同步:这个过程是将内存缓冲区中的数据写入到硬盘中的AOF文件中
Redis中默认执行的是RDB持久化,如何打开AOF持久化呢?我们先来看看AOF的配置项:
appendonly:这个参数是AOF的开关,配置成yes可以打开AOF持久化机制。打开AOF机制后
appendfsync:我们知道Redis中有个事件循环,Redis在每个事件循环都会将aof缓冲区中的内容写入到操作系统的内存缓冲区。这个参数就是来配置将内存缓冲区中的数据同步到硬盘上的AOF文件中的更新频率,有always、everysec、no三个配置值。always表示每次执行写入操作,就会立即将内存缓冲区中的内容同步到磁盘中的AOF文件中。这种配置性能比较差,但是可以确保数据不丢失。everysec表示每秒执行一次将操作系统的内存缓冲区中的数据同步到磁盘的AOF文件中,这个操作由一个线程来负责,性能很高。no表示由操作系统来控制何时将内存缓冲区中的数据同步到硬盘的AOF文件中。这种操作在服务器出现异常时会丢失一部分数据。
下面说说AOF文件的还原过程,我们知道AOF文件中存储的是所有曾经执行过的写命令,所以服务器只要读入并重新执行一遍AOF文件里保存的写命令,就可以还原服务器关闭之前的数据库内容。
三、RDB和AOF区别和联系,以及同时工作时的情况
区别和联系:
RDB持久化:默认开启;全量备份,一次性保存整个数据库;体积小,数据恢复快;服务器异常时可能会丢失部分数据;SAVE操作会阻塞,BGSAVE不阻塞。
AOF持久化:默认关闭;增量备份,一次保存一个修改数据库的命令;体积大,数据恢复慢;备份频率可以自己设置;不会出现阻塞。
当RDB和AOF同时开始时:
如果RDB在执行snapshotting操作,那么redis不会执行AOF rewrite; 如果redis在执行AOF rewrite,那么就不会执行RDB snapshotting。
如果RDB在执行snapshotting,此时用户执行BGREWRITEAOF命令,那么等RDB快照生成之后,才会去执行AOF rewrite。
同时有RDB snapshot文件和AOF日志文件,那么redis重启的时候,会优先使用AOF进行数据恢复,因为其中的日志更完整。
1.snap shotting快照持久化
该持久化默认开启,一次性把redis中全部的数据保存一份存储在硬盘中,如果数据非常多(10-20G)就不合适频繁操作该持久化操作。
如果对redis有数据操作,就会根据redis的配置文件指定的文件名和路径生成rdb文件,先来看一下redis配置方面的截图说明
再看一下在redis目录下生成的rdb文件
可以使用vim命令对dump.rdb文件编辑看一下内容
注意:如果您细心的发现,在对redis客户端进行数据操作之后,再次进行对dump.rdb文件进行编辑查看,文件中可能会缺少最近的操作记录,这与配置文件中备份的频率有关,下面看一下截图
- 第一条的意思是:服务器在900秒内对数据库执行过至少1次修改,就会执行BGSAVE命令
- 第二条的意思是:服务器在300秒内对数据库执行过至少10次修改,就会执行BGSAVE命令
- 第三条的意思是:服务器在60秒内对数据库执行过至少10000次修改,就会执行BGSAVE命令
以上三个save的意思都有了相应的说明,数据修改的频率非常高,备份的频率也高,数据修改的频率低,备份的频率也低。
如果发现dump.rdb文件缺少了最近的记录,那么在这补充一种手动持久化方式,可以立即看到效果,执行此命令
./redis-cli bgsave #异步保存
其次还包括一些其他的手动命令
./redis-cli shutdown #同步保存到服务器并关闭redis服务器
./redis-cli lastsave #返回上次成功保存到磁盘的unix时间戳
./redis-cli bgrewriteaof #当日志文件过长时优化AOF日志文件存储
由于快照方式是在一定间隔时间做一次的,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改。如果应用要求不能丢失任何修改的话,可以采用aof持久化方式
2.append only file(AOF持久化)
AOF持久化本质:把用户执行的每个“写”指令(添加/修改/删除)都备份到文件中,还原数据的时候就是执行具体写指令而已。
开启AOF持久化(会清空redis内部的数据,最好在redis使用之前就开启它)
我们在redis.conf配置文件中可以找到它:
修改完成配置之后重启redis
再次启动测试一下是否有数据
看一下目录下自定义的aof文件,目前得大小是0
操作之后
vim查看一下
所有指令全部写入文件
在redis.conf中,可以调整AOF备份形式:
always 一写指令就备份一次。这样做虽然安全,但是系统性能会降低。不推荐使用
everysec 每一秒中备份一次。不管一秒钟变化了多少key,只备份一次,性能得到一定的保护。推荐使用。
no 会查看当前服务器状态,如果状态良好,就进行备份(随机)。这种备份方式数据是没有保证的。
对比下来,性能:always<everysec<no,而数据安全:always>everysec>no。
举例说明一下,这里就暂时不操作了,您可以拿redis的自增来操作:incr num ,执行此命令10次,然后查看一下aof文件,发现aof文件保存的是最终的数值,而且是set命令,这样就节省了空间,下面说一下就是把AOF备份文件中所有的备份数据的内容进行一个处理。
在启动redis客户端的时候,使用bgrewriteaof指令,就可以对aof备份文件的内容进行
优化压缩处理。截图对比一下处理先后的大小
完毕