Caution
未完待续
1 RDB
Tip
- snapshot,快照
- 二进制格式
- 早期redis版本的默认方式
- 按照事先指定的频率,周期性都保存到磁盘
- 默认文件是dump.rdb
- 宕机后,数据会丢失一部分
redis.conf
Caution
如果你在60秒内 做了 999次操作, 然后这个时候redis服务器宕机了. 那么数据就不会写入磁盘,也就是说丢失了.
1.1 主动生成rdb快照
进入客户端
同步方式,在主线程中保存快照, 所以这个时候所有操作会阻塞,因为主线程就是用来执行client的请求的
- background save ,异步方式,client请求不会阻塞
- 调用fork创建一个子进程,父进程继续处理各个请求
- linux的写时复制cow特点,父子进程共享同一个物理空间,父进程会将操作的页面创建一个副本,而子进程的数据还是要开始保存的那个时间点
- 子进程负责将内存中的内容保存到临时文件,只有当其保存ok后,才会保存到真正的文件
- 执行完后,子进程退出
1.2 重放
- 就是将dump.rdb 重新加载到内存
- rdb比aof的重放速度快,直接文件重新写入 ,aof是重新执行命令
2 AOF
- append only file
- 记录每一次的写操作,几乎不会丢失数据,但是 这样性能肯定就没那么好了
- 因为写入磁盘本身 是先写到缓存的? 操作系统..
- 就是将你执行的redis命令 添加到指定的文件
- 文件会比较大
- 重启时,可以通过重新执行文件中的命令在内存中重建数据
redis.conf中开启aof
2.1 写入策略
2.2 重写优化
我们知道当redis重启时, 会将aof文件里的命令重新执行来达到重建数据的目的
- aof重写的问题
- aof 是重新执行了一遍命令, 肯定比rdb 重放慢
- 由于可能有很多无用的命令, 这个很好理解, 就是你后面的命令 直接覆盖了前面的, set a 1 ,set a 2,第一条命令实际就是没用的
- 比如你执行了100次的操作,可能只要一次就行了,但是保存的还是100语句
- 手动重写命令 bgrewirteaof 命令可以重写aof文件,合并一些操作
- 不会读取旧的aof文件
- 比如内存中的结果直接变成 它所对应的语句 写到临时文件
- 将内存中的文件保存到临时文件,最后替换真正的文件
- 过程
- 主进程通过fork 生成子进程
- 子进程根据内存中的数据创建数据库重建命令序列与临时文件中
- 父进程继续接收client的请求,会把这些请求的命令追加于原来的aof文件,为了防止重写失败,额外的会把这些新的请求写于一个缓冲队列中
- 子进程写完临时文件后,会通知父进程,父进程会把缓冲队列中的命令写到临时文件中
- 最后 父进程?用临时文件替换老的aof文
2.3 重写策略
3 redis 4.0以后 混合持久化
重启 Redis 时,我们很少使用 RDB来恢复内存状态,因为会丢失大量数据。我们通常使用 AOF 日志重 放,但是重放 AOF 日志性能相对 RDB来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很 长的时间。 Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化
- 就是结合了上面的2个
- 开启
- AOF在重写时,不再是单纯将内存数据转换为RESP命令写入AOF文件,而是将 重写这一刻之前的内存做RDB快照处理,并且将RDB快照内容和增量的AOF修改内存数据的命令存在一 起,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改 名,原子的覆盖原有的AOF文件,完成新旧两个AOF文件的替换。
- 于是在 Redis 重启的时候,可以先加载 RDB 的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,因此重启效率大幅得到提升。
- bgrewirteaof 后看下 aof文件,然后 set 写入 ,再看看文件里的内容