## 什么是Re
dis的持久化
我们知道Re
dis的数据都存储在内存中,如果服务器突然宕机,那么内存数据将会全部消失,为了防止这种情况出现,利用一套机制来保证数据不会因为故障而丢失,我们将这种机制称之为*Re
dis的持久化机制*,该机制主要目的是将*内存数据存入到硬盘*中
Re
dis 提供两种持久化机制RDB(Re
dis DataBase)和AOF(Append-Only File)机制。
## RDB-快照
快照是最简单的Re
dis持久化模式,也就是
生成某个时间点的数据集,
生成RDB
文件,可以看到RDB
文件中的数据是非常紧凑的,所以在恢复数据的时候读取也是非常快的

触发RDB快照的方式有两种
#### 手动触发
通过手动执行bgsave/save,
显示触发
生成快照
* save命令:阻塞当前Re
dis服务器,直到RDB过程完成为止,对于内存 比较大的实例会造成长时间阻塞,线上环境不建议使用
* bgsave命令:Re
dis进程执行fork操作创建子进程,RDB持久化过程由子 进程负责,完成后
自动结束。阻塞只发生在fork阶段,一般时间很短
#### 配置参数
自动触发
自动触发有以下几种情况:
* 使用save相关配置,命令*save m n*。表示m秒内数据集存在n次
修改时,
自动触发bgsave
* *从节点执行全量复制*操作,主节点
自动执行bgsave
生成RDB
文件发送给从节点
* *执行debug reload命令*重新加载Re
dis时,
自动触发save命令
* *执行shutdown命令*时,如果没有开启AOF持久化
功能自动执行bgsave
> 注意:在RDB持久化的过程中有两个问题需要考虑
>
> 1. RDB快照过程中Re
dis是否会停止对外提供服务
> 2. 如果没有停止服务,如何处理新的请求
针对上述问题我们先看一下RDB的持久化执行流程

根据上图我们可以看到主线程主要是*fork
一个子线程*来进行持久化操作,同时父子线程会*共享
一个数据区域*,而且该区域设置为read-only方式,该方式下读的时候没有问题,但是写的时候会*触发
copyonwrite机制*来进行,接下来我们看看什么是 COW(
copy On Write) 机制 。
#### COW(
copy On Write) 机制
COW(
copy On Write) 机制属于操作系统处理多进程下的一种机制,Re
dis在持久化的时候会
调用*glibc*
函数fork
一个子进程。父子进程会共享内存里面的
代码段和数据段。
所以持久化的时候是完全交给子进程,而父进程继续处理客户端请求,所以在持久化的时候操作系统采用COW机制进程数据段
页面的分离。数据段是由很多操作系统的
页面组合而成,当父进程对其中
一个页面进行数据
修改的时候,先将被父子线程共享的这
一个页面复制并分离出来,然后直接对复制的
页面进程
修改,而此时子进程对应的
页面是没有
修改的。
> Re
dis采用该机制的简单流程如下。Lunix在fork之后,操作系统会将*父进程的所有内存也权限设置为read-only*,然后子进程的地址空间指向父进程。当父进程只读时没有问题,当有写内存时,*
cpu硬件检测到内存也是read-only,于是会触发页异常中断(page-fault)*,陷入到操作系统的
一个中断例程。中断例程中,操作系统采用cow机制会触发异常的也复制一份,于是*父子进程各自持有独立的一份*,如果这个时候又大量写入操作,会产生大量的
分页错误(页异常中断page-fault),从而触发cow机制。
之所以称之为快照也就是说在子进程创建的那一时刻开始。内存的数据就固定下来了,不会发生变化。
#### RDB的优缺点
##### 优点:
1. *
性能最大化*,fork子进程来完成写操作,让主进程继续处理命令,保证了re
dis的高
性能
2. 重启恢复数据的时候。数据量比较大时候,Re
dis直接解析RDB二进制
文件,
生成对应的数据存储在内存中,*比AOF的启动效率更高*
##### 缺点
1. *数据安全性低*,因为是间隔一段时间进行持久化,如果在持久化之间发生了故障,会丢失数据,这也就决定了该方式更适合在数据要求不严谨的时候采用
2. *系统
性能耗费*,根据上文提到的Re
dis执行cow机制时,可以看到大量的*
分页错误会耗费不少
性能在复制上*。
## AOF(Append Only File - 仅追加
文件)
根据上文,快照在某些情况下不是可行的选择,所以AOF很好的
支持了。
#### AOF 原理
该方式非常简单:也就是
修改内存的操作命令都会记录下来,加入AOF日志记录都是Re
dis实例创建以来的所有
修改性指令序列,所以恢复也就是顺序执行所有执行。

Re
dis使用单线程相应命令,如果每次写AOF
文件命令都追加到硬盘,会极大地影响处理
性能,所以*Re
dis会先写入到aof缓冲区*,根据
用户配置的同步硬盘策略写入到aof
文件中,这个*策略可以通过appendfsync参数配置*,
* always:*每一次写操作都会
调用一次fsync*,这时数据是最安全的,当然,由于每次都会执行fsync,所以其
性能也会受到影响
* no:Re
dis不会主动
调用fsync去将AOF日志
内容同步到磁盘,所以这一切就*完全依赖于操作系统的调试了*。对大多数Linux操作系统,是每30秒进行一次fsync,将缓冲区中的数据写到磁盘上。
* everysec:*Re
dis会
默认每隔一秒进行一次fsync
调用*,将缓冲区中的数据写到磁盘。*但是当这一次的fsync
调用时长超过1秒时。Re
dis会采取延迟fsync的策略*,再等一秒钟。也就是在两秒后再进行fsync,这一次的fsync就不管会执行多长时间都会进行。这时候由于在fsync时
文件描述符会被阻塞,所以当前的写操作就会阻塞。
> 注意,这也是影响Re
dis性能的参数之一,建议采用 appendfsync everysec(缺省方式)
#### AOF重写
所谓重写,Re
dis在长期运行过程中日志会越来越大,在恢复的时候会非常好使,所以我们的目的就是对日志做瘦身
会从以下几点做瘦身:
1. *无效命令可以
删除*,比如del key1、hdel key2、srem keys、set a111、set a222等,直接用最终的数据
生成命令保存下来就行
2. *多条命令可以
删除*,如:lpush list a、lpush list b、lpush list c可以转化为:lpush list a b c
3. 等等,就不列举了
Re
dis使用bgrewriteaof指令做瘦身,主要也是开辟
一个子进程对内存遍历转化为一系列指令,并序列化到新的
文件中,接下来再将操作期
间的增量AOF日志追加到新的日志
文件中,最终替换了旧的。
AOF重写机制两种方式触发
1. 手动触发:*bgrewriteaof指令*
2.
自动触发:*根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定
自动触发时机*
* auto-aof-rewrite-min-size:表示运行AOF重写时
文件最小体积,
默认为64MB。
* auto-aof-rewrite-percentage:代表当前AOF
文件空间 (aof_current_size)和上一次重写后AOF
文件空间(aof_base_size)的比值。
```
auto-aof-rewrite-min-size????100auto-aof-rewrite-percentage??64mb复制
代码
```
> 如上代表AOF
文件的大小小于64mb(
默认值),且当前AOF
文件大小比基准大小增长了100%时会触发。
#### AOF优缺点
##### 优点
*数据安全*,aof持久化配置appendfsync
属性,有always,每执行一次命令操作就记录到aof
文件一次
##### 缺点
数据集大的时候,*比如RDB启动效率低*
## 混合持久化(Re
dis 4.0版本)
我们根据上文知道,RDB恢复会存在大量数据,AOF恢复
性能又较慢,所以在Re
dis4.0中,采用混合持久化,将RDB
文件内存和增量的AOF日志
文件放在一起,这里的AOF日志不再是全量日志。*而是自持久化开始到持久化结束的这段时
间的增量日志*,通常较小,重启效率因此大幅得到提升

加载的时候,首先会识别AOF
文件是否以RE
dis字符串开头,如果是就按照RDB格式加载,加载完成后继续按AOF加载剩余的部分
### 最后
光给面试题不给答案不是我的风格。这里面的面试题也只是凤毛麟角,还有答案的话会极大的**
增加文章的篇幅**,减少
文章的可读性,**因此仅以截图展示,[需要的小伙伴可以点击这里即可免费
获取!](https://docs.qq.com/doc/DSmxTbFJ1cmN1R2dB)**
# Java面试宝典2021版


# 最常见Java面试题解析(2021最新版)


# 2021企业Java面试题精选


版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。