Redis持久化
RDB(快照)持久化:保存某个时间点的全量数据快照
- save:阻塞redis的服务器进程,直到RDB文件被创建完毕;(save很少被使用,在主线程中保存快照,会阻塞所有client的请求)
- bgsave:fork出一个子进程来创建RDB文件,不阻塞服务器进程;
自动化触发RDB持久化的方式
- 根据redis.conf配置里的save m n 定时触发(用的是bgsave);
- 主从复制时,主节点自动触发;
- 执行debug reload;
- 执行shutdown且没有开启AOF持久化
BGSAVE原理
系统调用fork():创建进程,实现了copy-on-write;(旧方法:传统情况下,fork函数在创建子进程时直接把所有资源复制给子进程,这种实现方式简单,但是效率低下,而且复制的资源可能毫无用处。新方法:
Linux为了降低创建子进程的成本,改进fork实现,当创建子进程时,内核只为子进程创建虚拟空间,父子两个使用相同的物理空间,只有父子进程发生更改时才会为子进程分配独立的物理空间,这就是copy-on-write)
copy-on-write
如果有多个调用者同时要求相同资源(如内存或磁盘上的数据存储),他们会共同获取相同的指针指向相同的资源,直到某个调用者试图修改资源的内容时,系统才会真正复制一份专用副本给该调用者,而其他调用者所见到的最初的资源仍然保持不变。
RDB持久化
缺点:
- 内存数据的全量同步,数据量大会由于I/O而严重影响性能;
- 可能会因为redis挂掉从而丢失从当前到最近一次快照期间的数据。
redis.conf 配置
触发备份条件:
save 900 1
save 300 10
save 60 10000
禁用rdb设置:save “”
stop-writes-on-bgsave-error yes —— 当备份进程出错的时候,主进程停止接收新的写入了 ,如果自己的业务有完善的监控系统就可以关闭
rdbcompression yes —— yes 表示对rdb文件进行压缩之后再保存,redis本身属于CPU密集型服务器,再开启压缩会带来更多的CPU消耗,CPU成本比内存成本更高,建议设置为no
根目录下的dump.rdb文件就是保存数据的文件,是一个二进制文件。
AOF(Append-Only-File)持久化:保存写状态
- 记录下除了查询以外的所有变更数据库状态的指令;
- 以append的形式追加到AOF文件中(增量);
AOF开启配置设置(修改redis.conf)
- appendonly no ——no表示关闭AOF文件生成,yes表示打开
- appendfilename “appendonly.aof” ——AOF文件的文件名
- appendfsync everysec/always/no ——always表示一有变化马上存进去,everysec则表示每隔一秒去写入到AOF文件,no则表示将写入AOF操作交由系统来决定,即等到缓存区满了之后才写入AOF文件。推荐使用everysec。
注:修改完配置文件后需要重启redis才能生效
AOF文件大小不断增大的解决方法——日志重写
- 调用fork(),创建一个子进程;
- 子进程把新的AOF临时文件中,不依赖原来的AOF文件(AOF的重写是直接把当前的数据生成对应命令,并不需要读取老的AOF文件进行分析或者进行命令的合并);
- 主进程会持续将新的变动同时写进内存和原来的AOF里;(这样即使重写失败,也能保证数据的安全);
- 主进程获取子进程重写AOF的完成信号,往新AOF同步增量变动;(刚才存进内存的增量变动此刻就可以往新AOF中写入了,最后一句说的就是写入过程中的增量)
- 使用新的AOF文件替换掉旧的AOF文件
bgrewrite 命令可以重写AOF文件,也可以修改配置定时重写AOF文件
redis数据的恢复
RDB和AOF文件共存条件下的恢复流程:
RDB 和AOF的优缺点
- RDB优点:全量数据快照、文件小、恢复快
- RDB缺点:无法保存最近一次快照之后的数据
- AOF优点:可读性高、适合保存增量数据,数据不易丢失
- AOF缺点:文件体积大、恢复时间长
AOF基本上是人类可读的,RDB是人类不可读的。
RDB-AOF混合持久化
bgsave做镜像全量持久化,AOF做增量持久化