redis 缓存穿透、击穿、雪崩、无底洞分析及解决
Redis缓存处理流程:
前台请求,后台先从缓存层取数据,取到直接返回结果,取不到时从存储层取,存储层取到更新缓存,并返回结果,存储层未取到,那直接返回空结果。
缓存穿透:
缓存穿透是指查询一个根本不存在的数据,缓存层和存储层都不会命中,导致不存在的数据每次请求都要到存储层去查询,造成存储层压力巨大甚至down机
解放方案:
? 1)针对不存在的key也缓存一个null值,,同时设置一个过期时间,,(弊端:内存中可能会存放大量无效key、时间窗口数据不一致)
? 2)采用布隆过滤器,,对于不存在的key直接返回null值
缓存击穿:
指的是某个热点key在过期时间点上,此时有大量请求去查询这个key,,导致存储层压力增大
1)设置热点数据永不过期
2)使用setnx加互斥锁,容易影响吞吐量,大部分项目设置热点key永不过期基本解决问题
缓存雪崩:
某个时刻Redis集群中的热点key都失效了。存储层查询数据量巨大,引起存储层压力过大甚至down机。
和缓存击穿不同的是, 缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。
解决方案:
? 1)设置热点数据永不过期
? 2)缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生,是一种比较取巧的解决方案。在一定程度上减轻了存储层的瞬时压力,
? ? 但是这种方案也在一定程度上增加了维护的成本
?缓存无底洞:
?当集群维持到一定个数后,再增加集群个数,性能反而下降的问题
?解决方案:
?常见的IO优化思路
? 1)IO优化
? ? 1 命令本身的优化,例如优化SQL语句。
? ? 2 减少网络通信次数。
? ? 3 降低接入成本,例如客户端使用长连/连接池、NIO等。
? 2)减少网络通信次数(批量操作解决方案):
? ? 1 串行命令:客户端n次get:n次网络+n次get命令本身。
? ? ? ? ? ? ? Redis Cluster:无法使用mget命令一次性获取。
? ? ?优:实现起来比较简单。
? ? ?缺:时间复杂度较高。大量keys超时严重。
? ?2 串行IO:node次网络时间+n次命令时间。
? ? ?Redis Cluster:使用CRC16算法计算出散列值,再取对16383的余数就可以算出slot值。
? ? ?Redis Cluster:Smart客户端会保存slot和节点的对应关系。
? ? ?优:实现起来比较简单。
? ? ?缺:时间复杂度较高。大量nodes也会超时严重。
? ? ?可以得到得到每个节点的key子列表,然后分别对每个结点执行批量操作。
? 3 并行IO:
? ? 将方案2中的最后一步改为多线程执行,网络次数虽然还是节点个数,但由于使用多线程网络时间变为O(1)。
? ? 优:利用编程特性,时间取决于最慢的线程。
? ? 缺:增加编程复杂度。多线程并发,出现问题定位也会比较难。
? 4 hash_tag实现:1次网络时间+n次命令时间
? ? Redis Cluster:的hash_tag功能,它可以将多个key强制分配到一个节点上。
? ? 优:性能较好。
? ? 缺:业务维护成本高。容易出现数据倾斜。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!