适合初学者的[JAVA]:Redis(3:Redis异常与持久化机制)

目录

说明

前言

Reids异常

缓存穿透:

缓存击穿:

缓存雪崩:

双写一致性:

Redis持久化:

一、什么是redis持久化

RDB和AOF:

RDB:

(1)生成快照的方式:

客户端方式:

服务端方式:

AOF(追加日志文件):

追加频率选项:

修改同步频率:

(3)AOF重写

AOF重写:

重写原理:

4)优缺点

优点:

缺点:


说明


本文适合刚刚学习Java的初学者,也可以当成阿岩~的随手笔记.接下来就请道友们和我一起来学习吧!

如果本文有写的不对的地方,请道友们一定要说出来,避免影响到刚刚学习Java的道友们,也让阿岩~进行更新于改进,在这里谢谢各位道友了!

前言


在上一篇中,我们已经了解到了RedisI/O多路复用和事件派发机制.让我们更加立体的了解到了Redis的快,这篇我们来了解一下Redis的面试题与Redis的不同模式与机制

Reids异常

Redis 正常多用于缓存: (异常): 穿透 击穿 雪崩 双写一致 持久化 数据过期 淘汰策略 分布式锁: (异常): sentnx redisson

缓存穿透:

当查询一个不存在的数据时,mysql查询不到也不会直接写入缓存.导致每次请求到要查询数据库. 会导致数据库压力增大,可能会导致数据库宕机

解决方案1: 缓存空数据: 当查询不存在的数据时,缓存一个null 然后就当在访问不存在的数据时,将不会查询数据库,而是由缓存直接返回一个null

解决方案2: 布隆过滤器: 当数据进入缓存时也会跟着进入布隆过滤器中,布隆过滤器本身有一个bitmap (bit)位为单位的数组,每个数组中每个单元只能存储二进制的0或1.初始化为0.当有数据进入这个数组时,会通过多个hash函数计算后进入hash函数对应的位置,这个位置将重0变成1,证明这个位置有数据.布隆过滤器可以用于检索一个元素是否在集合中.用hash值去判断对应的位置是否为1

缺点: 有可能出现误判: 当一个没有数据的元素的位置对应的分别的是1,那么就出现了误判.

修复: 增大数组,当数组增大时,出现误判的几率就会相对减小,但是带来了更多的内存消耗

优点: 减少占用的内存,没有多余的key

缓存击穿:

给某一个key设置了过期时间,当key过期的时候,恰好这时间有对这个key有大量的并发请求过来,这些并发的请求可能会瞬间把数据库压垮

解决方案1: 互斥锁(分布式锁) 当该key被访问时,会制造一个线程去查询缓存,发现已过期,就会获取互斥锁,查询数据库重写缓存数据,写入缓存,释放锁. 在这期间,其他访问线程将一值重试前两步骤,直到线程一释放锁后,进行访问.

解决方案2: 逻辑过期: 在数据写入缓存时,写入一个逻辑时间.当查询缓存发现逻辑时间已过期,就会获取互斥锁,返回过期数据,但是在返回过期数据之前会开启新线程去重写数据,重置逻辑时间.释放锁. 在这期间如果有其他线程访问数据,将获取锁失败,并返回过期数据,直到重写数据之后.

总结: 方案一(互斥锁)强一致,性能差 方案二(逻辑过期)高可用,性能优,不能保证数据绝对一致 根据不同需求进行选择

缓存雪崩:

缓存雪崩的意思是设置缓存时大多数key采用了同一个过期时间,导致缓存在某一刻同时失效,请求全部转发到了数据库,数据库在瞬间压力过大而雪崩

于缓存击穿的区别: 雪崩是很多key,击穿是某一个key缓存

解决方案: 主要可以将缓存失效时间分散开,比如可以在原有的失效时间基础上添加一个随机数,比如1~5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件,把key的过期时间不设置成一样的

双写一致性:

当修改完数据库中的时候,缓存没有修改就会产生缓存与数据库中的内容不一致的情况

方案一:延迟双删( 删除缓存 → 修改数据库 →延迟→ 删除缓存 )/延迟时间也有可能出现脏数据

方案二:读写锁,写时加锁,读不受影响/强一致,性能不高

方案三:异步通知:增加mq,修改数据库的时候,给mq发信息,mq监听缓存的信息.保证最后的一致行

方案四:基于Canal的异步:当数据库发生变化时,会通知缓存进行修改.Canal会记录二进制日志记录所有的DDL(数据定义语言)语句和DML(数据操纵语言)语句,但不包括(SELECT,SHOW)语句

Redis持久化:

一、什么是redis持久化

redis是基于内存的数据库。

优点是cpu读取内存速度快,一秒钟可以进行数十万次,可以直接和cpu速度相近,读取极快。 缺点是基于内存,存在断电数据丢失的情况。

为了防止其数据断电丢失,就需要将数据存入硬盘中,这样在断电后也可以访问到数据库当中的数据。

这个将内存的数据写入到磁盘中,防止服务器宕机内存数据丢失,就是redis的持久化。

RDB和AOF:

redis提供两种持久化机制:RDB和AOF

redis的默认持久化方式是RDB。

RDB:

RDB:是Redis DataBase缩写。

按照一定的时间将内存的数据以快照的形式保存到硬盘中,对应产生的数据文件为dump.rdb。

(1)生成快照的方式:

①客户端方式:BGSAVE 和 SAVE指令

②服务端方式:服务器配置自动触发 和 shutdown

客户端方式:

BGSAVE:客户端可以使用BGSAVE命令来创建一个快照,当接收到客户端的BGSAVE命令时,redis会创建一个子进程,子进程负责将快照写入磁盘中,而父进程继续处理命令请求。(在子进程创建之初,父子进程共享相同内存,知道父进程或子进程对内存进行了写之后,对于被写入的内存的共享就会结束服务) SAVE:客户端使用SAVE命令创建一个快照,接收到SAVE命令的redis服务器在快照创建完毕之前将不再响应任何其他的命令。

服务端方式:

服务器通过配置方式来满足自动触发快照进行持久化,管理员需要在redis.conf中设置save配置选项,redis会在save选项条件满足之后自动触发一次BGSAVE命令,如果管理员设置了多个save配置选项,当任意save条件被满足,redis都会触发一次BGSAVE命令。 shutdown指令:当redis通过shutdown指令接受到关闭服务器的请求时,会触发一次SAVE命令,阻塞所有的客户端,不再执行客户端发送的任何命令,在SAVE命令执行完毕后关闭服务器。 (2)优缺点 优点:

只有一个dump.rdb文件,方便持久化 容灾性好,一个文件可以保存到安全的磁盘中。 性能最大化,子进程来完成写操作,主进程可以继续处理命令,实现IO最大化(使用单独的子进程来进行持久化,主进程不会进行任何IO操作,保证了redis的高性能)。 相对于数据集大时,比AOF的启动效率更高。 缺点:

数据安全性第。RDB是间隔一段时间进行持久化,如果持久化之间redis发生故障,会发生数据丢失。 dump.rdb文件是一个redis中特制的二进制文件,涉及到不同的redis版本,可能会发生版本不兼容问题。

AOF(追加日志文件):

AOF:是Append Only File的缩写。

是指,将redis执行的所有写命令记录到日志文件中,将被执行的写命令写到AOF的文件末尾,当redis重启时,redis会从头到尾执行一次AOF文件所包含的所有写命令,以此回复AOF文件的记录的数据集。

redis默认配置中AOF持久化机制是不开启的,需要在配置中开启。

① 修改 appendonly yes 开启持久化 ​

② 修改 appendfilename “appendonly.aof” 指定生成文件名称

追加频率选项:

① always【谨慎使用】 ​ 说明:每个redis写命令都要同步写入硬盘,严重降低redis速度 ​ 解释:如果用户使用了always选项,会将发生系统崩溃时出现的数据丢失减到最少,但因为这种同步策略需要对硬盘进行大量的写入操 作,所以redis处理命令的速度会受到硬盘性能的限制。 ​ 注意:使用固态硬盘(SSD)时需谨慎使用always选项,这种模式不断写入少量数据,可能会引发严重的写入放大问题,导致固态硬盘 的寿命从原来的几年降低为几个月。

② everysec【推荐】 ​ 说明:每秒执行一次的同步显示,将多个写命令同步到磁盘 ​ 解释:同时保障了数据安全和写入性能,redis每秒一次对AOF文件进行同步,此时AOF文件性能和不使用任何持久化特性时的性能基本 相同;通过每秒同步一次AOF文件,redis可以保证,即使系统崩溃,最多丢失一秒之内产生的数据。

③ no【不推荐】 ​ 说明:由操作系统决定何时同步 ​ 解释:这个选项不好对redis性能带来影响,但是当系统宕机时,丢失的数据量具有不确定性;另外,如果用户硬盘处理写入操作不够 快,当缓冲区被等待写入硬盘数据填满时,redis会处于阻塞状态,导致redis的处理命令请求速度变慢。

修改同步频率:

修改appendfsync everysec | always | no

(3)AOF重写

AOF文件是以追加的方式记录接收到的写命令的,不断的追加会导致AOF文件过大。 文件过大导致的问题:

① 文件系统的限制:文件系统本身对文件的大小有限制,无法保存过大文件,如果超出限制,会导致 redis 宕机,redis 执行命令 速度会降低。

② 追加效率降低:AOF文件采用追加的方式写入文件,每次要遍历寻找到文件尾部,如果文件过大,追加效率会大幅度降低。

③ 执行效率降低:如果服务器发生宕机,AOF文件命令要逐一执行,文件过大导致执行内容过多,影响效率。

AOF重写:

用来一定程度上减小AOF文件的体积,解决文件过大的问题。

重写原理:

重写AOF的时候,创建一个重写子进程,然后读取旧的AOF文件,压缩并写入到一个临时AOF。

在此期间,主进程一边将接收到的指令累计到一个缓冲区中,一边将指令写入到旧的AOF。

(这样的好处,保证AOF文件的可用性,避免写过程时出意外)

子进程写完后,向主进程发送一个信号量,主进程就将缓冲区中的指令追加到新AOF。

用新的AOF替换旧的AOF,之后的新指令就追加到新的AOF。

4)优缺点

优点:

数据安全,AOF持久化可以通过配置appendfsync属性,设置其记录频率。 通过append模式写文件,即使服务器宕机,也可以通过redis-check-aof工具解决数据一致问题。 更加灵活。AOF机制的 rewrite 模式,AOF文件没被rewrite之前(文件过大时回对命令进行合并重写),可以删除其中的某些命令。

缺点:

AOF文件比RDB文件更大,且回复速度更慢。 数据集大时,AOF比RDB启动效率低。 当RDB和AOF同时开启时,redis数据恢复会优先选中AOF恢复。

                                                                                                                        ------阿岩~的随手笔记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值