Redis底层原理-持久化【详细易懂】
Redis底层原理-持久化
好久没更文了,最近开始重拾自己技术博文,并整理沉淀下自己的技术,
因为之前感觉都是你一说,我感觉会,但是真叫我说,我又说不出来
哈哈哈!尴尬的场面(别问了,本人亲身体验过)
不废话了,一起吸收一波吧!
主要支持的两种持久化机制: RDB和AOF
文章目录
- Redis底层原理-持久化
- RDB
- 思考:`bgsave`问什么可以不阻塞?(面试题)
- 思考:快照时数据能修改吗?
- AOF(Append Only File)
- 思考:AOF的持久化原理是什么?
- 思考:Redis重启时如何启动的呢?流程是什么?
- RDB-AOF混合持久化
- 思考: 主线程,子线程和后台线程的联系与区别?
- 思考: `Redis`的持久化过程有没有一些风险?
- 思考: 为什么主从复制不使用`AOF`
- 完结
RDB
RDB文件的生成是否会阻塞主线程?分情况
save:阻塞主线程
bgsave:创建子进程(专门写入RDB文件) 也是自动保存(配置文件中)的命令

但是手动确很不方便,怎么自动进行配置?—>
1.配置文件中:save命令操作
我们在Redis安装目录中的redis.windows-service.conf(里面用的就是bgsave)

2.自动机制: shutdown
从节点执行全量复制操作,主节点自动执行
bgsave生成一个RDB文件发给从节点,
3.使用sqve "":关闭持久化,就是一个纯内存的的缓存软件
思考:bgsave问什么可以不阻塞?(面试题)
我们看下方此图
答案:
- 避免不阻塞采用一个技术: 写时复制机制
- 首先主线程在运行时,会花费一个
t1主线程->子进程的时间去fork一个子线程(fork的过程会阻塞) - 接下来: 对于主线程是读取的操作,则没有任何影响,主线程正常到内存读取(然后到子进程保存)
- 但是:若是修改的操作,如下图所示,主线程修改键值对B,
Redis的会在内存中启动写时复制来保存主线程的当前修改操作的键值对B值 - 最后将主线程的读或者写的操作交给子进程写成快照保存

RDB保存的快照文件默认采用LZF压缩算法来保存,在配置文件中(默认开启)
rdbcompression yes

如果检验快照文件是否损坏?怎么检查
找到你安装的
Redis目录,打开cmd黑窗口,输入如下命令

思考:快照时数据能修改吗?
当然能!!为什么?
答案:
- 我们每次的保存,正如上面的配置文件中保存
bgsave命令,都会修改快照文件数据,所以能修改 - 但是会存在一个问题,如下图所示,会存在数据的丢失问题,这
RDB弊端怎么解决呢?

接下来,我们就需要引入AOF了
AOF(Append Only File)
开启的命令:
appendonly yes

思考:AOF的持久化原理是什么?
结合下图理解
-
首先
lpush操作命令写入 -
然后第1步采用
append的AOF缓冲区进行写入,采用RESP协议(文本协议)我们看下图可以看到AOF缓冲区里面的一堆字符 -
第2步:我们会看到
appendfsync:表是缓冲区向磁盘写(三个参数)表示写入的时间,当中的everysec:每隔一秒进行保存,no:没有间隔(追求高性能) -
第3步:
rewrite重写机制,将AOF的缓冲区的文件通过rewrite进行AOF的重写缓冲,减少文件的大小(重写目的为了避免重复)
-
注意:我们看下图,命令写入的时候(在重写的过程中都可),
00-后续的命令写入,也会进行AOF重写缓冲(就是不是首次的命令) -
最后:当
Redis进行重启的时候,Redis就会拿着AOF文件进行对照着恢复了
AOF持久化的整个流程图

思考:Redis重启时如何启动的呢?流程是什么?
- 1.首先查看是否开启AOF,
- 2.是的话,进行检测有没有
AOF文件有就进行加载,没有就加载RDB文件 - 3.否的话:检测有没有
RDB文件,有则进行加载RDB文件,没有就正常启动(啥都不加载) - 4.判断启动是否成功: 是就成功,否就失败
- 总之:优先加载
AOF,再看RDB

通过上面的阅读,我们也了解了AOF对性能要求高,RDG又存在数据丢失的问题,都不完美(要做全量),怎么办呢?有没有中间方案?
答案:有的(哈哈哈!~)我们继续往下看
RDB-AOF混合持久化
开启命令:
aof-use-rdb-preamble yes

全流程图
我们可以看到
rewrite的过程中下方的AOF文件,首先加载RDB文件混合模式写入的时候: 在
rewrite首先保存成RDB(更快),后面使用AOF防止数据丢失和性能(避免阻塞)

注意:AOF不是不丢失数据,只是在缓存中丢失很少,比RDB的全量复制更好
举个例子:
AOF相当于签到表有个记录就行,RDB相当于开会,必须全员都来,否则不能开(全量复制)
思考: 主线程,子线程和后台线程的联系与区别?
如下图所示:

Redis的主线程只有一个:主要用来处理客户端的命令请求,执行相应的操作,并返回对应的结果(多个请求就顺序执行)- 后台线程: 异步处理,不会阻塞主线程
- 子进程: 是
Redis的一个特例,用来Redis的持久化的操作- 一般而言: 主进程和子进程一般会共用一块内存区域
- 进程: 作为分配资源的单位,
- 线程: 是
CPU调度和执行的一个实体
思考: Redis的持久化过程有没有一些风险?
答案: 肯定有
Redis在持久化的fork过程中,会有一些卡顿(因为此过程会产生阻塞)
思考: 为什么主从复制不使用AOF
- 因为作为
RDB文件来说,它本身是二进制文件,所以这个文件无论是写入磁盘还是作为网络传输,他的效率都会比AOF高 - 另外: 看下图,就知道,
RDB从主到从,采用二进制文件生成快,到从恢复也快,不像AOF采用追加的方式一个一个命令的写入

完结
好了,关于
redis的持久化相关知识就分享到这码字不易,求关注,求点赞啊!~哈哈哈!一起加油,顶峰见!

