1.续 Redis强化
1.1缓存穿透
所谓缓存穿透,就是一个业务请求先查询redis,redis没有这个数据,那么就去查询数据库,但是数据库也没有的情况
正常业务下,一个请求查询到数据后,我们可以将这个数据保存在Redis
之后的请求都可以直接从Redis查询,就不需要再连接数据库了
但是一旦发生上面的穿透现象,仍然需要连接数据库,一旦连接数据库,项目的整体效率就会被影响
如果有恶意的请求,高并发的访问数据库中不存在的数据,严重的,当前服务器可能出现宕机的情况
解决方案:业界主流解决方案:布隆过滤器
布隆过滤器的使用步骤
1.针对现有所有数据,生成布隆过滤器,保存在Redis中
2.在业务逻辑层,判断Redis之前先检查这个id是否在布隆过滤器中
3.如果布隆过滤器判断这个id不存在,直接返回
4.如果布隆过滤器判断id存在,在进行后面业务执行
1.2缓存击穿
一个计划在Redis保存的数据,业务查询,查询到的数据Redis中没有,但是数据库中有
这种情况要从数据库中查询后再保存到Redis,这就是缓存击穿
但是这个情况也不是异常情况,因为我们大多数数据都需要设置过期时间,而过期时间到时,这个数据就会从Redis中移除,再有请求查询这个数据,就一定会从数据库中再次同步
缓存击穿本身并不是灾难性的问题,也不是不许发生的现象
1.3缓存雪崩
上面讲到击穿现象
同一时间发生少量击穿是正常的
但是如果出现同一时间大量击穿现象就会如下图
所谓缓存雪崩,指的就是Redis中保存的数据,短时间内有大量数据同时到期的情况
如上图所示,本应该有Redis反馈的信息,由于雪崩都去访问了Mysql,mysql承担不了,非常可能导致异常
要想避免这种情况,就需要避免大量缓存同时失效
大量缓存同时失效的原因:通常是同时加载的数据设置了相同的有效期导致的
我们可以通过在设置有效期时添加一个随机数,这样就能够防止大量数据同时失效了
1.4Redis持久化
Redis将信息保存在内存
内存的特征就是一旦断电,所有信息都丢失,对于Redis来讲,所有数据丢失后,再重新加载数据,就需要从数据库从新查询所有数据,这个操作不但耗费时间,而且对数据库的压力也非常大
而且有些业务是先将数据保存在Redis,隔一段时间和数据库同步的
如果Redis断电,这段时间的数据就完全丢失了!
为了防止Redis的重启对数据库带来额外的压力和数据的丢失,Redis支持了持久化的功能
所谓持久化就是将Redis中保存的数据,以指定方式保存在Redis当前服务器的硬盘上
如果存在硬盘上,那么断电数据也不会丢失
Redis实现持久化有两种策略
RDB:(Redis Database Backup)
RDB本质上就是数据库快照(就是当前Redis中所有数据转换成二进制的对象,保存在硬盘上)
默认情况下,每次备份会生成一个dump.rdb的文件
当Redis断电或宕机后,重新启动时,会从这个文件中恢复数据,获得dump.rdb中所有内容
实现这个效果我们可以在Redis的配置文件中添加如下信息
save 60 5
上面配置中60表示秒
5表示Redis的key被修改的次数
配置效果:1分钟内如果有5个key以上被修改,就启动rdb数据库快照程序
优点:
因为是整体Redis数据的二进制格式,数据恢复是整体恢复的
缺点:
生成的rdb文件是一个硬盘上的文件,读写效率是较低的
如果突然断电,只能恢复最后一次生成的rdb中的数据
AOF(Append Only File):
AOF策略是将Redis运行过的所有命令(日志)备份下来,保存在硬盘上
这样即使Redis断电,我们也可以根据运行过的日志,恢复为断电前的样子
我们可以在Redis的配置文件中添加如下配置信息
appendonly yes
经过这个设置,就能保存运行过的指令的日志了
理论上任何运行过的指令都可以恢复
但是实际情况下,Redis非常繁忙时,我们会将日志命令缓存之后,整体发送给备份,减少io次数以提高备份的性能和对Redis性能的影响
实际开发中,配置一般会采用每秒将日志文件发送一次的策略,断电最多丢失1秒数据
优点:
相对RDB来讲,信息丢失的较少
缺点:
因为保存的是运行的日志,所以占用空间较大
实际开发中RDB和AOF是可以同时开启的,也可以选择性开启
Redis的AOF为减少日志文件的大小,支持AOF rewrite
简单来说就是将日志中无效的语句删除,能够减少占用的空间