衡阳网站设计公司,视频网站备案,php商城,wordpress电视主题先理解概念#xff1a;【注#xff1a;我们这里说的是分布式、高并发环境】 一、缓存穿透是什么#xff1f; 缓存穿透是指#xff1a;请求【可以有很多】的数据在缓存、关系型数据库中都不存在#xff0c;每次来查询都会查询到关系型数据库中。 解决方案#xff1a; 1、将…先理解概念【注我们这里说的是分布式、高并发环境】 一、缓存穿透是什么 缓存穿透是指请求【可以有很多】的数据在缓存、关系型数据库中都不存在每次来查询都会查询到关系型数据库中。 解决方案 1、将空对象缓存到Redis 简单的说就是第一次如果去关系型数据库查询回来如果为空就将将空值也缓存到Redis如set keyxxx null可以将过期时间设置短一点避免大量的null值占用内存如遇到key值饱和攻击将会是很大的麻烦内存会被这些空值大量占用。
优点实现简单。 缺点不存在的key-value占用内存高并发环境多个线程同时访问可能存在缓存过期前或者刷缓存前查询都为空返回不了真实数据。
2、使用布隆过滤器 所谓布隆过滤器就是一个很大的bitmap由二进制向量表和一系列随机映射函数组成。里面并不存放真实的数据里面只是标识位0/1某个key在hash过后来查不用过滤器返回为0就表示数据库不存在该数据直接给请求返回为空就行有值就是1然后就可以查询缓存服务器或者去查关系型数据库了。实现方案redissonredisredisson本来就封装好了布隆过滤器、guava、fpp都可以。
------------------- redisson方案
dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId/dependencydependencygroupIdorg.redisson/groupIdartifactIdredisson-spring-boot-starter/artifactIdversion3.13.0/version/dependency
/dependencies------------------- guava方案dependencygroupIdcom.google.guava/groupIdartifactIdguava/artifactIdversion29.0-jre/version
/dependency优点布隆过滤器内存占用较少 缺点实现相对复杂一丢丢、布隆过滤器存在误判【原因是hash冲突如果key的hash值相同就会引起本来没值的key判断成了有值去查Redis或者MySQL】。
二、缓存击穿是什么 缓存击穿指一个被高并发访问且缓存重建业务较复杂的key突然失效了无数查询这个key的请求瞬间会直接打在关系型数据库上给数据库带来了巨大的压力通常也叫热点Key问题。 解决方案
1、互斥锁 高并发环境避免缓存不存在这个key的数据然后多个线程并发的去访问数据库我们需要在查询缓存结束没有数据后在查询数据库前需要设置一道分布式锁拿到锁的才可以执行后续逻辑拿不到的可以让他等待一段时间重试缓存是否有数据这里不能重试查询关系型数据库哦【这里锁的设置需要考虑锁的可重入、可重试、锁的超时释放、锁的主从一致性】。 2、逻辑过期
key的失效多数是由于到了过期时间的key被清理而新的该key的缓存还没建立而此时来了大量请求那我们是不是可以设置该key不主动失效、分布式锁解决。 a、key不主动失效,不是不主动失效可以利用Redis的hash结构将过期时间拼接在value里面如hset product_01 1000 timestamp ,用户自己去决定这个key是否过期删除类似于Redis的key的惰性删除原理如果有请求过来查询该key时候会有一次检查过期时间的操作如果过期了就先加锁暂时阻塞其他线程访问数据库然后删除该缓存接着再请求数据库写入缓存释放锁【只能删除自己的锁】返回数据其他线程可以查询缓存返回数据库了。这里有可能存在极端情况就是在更新缓存期间其他线程等待时间过长直接返回空数据回去。这里也可以考虑MQ异步的去更新缓存哦。
三、缓存雪崩 缓存雪崩是指同一时段内缓存中大量的key同时失效或者缓存服务器宕机导致大量请求打在关系型数据库上关系型数据库有可能瞬间被打死。【通常8c16g的mysql数据库单台主库2000次/s并发写是可以扛住的从库8c16g可以达到5000多qps】 解决方案
1、key同时段失效的情况 a、 给key的过期时间设置随机值比如说选择60s~600s随机一个数字为过期时间。 b、多级缓存然后设置不同的过期时间 c、结合网关、hystrix/sentinel 限流大批量的请求不用全都放过来可以允许一部分请求一次失败让客户重试比如抢购、抢红包 d、结合MQ请求直接先放到MQ里面异步的查询Redis或者关系型数据库异步返回数据消费者慢慢消费几乎也都可以做到毫秒或者秒级的返回高并发的环境一般用户等待个几秒钟都是可以接受的不用追求极致也需要在成本、用户体验、性能、可用性之间做个平衡作为架构师应该要考虑到这些问题。
2、缓存服务器宕机的情况 这个要尽可能的实现缓存服务的高可用了不管是缓存的主从哨兵、分片主从哨兵、集群一致性hash结构/避免hash倾斜的增加虚拟节点的结构哨兵主从等结构都可以。注意主从节点一般都是至少三个节点且最好是奇数个节点避免集群选举出现脑裂或者票数一半一半选不出来qurom半数节点以上majority存活实例数/21。