文章目录
目录
前言
主要学习了Redis的RDB持久化机制。
一、基础知识
- RDB概念
- RDB是redis的一种持久化机制,可以通过配置save选项配置,实现每隔一段时间,调用BGSAVE命令,将数据库某一时刻的内存快照写入磁盘里,默认900s 1/300s 10/60s 10000次修改触发BGSAVE命令,然后在需要恢复时将磁盘中的dump.rdb文件直接读到内存里
- RDB保存的是一个dump.rdb文件,它是一个经过压缩的二进制文件,保存在磁盘里
- 需要RDB的原因
- Redis是一个内存数据库,需要定期将内存中的数据存储到磁盘里实现持久化,否则如果电脑宕机,会出现数据的丢失
- RDB优缺点
- 优点
- 大规模且对数据恢复完整性不敏感的恢复,RDB比AOF更高效
- 缺点
- RDB最后一次持久化可能会丢失数据
- 最后一次的rdb文件还没覆盖旧文件主机就宕机了,导致最后那段时间写的数据没有成功写入rdb文件里
- RDB最后一次持久化可能会丢失数据
- 优点
二、RDB文件(dump.rdb)创建
- SAVE
- 阻塞服务器进程实现RDB文件(dump.rdb)的创建,持久化期间不接受新请求
- BGSAVE
- 服务器fork一个子进程完成RDB文件(dump.rdb)的创建,这个子进程和当前进程完全一样,子进程会创建一个临时文件,数据写入完成后用这个文件替代之前的旧文件,主进程还可以继续处理其他的请求,但是不会进行任何的内存与磁盘交互数据的IO
- BGSAVE和BGREWRITEAOF两个命令处于性能的考虑不会同时执行
- 如果BGSAVE执行中出现BGREWRITEAOF命令,BGSAVE完成后再执行BGREWIRTEAOF
- 如果BGREWRITEAOF执行中出现BGSAVE命令,会拒绝执行BGSAVE
- 写RDB文件和重写AOF文件都不会写入过期键,过期键删除时记录它的DEL写入AOF文件
三、RDB文件载入
- Redis的载入策略是,先看看有没有开启AOF,因为AOF比RDB文件的更新频率更高,如果有AOF会载入AOF,如果没有AOF才载入RDB
- Redis没有命令实现载入,只要检测到了RDB文件会自动载入
- 载入过程中服务器进程阻塞
- 主模式载入过程不会载入过期键,从模式载入所有键
四、自动间隔性保存
- 如何配置
- 通过在配置文件里完成save选项的配置,可以间隔的执行BGSAVE指令,由子进程完成数据的拷贝
- 默认的配置是900秒修改1次;300秒修改10次;60秒修改10000次
- 底层实现
- saveparams数组:存三个saveparam,每个saveparam存秒数和修改数
- dirty计数器:记录键值修改次数,每次执行BGSAVE或者SAVE命令后清零
- lastsave属性:记录上一次SAVE或者BGSAVE的时间戳
- serverCron方法每隔100ms检查一次是否满足saveparam的条件,满足就执行一次BGSAVE
五、RDB文件结构
- REDIS:5B,用于标识RDB文件
- db-version:4B,一个字符串用于标识数据库版本
- databases:所有非空数据库(结构如下)
- SELECTDB+db-number:1B+1B,376+x,执行SELECT命令切换到db-number指定的数据库
- key-values-pairs:保存db-number数据库中的所有键值对(结构如下)
- 无过期时间
- TYPE:对象类型或底层编码之一
- key:是一个String类型的字符串,编码应该是SDS的RAW或者INT
- value
- string:长度+值;int编码直接保存,raw可以直接保存也可以通过LZF算法压缩保存,压缩保存被解析到会进行解压
- list/set:记录list/set的长度 + 所有元素
- hash/zset:记录元素个数 + 键&值/值&分数紧挨着排列
- INTSET/ZIPLIST(list/hash)底层编码:会被转换成字符串对象存储
- 有过期时间(从模式会载入过期对象,主模式不载入)
- EXPIRETIME-MS+ms:1B+8B,374+xxxxxxxx,这个键值对会在ms时间戳过期
- TYPE+key+value
- 无过期时间
- EOF:1B,377,结束标识符
- check-sum:8B,CRC校验码检查RDB文件是否出错