目录
一、缓存的概念
1.为什么需要把用户的权限放入redis缓存
2.为什么减低了数据库的压力呢?
3.那么什么情况下用redis,什么情况下用mysql呢?
4.关于权限存入redis的逻辑?
二、使用缓存出现的三大情况
1.缓存穿透
1.1概念
1.2出现原因
1.3解决办法
1.4特点
2.缓存击穿(与缓存穿透容易记混,击穿的威力大,所有请求打在一个key上,直接把缓存穿掉了)
2.2解决办法
2.3特点
3.缓存雪崩
3.1概念
3.2解决办法
三、缓存预热
四、缓存更新
1.使用缓存存在数据一致性问题
2.如何保证最终数据一致性
一、缓存的概念
1.为什么需要把用户的权限放入redis缓存
因为用户的权限是一个读大于写的操作,所以对用户权限的查询就不必说每次都去Mysql数据库中查询,可以将第一次查询的结果放入redis缓存中,这样就减少了数据库的交互,降低了给数据库带来的压力,并且提高了查询速度
2.为什么减低了数据库的压力呢?
因为数据库可以接受的同时访问数量为5000,如果在高并发的情况下去查询同一个用户的权限,那么很可能导致数据库承受不住这个访问的压力,所以将第一次查询的结果放入redis缓存中,先从redis缓存中查询数据,redis缓存可以接受在高并发的情况下最大访问数为十万,并且redis的数据是存储在内存中的,而mysql的数据是存储在硬盘中的需要进行IO读写,所以redis读取数据会比mysql快,所以效率就高
3.那么什么情况下用redis,什么情况下用mysql呢?
这就要说mysql和redis的区别了,mysql是关系型数据库,它里面的关系都是由表和字段组成,并且还可以存在约束关系,哪怕某个数据为空,它也是存在表中的,他是一个表的部分
而redis是非关系型数据库,它里面都是通过键值对存储数据的,所以它数据的展示可以是不规则的,它可以只存储有必要的数据,而mysql哪怕为空也是在表中显示的
并且 mysql是持久型数据库,数据存储硬盘,它可以做一些持久化的操作,存储永久和真实重要的数据
redis是缓存型数据库,它的数据存储在内存,所以它可以做一些计算
其实关于它们的使用 一般是结合使用,通过redis首先做一道缓存,提高效率和降低数据库压力,
mysql做持久化,保证数据的真实性和安全性,当我们需要的数据必须是真实可靠的,这个时候就可以直接去数据库中查询
4.关于权限存入redis的逻辑?
首先对于查询权限的请求,先去redis缓存中中查找是否有这个用户的权限,如果有这个权限那么直接将这个权限返回给调用者,如果缓存中没有这个用户的权限,那么就去数据库中找,如果数据库中有数据,那么直接返回给调用者,如果数据库中也没有用户的权限,那么在缓存中设置一个默认值,下次同样的请求发过来,直接从redis缓存中取用户的权限,如果是默认值,说明数据库也没有这个权限,这个时候就可以不必去查找数据库了,这样就提高了查询效率并且解决了因为缓存中没有权限而每次去访问数据库给数据库带来的压力,也就是缓存击透
二、使用缓存出现的三大情况
1.缓存穿透
1.1概念
缓存穿透:就是指查询请求每次都无法在缓存中找到对应的数据,缓存失效,导致每次请求都直接打到了数据库,即使数据库中也不存在相应的数据,也会对数据库进行频繁查询,这会增加数据库的压力,降低系统性能
1.2出现原因
恶意请求、随机查询等原因引起的
1.3解决办法
(1)设置默认值并且设置较短的过期时间
当从缓存中得到的是一个默认值,说明数据库也没有我们要查询的数据,所以我们直接 不去数据库中查了,并且设置较短的过期时间,以防止缓存中一直保存无效数据(保证 数据的最终一致性)
1.4特点
缓存没有要查询的数据,数据库也没有要查询的数据
2.缓存击穿(与缓存穿透容易记混,击穿的威力大,所有请求打在一个key上,直接把缓存穿掉了)
2.1概念
在并发的情况下,大量的请求同时访问redis缓存中的一个热点key,而这个热点key已经过期了,所以导致所有请求打到了数据库,导致数据库对同一条数据进行了多次查询操作
2.2解决办法
(1)锁机制:当多个请求过来的时候,调用方法从redis中中获取数据,如果redis获取的数据为空,那么就加锁,得到锁资源后,然后再去redis缓存中获取一次,如果redis获取的数据为空,那么去mysql中获取数据,然后存入redis,如果并不为空则返回数据;如果没有得到锁资源,那么递归方法;
(2)布隆过滤器:可以判断出这个数据可能存在和一定不存在。
为什么布隆过滤器可以判断:因为底层是一个hash结构(数组+链表)。
当我们查询一个数据(key)的时候,可以根据hash算法得到它的hash值,然后根据hash值去hash数组中找到这个位置,看这个位置是否有值,如果没有值,说明数据一定不存在,不用去数据库中找了,如果有值说明可能存在,因为数组里面一个链表,有值并不代表是我们要找的数据
如果出现了hash碰撞并且这个链表上有数据就说明有可能存在,可以去查询数据库。
2.3特点
缓存中没有要查询的数据,数据库中有要查询的数据
3.缓存雪崩
3.1概念
在同一个时间点上大量的key同时过期,同时有大量的请求查询这些key,导致缓存没有命中,都打到了数据库,给数据库带来了巨大的压力,甚至宕机
3.2解决办法
给每个key设置不同的过期时间,让它们分时间段的过期
那样就不会导致同一时间大量的请求打到数据库
三、缓存预热
有预估性的知道某些数据可能会被大量的访问,所以可以进行缓存预热,提前将数据从数据库中取出存入缓存中,提高查询效率
四、缓存更新
1.使用缓存存在数据一致性问题
使用了缓存那么必然就会存在一个redis缓存与mysql数据库之间的一个数据一致性问题
因为他们是两个数据库,我们无法保证它们的操作都能同时执行成功,无法保证它们的原子性,所以我们只需要保证它们的最终一致性就好了,某个时间段数据不一致没关系
2.如何保证最终数据一致性
(1)当mysql的数据发生修改后,我们需要把缓存中的数据删除
(2)给key设置一个过期时间,让它自己到期删除
并且在需要真实可靠的数据的时候我们可以直接查询数据库确保数据的真实性