长春网站怎么推广,做外汇门户网站,海洋公司做网站,西安网站推广公司后面更新的这些文章是将所学的redis知识进行巩固并且分享#xff0c;也希望这些知识不仅仅是用于复习面试#xff0c;更能在实际的应用中起到优化的作用。
有时候我们会存储一些查询多#xff0c;修改少#xff0c;业务逻辑较弱的数据#xff0c;并且还能高效查询#x… 后面更新的这些文章是将所学的redis知识进行巩固并且分享也希望这些知识不仅仅是用于复习面试更能在实际的应用中起到优化的作用。
有时候我们会存储一些查询多修改少业务逻辑较弱的数据并且还能高效查询那么redis就是一种选择。
redis缓存三件套 所谓的缓存三件套说白了就是在高并发的场景下因为一些奇奇怪怪的操作或者原因导致大量的请求没有去请求redis而是去请求数据库了而数据库的连接是有限的一旦超过了就会出事。因此我们的最终目的就是减少或者尽量不去访问数据库。其实解决方法我觉得可以分为外在和内在外分为如何控制请求量内在于如何处理这些请求量。
内在操作
缓存穿透 大量并发去访问一个数据库不存在的数据由于缓存中没有该数据导致大量并发查询数据库这个现象要缓存穿透。缓存穿透可以造成数据库瞬间压力过大连接数等资源用完最终数据库拒绝连接不可用。
解决
如何解决缓存穿透?
1、对请求增加校验机制
如果请求参数不符合我们规定的条件就直接让他滚蛋返回恶意攻击拜拜。
2、使用布隆过滤器
百度百科
布隆过滤器可以用于检索一个元素是否在一个集合中。如果想要判断一个元素是不是在一个集合里一般想到的是将所有元素保存起来然后通过比较确定。链表树等等数据结构都是这种思路. 但是随着集合中元素的增加我们需要的存储空间越来越大检索速度也越来越慢(O(n),O(logn))。不过世界上还有一种叫作散列表又叫哈希表Hash table的数据结构。它可以通过一个Hash函数将一个元素映射成一个位阵列Bit array中的一个点。这样一来我们只要看看这个点是不是1就可以知道集合中有没有它了。这就是布隆过滤器的基本思想。
布隆过滤器的特点是高效地插入和查询占用空间少查询结果有不确定性如果查询结果是存在则元素不一定存在如果不存在则一定不存在另外它只能添加元素不能删除元素因为删除元素会增加误判率。
我们可以利用如果不存在则一定不存在的特性来运用过滤器去查询。
比如将商品id写入布隆过滤器如果分3次hash此时在布隆过滤器有3个点当从布隆过滤器查询该商品id通过hash找到了该商品id在过滤器中的点此时返回1如果找不到一定会返回0。
所以为了避免缓存穿透我们需要缓存预热将要查询的内容提前存入布隆过滤器添加数据时将信息的id也存入过滤器当去查询一个数据时先在布隆过滤器中找一下如果没有到到就说明不存在此时直接返回。
实现方法有
Google工具包Guava实现。
redisson 。
2、缓存空值或特殊值
请求通过了第一步的校验查询数据库得到的数据不存在此时我们仍然去缓存数据缓存一个空值或一个特殊值的数据。
但是要注意如果缓存了空值或特殊值要设置一个短暂的过期时间。
缓存击穿
缓存击穿是指大量并发访问同一个热点数据当热点数据失效后同时去请求数据库瞬间耗尽数据库资源导致数据库无法使用。
解决
1、使用同步锁控制查询数据库的线程
使用同步锁控制查询数据库的线程只允许有一个线程去查询数据库查询得到数据后存入缓存。
锁的话就会想到sychronized这锁很明显重量级锁效率太低。相比于sychronized这种读多写少的情况更适合用ReentrantReadWriteLock,Semaphore,StampedLock读写锁。
同时我们应该尽量减少锁控制的代码块可以使用双重校验也可以用乐观锁来提高效率。
2、热点数据不过期
可以由后台程序提前将热点数据加入缓存缓存过期时间不过期由后台程序做好缓存同步。
缓存雪崩
缓存雪崩是缓存中大量key失效后当高并发到来时导致大量请求到数据库瞬间耗尽数据库资源导致数据库无法使用。
造成缓存雪崩问题的原因是是大量key拥有了相同的过期时间如果高并发查询大量的课程信息那么固定时间后就会过期一旦失效将同时失效造成雪崩问题。
解决
我们要知道缓存雪崩的原因出现在请求量大大量key过期时间相同。所以我们应该对症下药
1、使用同步锁控制查询数据库的线程
主题的做法在击穿里已经说明 2、缓存预热
不用等到请求到来再去查询数据库存入缓存可以提前将数据存入缓存。使用缓存预热机制通常有专门的后台程序去将数据库的数据同步到缓存。
3、对同一类型信息的key设置不同的过期时间
通常对一类信息的key设置的过期时间是相同的这里可以在原有固定时间的基础上加上一个随机时间使它们的过期时间都不相同。 总结下来就是尽量做到控制请求量防止数据不存在热点数据过期时间设置过期时间key随机。 外在操作
网关
网关不仅仅可以用来处理负载均衡权限认证跨域还可以限流。
全局过滤器的作用也是处理一切进入网关的请求和微服务响应与GatewayFilter的作用一样。区别在于GatewayFilter通过配置定义处理逻辑是固定的而GlobalFilter的逻辑需要自己写代码实现。
定义方式是实现GlobalFilter接口。
public interface GlobalFilter {/*** 处理当前请求有必要的话通过{link GatewayFilterChain}将请求交给下一个过滤器处理** param exchange 请求上下文里面可以获取Request、Response等信息* param chain 用来把请求委托给下一个过滤器 * return {code MonoVoid} 返回标示当前过滤器业务结束*/MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain);
} 在filter中编写自定义逻辑可以实现下列功能
登录状态判断,权限校验,请求限流等
sentinel
这也是一个微服务中间件这里先不再详细介绍。