在用redis当中可能遇到的问题解决方案以及redis中的一些名词解释
- Redis篇
- 一、缓存穿透:
- 解决方案:
- 缓存空数据
- 布隆过滤器
- 二、缓存击穿
- 解决方案
- 互斥锁,强一致性,性能差,速度慢
- 逻辑过期,数据不同步,性能优
- 三、缓存雪崩
- 解决方案
- 四、双写一致
- 解决方案
- 允许业务延时一致的业务,采用异步通知
- 强一致性的,采用Redisson提供的读写锁
- 五、Redis持久化
- RDB
- AOF
- 六、数据过期策略
- 惰性删除
- 定期删除
- 七、数据淘汰策略
- LRU
- LFU
- 八、redis分布式锁是如何实现的
- 分布式锁主要利用Redis的setnx命令
- Redisson实现分布式锁如何合理的控制锁的有效时长
- Redisson的这个锁,可以重入吗
- Redisson锁能解决主从一致的问题吗
- 九、Redis集群有哪些方案,
- 主从同步
- 全量同步
- 主从增量同步(slave重启或后期数据变化)
- 十、怎么保证Redis的高并发高可用
- 使用的redis是单点还是集群
- 分片集群结构
- 解释I/O多路复用模型
- Redis网络模型
- Redis网络模型
Redis篇
一、缓存穿透:
名次解释:查询一个不存在的数据,musql查询不到数据也不会直接写入缓存,就会导致每次请求都查数据库
解决方案:
-让查询返回的数据为空,这个空数据缓存在Redis当中,优点:简单 *缺点:消耗内存,可能会发生不一致问题,
二、缓存击穿
名次解释:给某一个Key设置了过期时间,当key过期的时候,恰好这个时间段有大量的靠key查询的请求发过来,这些请求可能一瞬间将DB压垮
解决方案
-
互斥锁,强一致性,性能差,速度慢
-
逻辑过期,数据不同步,性能优
三、缓存雪崩
名次解释:缓存雪崩是指在统一时间内大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库
解决方案
- 给不同的Key的TTL添加随机值
- 利用Redis集群提高服务的可用性(哨兵模式,集群模式)
- 给缓存业务添加降级限流策略(ngxin或spring cloud gateway)
- 给业务添加多级缓存 guava或caffeine
四、双写一致
问题:redis作为缓存,mysql的数据怎么保证和redis的数据一样
解决方案
允许业务延时一致的业务,采用异步通知
-
使用MQ中间中间件,更新数据之后,通知缓存删除,在此当中保证MQ的可靠性
-
利用canal中间件,不需要修改业务代码,伪装为mysql的一个从节点,canal通过读取binlog数据更新缓存
Canal是一个用于MySQL数据库增量日志解析的开源工具,常用于数据库镜像、实时备份、索引维护和缓存刷新等。它模拟MySQLslave与master交互,解析binlog并提供数据同步。文章介绍了Canal的工作原理、架构、高可用机制以及配置和应用示例,包括与Redis和ES的同步,并提供了实战代码示例。
强一致性的,采用Redisson提供的读写锁
-
共享锁,读锁readlock
-
排他锁:独占锁,加锁之后,其他线程读写受阻
五、Redis持久化
RDB
basave开始时会fork(克隆)主进程得到子进程,子进程共向内存数据(页表),页表储存着虚拟内存和物理内存之间的映射关系,完成fork操作之后读取数据并且写入RDB文件,
AOF
aof默认是关闭的,通过redis.conf文件来打开,配置项有三种,always,everysec,no,通过执行bgrewriteof命令,可以让redis使用重写功能,auto-aof-rewrite-pencentage 100(增长超过多少百分比触发)
六、数据过期策略
惰性删除
设置过期时间后,不去管它,当需要用到的时候,验证是否过期,如果过期,则删掉它,否则,就返回该key
优点:对Cpu友好,只有在用到该内存时,才会对该值进行检查
缺点:长时间不用的话过期的key值堆积
定期删除
每隔一段时间,我们就对一些key进行检查,删除里面过期的key(从一定数量的数据库中取出一定数量的随机key进行检查,并删除其中的过期key),分为两种模式
slow模式是定时任务,执行频率默认10hz,每次不超过25ms
fast模式执行频率不固定,但两次间隔时间不超过2ms
优点:可以限制删除操作执行的时长和频率来减少删除操作对CPU的影响,
缺点:难以确定删除操作执行的时长和频率
七、数据淘汰策略
CTemp%5C1727269554012.png&pos_id=img-LdwbyIj5-1743062150316)
当Redis中的内存不够时
此时再向Redis中添加新的数据,那么Redis就会使用一种策略将内存中的数据删除掉
LRU
最近最少使用。用当前时间减去最后一次访问时间,这个值越大则淘汰优先级越高
LFU
最少频率使用。会统计每个key值得访问频率
- 优先使用allkeys-lru策略,把最近最常访问得数据留在缓存当中,如果有明显得冷热数据区分,建议使用
- 如果数据访问频率差距不大,allkeys-random
- 有置顶需求,volatile-lru策略,同时置顶数据不设置过期时间
- 业务中有短时间内高频访问得数据,可以使用allkeys-lfu或者volatile-lfuf
八、redis分布式锁是如何实现的
分布式锁主要利用Redis的setnx命令
我们当使用的rdisson实现的分布式锁,底层是setnx和lua脚本(保证原子性性),在代码中,加锁,设置过期时间等操作都是基于Lua脚本完成
Redisson实现分布式锁如何合理的控制锁的有效时长
在redisson的分布式锁中,提供了一个WatchDog(看门狗),一个线程获取锁成功以后,WatchDog会给持有锁的线程续期(默认是每十秒续期一次)
Redisson的这个锁,可以重入吗
可以重入,多个锁重入需要判断是否是当前线程,在redis中进行存储的时候使用的hash结构,来存储线程信息和重入的次数
Redisson锁能解决主从一致的问题吗
不能解决,但是可以使用redisson提供的红锁来解决,但性能低,如果非要保证数据的强一致性,采用zoo keeper实现的分布式锁
九、Redis集群有哪些方案,
三种,主从同步,哨兵模式,Redis分片集群
主从同步
缺点 不能保证Redis的高可用性,当主节点宕机之后,就丧失了写数据的能力
单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离,一般都是一主多从,主节点负责写数据,从节点负责读数据
全量同步
replication id:简称Replid,是数据集的标记,id一致说明是统一数据集,每一个master都有唯一的replid,slave则会继承master节点的replid
offset: 偏移量,随着记录在repl_baklog中的数据增多而逐渐增大,slave完成同步时也会记录当前同步的offset,如果slave中的offset小于master中的offset,说明slave数据落后于master,需要更新
步骤
1,salve执行replicaof命令,建立连接,请求数据同步,
2,master判断是否是第一次同步(replid是否一致),是第一次,返回master的数据版本信息replid,offset,slave保存版本信息
3,master执行bgsave,生成RDB文件,发送RDB文件,slave清空本地数据,加载RDB文件
4,master,记录RDB期间的所有命令,发送repl_baklog中的命令,slave执行收到的命令
主从增量同步(slave重启或后期数据变化)
1,slave重启,发送psync replid offset,master判断请求replid是否一致,不是第一次,回复continue,去repl_baklog中获取offset后的数据,发送offset后的命令,slave执行命令
十、怎么保证Redis的高并发高可用
哨兵模式:实现主从集群的自动故障恢复(监控,自动故障恢复,通知)
哨兵选主规则
-
首先判断主从节点断开时间长短,如超过指定值就排除该节点
-
判断从节点的额slave-priority值,越小优先级越高
-
如果以上一样,则判断slave节点的offset值,越大优先级越高
-
判断slave节点id值得大小
使用的redis是单点还是集群
主从(1+1)+哨兵,单节点内存不超过10G,如果内存不足,可以给不同得服务分配独立的Redis主从节点
redis集群脑裂:是由于主节点和从节点的sentinel处于不同的网络分区,使得sentinel没有能够心跳感知到主节点,所以通过选举的方式提升了一个从节点为主,这样就存在了两个主节点,导致客户点在老地节点那边写数据,新节点无法同步数据,当网络恢复后,sentinel会将老的主节点将为从节点,这是再从新的master同步数据,
解决方法:修改redis的配置,设置最小的从节点数量,缩短同步的延迟时间
分片集群结构
解释I/O多路复用模型
单个线程同时监听多个,Socket,再某个Socekt进程可读可写时,得到通知,从而避免无效的等待,多数用epoll模式实现,它在通知socket就绪的同时,将socket写入用户空间,不会每个遍历,节省了时间
Redis网络模型
就是使用I/O多路复用结合时间的处理器来应对多个Socket请求
连接应答处理器
命令恢复处理器,在Redis6.0之后,使用多线程来处理
命令请求处理器,在Redis6.0之后,将命令的转换使用了多线程,增加命令的转换速度
无效的等待,多数用epoll模式实现,它在通知socket就绪的同时,将socket写入用户空间,不会每个遍历,节省了时间
Redis网络模型
就是使用I/O多路复用结合时间的处理器来应对多个Socket请求
连接应答处理器
命令恢复处理器,在Redis6.0之后,使用多线程来处理
命令请求处理器,在Redis6.0之后,将命令的转换使用了多线程,增加命令的转换速度