最近在整理有关redis的相关知识,本篇文章主要对redis的持久化方案进行汇总和备注(主要为面试用)
我们都知道Redis是基于内存的数据库,其数据均存储在内存中,一旦进程退出内存中的数据将出现丢失,为了避免这种情况产生,我们可以采用集群的方案避免出现所有节点同时失效,也可以通过持久化内存中数据到本地磁盘,确保核心关键数据不丢失
redis主要提供了两种持久化方式,分别是RDB以及AOF
一、RDB
rdb文件可以理解为是某一时刻Redis内存数据的快照文件,其文件中包含的是键值对对象。
rdb文件可以通过SAVE命令、BGSAVE命令或者设置save配置项等方式产生,三者的区别如下:
rdb文件的名称以及生成的地址可以在redis.conf中进行配置:
命令 | 执行方式 | 执行过程 | 备注 |
SAVE命令 | 当SAVE命令执行时,redis服务器会被阻塞,此时无法处理客户端命令,直到SAVE命令执行完毕 | ||
BGSAVE |
当发送bgsave命令时,服务器会创建一个子进程来实现RDB文件创建,此时服务器依然可以处理客户端命令; |
1.bgsave与save、bgsave本身命令不可以同时执行 |
|
save配置 |
save 900 1(含义:在最近一次快照创建成功只有开始计算,在900s内只要有一个key发生变化,则执行BGSAVE命令) 上述配置项在redis.conf中可以修改 |
reids根据内置的定时函数(每隔100ms)检查是否满足相关配置条件,如果满足则执行bgsave命令 |
注:一般情况下,生产环境会关闭RDB备份方式,不管事save还是bgsave都会存在其各自的缺陷;save会阻塞客户端命令执行,这对于承接大量缓存类请求是不能接受的;bgsave虽然不会阻塞客户端命令,但是其会创建一个子进程,且会额外占用内存空间保存备份的数据,如果redis中存储了大量的数据(几十个G),那么新创建的子进程由于执行需要额外占用cpu、内存等资源,也会造成redis所在虚拟机资源发生争抢进而导致redis处理效率大大降低。
二、AOF
aof主要通过命令追加、文件写入、文件同步三个步骤实现redis持久化。
主要流程如下图:
aof对比rdb的一个最大的有点就是丢失的数据更少,由于aof采用命令追加的方式,即使遇到服务器宕机,最多损失的也就是一次时间循环期间的命令,比rdb损失的命令要少很多。
所谓成也萧何败也萧何,由于采用命令追加的方式,当redis长时间运行之后,追加的命令的会约来越多,此时会大大占用物理空间,同时在进行redis恢复的时候也会造成恢复时间增大
此时就需要AOF重写来进行优化
AOF重写即通过对现有服务器内的命令进行读取,生成一个新的aof文件并替换现有文件;新文件只包含复原现有redis状态的最终命令,因此大大降低了对磁盘空间的占用。
AOF重写会伴随大量的写入操作,因此redis会单独创建一个线程进行重写,此时不会阻塞redis服务器处理客户端的命令,但是也随之带来另外一个问题,就是进行重写的过程中,服务器继续处理客户端命令,会导致重写产生的aof文件与服务器最终命令不一致,此时需要额外引入一个aof重写缓冲区的概念(与aof_buf同步处理,主要目的是在aof重写期间不影响服务器对客户端的命令处理),即在重写子进程创建之后,会产生一个aof重写缓冲区,用于记录在aof重写期间服务器所接收处理的新命令;
当重写子进程完成之后,服务器会阻塞客户端命令,同时将aof重写缓冲区的内容写入到新的aof文件中,同时对新的aof文件重命名并原子的替换现有aof文件,至此aof重写即完成。