点一下关注吧!!!非常感谢!!持续更新!!!
目前已经更新到了:
- Hadoop(已更完)
- HDFS(已更完)
- MapReduce(已更完)
- Hive(已更完)
- Flume(已更完)
- Sqoop(已更完)
- Zookeeper(已更完)
- HBase(已更完)
- Redis (正在更新…)
章节内容
上节完成了的内容如下:
- Redis 持久化原因
- Redis 持久化机制 RDB AOF
- 基础概念、适用场景等
RDB
RDB(Redis DataBase),是Redis的默认存储方式,RDB是通过快照的方式(snapshotting)完成的。
触发方式
- 符合自定义配置的快照规则
- 执行 save 或 bgsave 命令
- 执行 flushall 命令
- 执行主从复制操作(第一次)
配置参数
在 redis.conf
中配置:save
显式触发
执行流程
- Redis 父进程判断:当前是否在执行 Save、bgsave、bgrewriteaof等等指令的子进程,如果在执行则bgsave命令直接返回
-
父进程
执行fork
操作创建子进程
,这个过程中父进程
是要进行阻塞
的,Redis
此时不能执行
来自客户端的任何命令
。 -
父进程fork后
,bgsave命令返回“Background saving started”
信息并不再阻塞父进程
,并可以响应
其他命令。 -
子进程
创建RDB文件
,根据父进程内存
快照生成临时文件
,完成对原有文件
进行原子替换
。 -
子进程
发送信号
给父进程
表示完成,父进程更新
统计信息。 - 父进程Fork结束后,继续工作。
文件结构
- 头部 5字节固定位 REDIS
- 4字节 RDB 版本号
- 辅助字段 以 KEY-VALUE
- 存储数据库号码
- 字典大小
- 过期 KEY
- 主要数据 以 KEY-VALUE
- 结束标志
- 校验和,看文件是否存坏,是否被修改
RDB优点
- RDB是
二进制压缩
文件,占用空间小
,便于传输 -
主进程Fork子进程
,可以最大化Redis性能,主进程不能够太大,否则会导致阻塞
RDB缺点
-
不保证
数据的完整性
,会丢失最后一次快照以后的数据
AOF
AOF(append only file)是Redis的另一种持久化方式,Redis默认
情况下是不开启
的。
Redis 将所有对数据库
进行写入命令
记录到AOF文件
中,这样 Redis 重启
后按顺序执行
这些指令即可恢复。AOF 会记录过程,RDB 是保存结果。
配置参数
同样,我们修改 redis.conf
具体原理
AOF 文件中存储的 Redis 的指令,具体过程有三个阶段:
-
命令传播:
Redis 将执行完的命令、参数等发送到 AOF 程序中 -
缓存追加:
AOF 程序根据接收到的命令数据,将命令转换为网络通讯协议格式,再追加到服务器的AOF缓存中。 -
文件写入保存:
AOF 缓存中的内容会被写入到 AOF 文件末尾,如果设定的AOF保存条件被满足的话,fsync函数或者fdatasync函数会被调用,写入的内容被真正的保存到磁盘中
保存方式
可以配置保存的方式如下:
- AOF_FSYNC_NO 不保存
- AOF_FSYNC_EVERYSEC 每一秒钟保存一次
(默认)
- AOF_FSYNC_ALWAYS 每一个指令保存一次
AOF 瘦身
平常会遇到如下的场景
或者是这种场景
Redis 不希望 AOF 重写造成服务器无法处理请求,所以 Redis 决定将 AOF 重写程序放入到后台中:
- 子进程AOF重写期间,主进程可以继续处理请求
- 子进程带有主进程的发数据副本,
使用子进程
不过使用子进程也有一个问题:
因为子进程在进行AOF重写期间
,主进程还需要继续处理命令,而新的命令
可能会对现有的数据进行修改
,这会让当前数据库
的数据和重写后
的AOF文件中的数据不一致
。为了解决不一致的问题
,Redis 加了一个 AOF 缓存,这个缓存在Fork出子进程之后,Redis主进程接收到新的写命令时,除了会将这个命令追加到现有的AOF文件,还会追加
到这个缓存中。
具体的逻辑图如下:
触发方式
可以修改 redis.conf
显式触发
持久化混合
RDB 和 AOF 各有优缺点
,Redis 4.0
版本之后开始支持 RDB + AOF
混合的模式。
如果在混合模式下,AOF rewrite时就直接把 RDB的内容写到 AOF 的开头。
如果要开启 混合模式 修改 redis.conf