Redis知识进阶
Redis的基础知识可参照Redis基础知识
什么是缓存穿透?怎么去解决?
缓存穿透 是指缓存和数据库中都没有的数据,⽽⽤户不断发起请求,我们数据库的 id 都是1开始⾃增上去的,如发起为id值为 -1 的数据或 id 为特别⼤不存在的数据,会短时间的大量请求落到数据库上。这时的⽤户很可能是攻击者,攻击会导致数据库压⼒过⼤,严重会击垮数据库。
解决方法:
- 存储 null值
如果从数据库查询出来的对象是空的,也可以放入缓存,其格式为,key为用户提交过来的主键值(id) ,value为null,但是将设定的缓存过期时间比较短,比如设置为60秒。这样如果该用户连续的去查找不存在的id时,也会只到Redis中查询,这样可以将数据库保护起来。 - 添加校验
也可以在接口层增加校验,比如用户的鉴权校验,对用户输入的参数进行校验,不合法的参数直接将代码return。 - 布隆过滤器
使用布隆过滤器 (Bloom Filter)
也能很好的防止缓存穿透的情况发生。
布隆过滤器的原理就是利用高效的数据结构和算法来快速判断出当前这个key是否存在数据库中,若是不存在就直接return。
什么是缓存穿击?怎么去解决?
缓存击穿,是指一个key非常热点(例如双十一期间进行抢购的商品数据),在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求到数据库上,就像在一个屏障上凿开了一个洞。
解决方法:
- 热点数据永不过期
对高访问量的热点数据设置永不过期,这样就使得高并发集中访问的时候key突然失效。 - 加互斥锁
这个方法可以使用,但是会导致大量线程阻塞,会使吞吐量降低。
什么是缓存雪崩?怎么去解决?
缓存雪崩,是指在某一个时间段,缓存集中过期失效。在缓存集中失效的这个时间段对数据的访问查询,都落到了数据库上,对于数据库而言,就会产生周期性的压力波峰。
和缓存穿击不同的是,缓存穿击指的是并发查同一条数据,而缓存雪崩是不同数据在某一时间段中都过期,很多数据都无法从Redis中查到,从而要去访问数据库。
解决方法:
- 均匀过期时间
可以将缓存的数据设置不同的失效时间,这样可以避免缓存数据再某一时间段集中失效。通常可以为有效期增加随机值或者统一规划有限期。 - 加互斥锁
同一时间只让一个线程构建缓存,其他线程阻塞排队。 - 设置缓存永不过期
对于热点数据 (访问频率高的数据) 设置为永不过期。 - 双层缓存策略
采用主缓存和备份缓存的模式,当主缓存突然失效后,可以从数据库加载最新的值,备份缓存在获取锁失败时读取,主缓存更新是需要同步更新备份缓存。
Redis的集群方案有哪些?
单台Redis服务性能不足的问题。这就需要使用到Redis的集群,构建Redis集群也是有多种方案。
主从复制模式
哨兵(Sentinel)模式
集群cluster
什么是主从复制?
在主从复制模式下Redis节点分为两种角色:主节点(也称为master)和从节点(也称为slave)。这种模式
集群是由一个主节点和多个从节点构成。
原则:Master会将数据同步到slave,而slave不会将数据同步到master。Slave启动时会连接master来
同步数据。
- 主节点说明
利用master来处理写操作,slave提供读操作
。这样可以有效减少单个机器的并发访问数量。要实现主从复制这种模式非常简单,主节点不用做任何修改,直接启动服务即可。 - 从节点说明
从节点需要修改redis.conf配置文件。加入配置:
slaveof <主节点ip地址> <主节点端口号>
例如master的ip地址为192.168.200.129,端口号为6379,那么slave只需要在redis.conf文件中配置slaveof 192.168.200.129.6379
即可。
主节点的写操作,从节点立刻就能看到相同的数据。但是在从节点进行写操作,提示 READONLY You can't write against a read only slave
不能写数据到从节点。
这样就可以通过这种方式配置多个从节点进行读操作,主节点进行写操作,实现读写分离。
什么是哨兵sentinel?
Redis实现主从复制,可将主节点数据同步给从节点,实现了读写分离,提高Redis的性能。但是现在还存在一个问题,就是在主从复制这种模式下只有一个主节点,一旦主节点宕机,就无法再进行写操作。
这不能体现高可用性,为了解决这个问题,出现了哨兵模式。
sentinel(哨兵)是用于监控redis集群中Master状态的工具,其本身也是一个独立运行的进程,同时sentinel也可以实现集群,是Redis的高可用解决方案,sentinel哨兵模式已经被集成在redis2.4之后的版本中。
其工作流程:
sentinel可以监视一个或者多个redis master服务,以及这些master服务的所有从服务;当某个master服务下线时,自动将该master下的某个从服务升级为master服务替代已下线的master服务继续处理请求,同时通知客户端,并且其余从节点开始从新的主节点复制数据。
什么是sentinel的故障转移?
在了解什么是故障转移之前,先了解两种触发故障转移的情况:
- 主观下线
每个sentinel都会定时向主节点和从节点进行心跳检查(通过ping的方式),当检测出主节点出现超时状态的时候,会认为这个主节点已经不可用了,这种判定就是主观下线
。 - 客观下线
在出现主观下线后,该sentinel会通过sentinel ismaster-down-by-addr
命令向其他 Sentinel 节点询问对主节点的判断,如果quorum
个的sentinel节点都认为该主节点不可用了,就会执行客观下线
。
quorum通常为 Sentinel节点总数/2+1,即半数以上节点做出主观下线判断就可以执行客观下线。
达到了客观下线的情况,就会开始进行 故障转移。这一步操作只要一个sentinel就能完成,这时就会基于Raft算法
选取一个sentinel来进行故障转移。
- 在从节点中按照一定的选举要求来选出一个节点作为新的主节点
- 对选出来的从节点执行
slaveof no one
命令让其成为主节点。 - sentinel就会向剩余的从节点发送命令,让他们从新的主节点上复制数据。
- 如果这时原主节点恢复,但是不会变回主节点,sentinel会将其变成从节点, 并对其进行监控, 发送命令去复制新的主节点。
Redis内置集群cluster是什么?
引入Cluster模式的原因:
不管是主从模式还是哨兵模式都只能由一个master在写数据,在海量数据高并发场景,一个节点写数据容易出现瓶颈,引入Cluster模式可以实现多个节点同时写数据。
Redis Cluster是Redis的内置集群,在Redis3.0推出的实现方案。在Redis3.0之前是没有这个内置集群的。Redis Cluster是无中心节点的集群架构,依靠Gossip协议协同自动化修复集群的状态。
Redis cluster在设计的时候,就考虑到了去中心化,去中间件,也就是说,集群中的每个节点都是平等的关系,都是对等的,每个节点都保存各自的数据和整个集群的状态。
每个节点都和其他所有节点连接,而且这些连接保持活跃,这样就保证了我们只需要连接集群中的任意一个节点,就可以获取到其他节点的数据。
值得注意的是,这种集群模式下的每个节点保存的数据并不是完整的数据,而只是部分的数据。其分配规则就是使用 哈希槽
。
Redis 集群是采用一种叫做哈希槽 (hash slot) 的方式来分配数据的。redis cluster 默认分配了
16384
个slot,当我们set一个key 时,会用 CRC16 算法来取模得到所属的 slot ,然后将这个key 分到哈希槽区间的节点上,具体算法就是:CRC16(key) % 16384
如何提高集群cluster的高可用性?
可以在cluster中加入主从模式,一个主节点对应一个或多个从节点,主节点提供数据存取,从节点则是从主节点拉取数据备份,当这个主节点挂掉后,就会在这些从节点中选取一个来充当主节点,从而保证集群不会挂掉。
个人理解,有误希望大家多多指出😁😁😁