什么是缓存穿透、缓存击穿、缓存雪崩,以及各自的解决方案
什么是缓存穿透、缓存击穿、缓存雪崩
缓存雪崩
当缓存数据大面积失效,导致请求无法从缓存中拿到数据而是直接访问数据库。
缓存穿透
缓存穿透是指查询一个缓存中和数据库中都不存在的数据,导致每次查询这条数据都会透过缓存,直接查库,最后返回空。当用户使用这条不存在的数据疯狂发起查询请求的时候,对数据库造成的压力就非常大,甚至可能直接挂掉。这种情况的流程就变成下图这样了:
缓存击穿
缓存击穿是指当缓存中某个热点数据过期了,在该热点数据重新载入缓存之前,有大量的查询请求穿过缓存,直接查询数据库。这种情况会导致数据库压力瞬间骤增,造成大量请求阻塞,甚至直接挂掉。
解决方案
缓存雪崩
针对第一种大量key同时过期的情况,解决起来比较简单,只需要将每个key的过期时间打散即可,使它们的失效点尽可能均匀分布。
针对第二种redis发生故障的情况,部署redis时可以使用redis的几种高可用方案部署,部署方法可以参考我之前的文章Redis高可用方案—主从(masterslave)架构、Redis高可用架构—哨兵(sentinel)机制详细介绍、Redis高可用架构—Redis集群(Redis Cluster)详细介绍。
除了上面两种解决方式,还可以使用其他策略,比如设置key永不过期、加分布式锁等。
缓存穿透
解决缓存穿透的方法一般有两种,第一种是缓存空对象,第二种是使用布隆过滤器。
第一种方法比较好理解,就是当数据库中查不到数据的时候,我缓存一个空对象,然后给这个空对象的缓存设置一个过期时间,这样下次再查询该数据的时候,就可以直接从缓存中拿到,从而达到了减小数据库压力的目的。但这种解决方式有两个缺点:(1)需要缓存层提供更多的内存空间来缓存这些空对象,当这种空对象很多的时候,就会浪费更多的内存;
(2)会导致缓存层和存储层的数据不一致,即使在缓存空对象时给它设置了一个很短的过期时间,那也会导致这一段时间内的数据不一致问题。
第二种方案是使用布隆过滤器,这是比较推荐的方法。所谓布隆过滤器,就是一种数据结构,它是由一个长度为m bit的位数组与n个hash函数组成的数据结构,位数组中每个元素的初始值都是0。在初始化布隆过滤器时,会先将所有key进行n次hash运算,这样就可以得到n个位置,然后将这n个位置上的元素改为1。这样,就相当于把所有的key保存到了布隆过滤器中了。
举个例子,比如我们一共有3个key,我们对这3个key分别进行3次hash运算,key1经过三次hash运算后的结果分别为2/6/10,那么就把布隆过滤器中下标为2/6/10的元素值更新为1,然后再分别对key2和key3做同样操作,
当客户端查询时,也对查询的key做3次hash运算得到3个位置,然后看布隆过滤器中对应位置元素的值是否为1,如果所有对应位置元素的值都为1,就证明key在库中存在,则继续向下查询;如果3个位置中有任意一个位置的值不为1,那么就证明key在库中不存在,直接返回客户端空即可
缓存击穿
解决缓存击穿的方法也有二种,第一种是设置key永不过期;第二种是使用分布式锁,保证同一时刻只能有一个查询请求重新加载热点数据到缓存中,这样,其他的线程只需等待该线程运行完毕,即可重新从Redis中获取数据。
1、在设置热点key的时候,不给key设置过期时间即可。不过还有另外一种方式也可以达到key不过期的目的,就是正常给key设置过期时间,不过在后台同时启一个定时任务去定时地更新这个缓存。
2、使用加锁的方式,锁的对象就是key,这样,当大量查询同一个key的请求并发进来时,只能有一个请求获取到锁,然后获取到锁的线程查询数据库,然后将结果放入到缓存中,然后释放锁,此时,其他处于锁等待的请求即可继续执行,由于此时缓存中已经有了数据,所以直接从缓存中获取到数据返回,并不会查询数据库。
相关文章:

Windows下安装和配置Redis
下载版本Redis-x64-5.0.14.1.zip。(可能需要开代理)

Redis 击穿、穿透、雪崩产生原因解决思路
也就是在设定的时间里数据没有取出来,但是锁由过期了,常见的思路是,锁过期时间值递增,但是想想不靠谱,因为第一个请求可能超时,如果后面的也超时呢,接连多次超时之后,锁过期时间值势必特别大了,这样做弊端太多。雪崩,和击穿类似,不同的是击穿是一个热点Key某时刻失效,而雪崩是大量的热点Key在一瞬间失效,网络上很多博客都在强调解决雪崩的策略是随机过期时间,这个非常不准确,举个例子,银行做活动,之前这个利息系数为2%,过了零点系数改为3%,这种情况能将用户的对应的key改为随机过期吗?如果用的过去的数据叫脏数据。

Redis的key过期策略是怎么实现的
这是一道经典的Redis面试题,一个Redis中可能存在很多很多的key,这些key中可能有很大一部分都有过期时间,此时Redis服务器咋知道哪些key已经过期,哪些还没过期呢?如果直接遍历所有的key,这显然是行不通的,效率非常低!!Redis整体的策略是定期删除和惰性删除相结合。举个栗子:假如我去小卖铺买东西,付款的时候,发现东西过期了。就告知老板,于是老板下架此产品。消费者发现过期了,才去下架,这就叫。小卖铺老板主动定期抽取一部分商品,进行筛查,这就叫定期删除。

Redis 除了用作缓存还能干吗?
Redis 是一种内存键值数据库。它支持多种数据结构,如 String, Hash, List, Set 和 SortedSet。

【Redis】Redis 红锁
本章节主要讲解redis中的红锁,假设我们有个客户端要获取锁,然后向master去获取锁,然后master会把锁同步到slave节点,假设现在还没同步出去的时候,master节点挂了。然后从节点升级为主节点,然后另外一个刚刚在竞争锁失败处于阻塞状态的线程去获取锁的时候,但是新的master上,并没有锁的信息,然后就能拿到锁,此时就可能导致一些问题。此时我们就能使用红锁,来解决这个问题。一个客户端要向多个master节点发送加锁请求。只有半数的锁加锁成功,才是获取锁。

【Redis】Redis 配置文件
自定义目录:/myredis/redis.conf。

【redis】redis的哨兵Sentinel高可用架构
redis的哨兵Sentinel高可用架构,redis 哨兵集群与redis集群的关系以及故障转移,故障检测等原理

【redis】Redis哨兵机制和集群有什么区别?
Redis哨兵机制和集群有什么区别?redis集群有几种实现方式,一个是主从集群,一个是redis cluster.

【Redis】Redis中执行Keys命令会有什么问题?
如果需要根据某种模式来获取键,更好的选择是使用更高效的命令,如SCAN命令,它使用游标方式迭代返回匹配的键,避免了遍历整个键空间的性能问题,并且可以逐步处理数据。KEYS命令用于检索匹配指定模式的所有键。如果匹配的键非常多,返回的结果列表可能巨大无比,占用大量的内存。在极端情况下,如果执行KEYS命令返回的结果集非常大,并且内存不足以容纳整个结果集,Redis服务器可能会发生内存溢出错误。如果KEYS命令运行时间较长或遇到大量匹配的键,会导致服务器长时间无法响应其他请求,从而对系统的可用性产生负面影响。

【Redis】Redis中的大key怎么处理?
在Redis中,大key是指存储了大量数据的键。处理大key可能会对Redis服务器的性能和资源消耗产生负面影响。询问这个问题,首先要知道redis的大key会有什么影响。大key占用的内存空间较大,当大量的大key存在时,会消耗大量的内存资源。这可能导致Redis服务器的内存不足,并触发内存溢出,从而影响系统的稳定性和性能。当读取或写入大key时,需要将大量的数据通过网络传输。对于大量的网络传输,特别是在高并发的情况下,会增加整体的延迟,并占用带宽资源。

Redis的opsForValue()和boundValueOps()区别
该模板的序列化机制改变起来也很容易,并且Redis模块在org.springframework.data.redis.serializer包中提供了多种可用的实现,详情请参考Serializers。大部分的用户都喜欢用RedisTemplate,它相应的包是org.springframework.data.redis.core。虽然RedisConnection提供接受和返回二进制值(字节数组)的低级方法,但该模板可以处理序列化和连接管理,使得用户不需要处理太多的细节。如果 两者是实现的效果是相同的。

【redis】技术派中的缓存一致性解决方案
对于上面这种情况,对于第一次查询,请求 B 查询的数据是 10,但是 MySQL 的数据是 11,只存在这一次不一致的情况,对于不是强一致性要求的业务,可以容忍。这个图已经画的很清晰了,我就不用再去啰嗦了吧,不过这里有个前提,就是对于读请求,先去读 Redis,如果没有,再去读 DB,但是读请求不会再回写 Redis。请求 A、B 都是先写 MySQL,然后再写 Redis,在高并发情况下,如果请求 A 在写 Redis 时卡了一会,请求 B 已经依次完成数据的更新,就会出现图中的问题。

【redis】为什么Redis集群的最大槽数是16384个?
对网络同学开销的平衡:redis集群中的每个节点,会发送心跳消息,而心跳包中会携带节点的完整配置,他能够以幂等的方式来实现配置的更新。但是修改集群的槽位数量需要进行数据迁移和重新均衡,会对集群产生较大的影响,因此一般情况下建议使用默认的 16384 个槽位。可用性和容错性:16384 是一个较大的数字,可以提供足够的槽位数量来分布数据,从而提高集群的可用性和容错性。应用程序去存储一个key的时候会通过,对key进行一个CRC16去计算,再取模,然后路由到hash slot所在的节点。

【redis】Redis中AOF的重写机制
为了避免子进程在重写过程过程中,主进程中的数据发生变化,导致AOF文件里面的数据和redis内存中的数据不一致,redis中还做了一个优化,也就是说在子进程在做这个重写的过程中,主进程中的数据变更,需要追加到AOF的重写缓冲区中,等到AOF重写完成以后,再把AOF重写缓冲区的数据,追加到新的AOF文件里面,这样意料就能保证新的AOF文件里面的数据和当前Redis中的数据保持一致。子进程在进行重写的过程中,主进程依然可以去处理客户端的一个请求,这样一来子进程在重写的过程中,不耽误客户端的使用。

【redis】bitmap技术解析:redis与roaringBitmap
然后再看这个好理解一些。bitmap的表象意义是,使用一个01标识位来表示是否的状态,可以达到节省空间和高效判定的效果。在我们的实际工作中,也有着许多的应用场景,相信了解bitmap定会给你带来一些额外的收获。

Redis保证高可用的三种方式
Redis保证高可用主要有三种方式:主从、哨兵、集群。

Redis查看集群状态有节点显示fail,连接失败
现有6台redis,为集群,3主3从,由于两台服务器故障重装系统之后进行重新安装2台redis,安装完成之后。查询当前redis状态,发现有存留的节点,但连接为fai。将新建的两台redis启动,保证配置文件一致。查询fail节点的node_id。将新建的两台redis设为从节点。登录新建的两台redis服务器。先通过ID删掉无用的节点。