当前位置: 首页 > news >正文

Redis面试常见问题

1.Redis的常用类型

Redis常用的类型也就那五个,我想经常看各大八股文的小伙伴,应该都熟练于心了吧!它们分别是String、Hash、List、Set、ZSet;接下来跟我一起分析这五大常用类型

  • String数据类型格式:key value
  • Hash数据类型格式:key field value(这里的field是字段名,value是对应字段的值)
  • List数据类型格式:key value [value ...]
  • Set数据类型格式:key member 
  • Zset数据类型格式: key member score(Zset是在Set的基础上通过score进行排序)

2.Redis的常见三大问题(缓存穿透,缓存击穿,缓存雪崩)

(1)缓存穿透:在Redis中查询不到的数据直接查询数据库,但是该数据又不存在于数据库中,这样导致每次请求都直接查询数据库;为了解决这个问题可以对查询不到的数据赋值为null存储到Redis中,这样第二次发起查询请求时,直接通过Redis返回null的值告诉客户端查询不到该值即可。或者通过布隆过滤器,在请求到达缓存前,进行布隆过滤器检查,如果数据一定不存在,则直接返回,不再查询缓存和数据库

(2)缓存击穿:主要是针对热点数据,当大量数据请求同一时刻请求进来且Redis中没有该数据信息,导致所有的数据请求都直接到达数据库;可以通过对热点数据设置永不过期的方式。或者使用互斥锁,让第一个请求去数据库加载数据并更新缓存,其他请求等待缓存更新完成后再返回。

(3)缓存雪崩:同一时间段内缓存key集中失效,导致所有的请求都直接到达数据库上。解决的方式是通过给过期时间设置随机值。给缓存业务添加降级限流,熔断机制。或者给业务加上多级缓存。

3.Redis双写一致性

一般Redis都是读写分离的,所以主节点的数据传递给从节点需要一定的时间。 

Redis双写一致性:保证缓存和数据库中的数据一致性

如果对于数据的实时性并没有要求那么高,允许延时一致的业务(最终一致性):

  • 采用异步的方式进行通知,可以使用MQ中间件,更新数据后,通知缓存删除
  • 利用canal中间件,不需要修改业务代码,伪装为mysql的一个从节点,canel通过读取binlog数据更新缓存

如果对于数据的实时性要求高,不允许延时一致的业务(强一致性):

使用Redisson提供的读写锁:

  • 共享锁:读锁readLock,加锁之后,其他线程可以共享读操作
  • 排他锁:独占锁writeLock,加锁之后,阻塞其他线程读写操作

4.Redis持久化

有两种方式:分别是RDB、AOF

(1)RDB是基于快照的方式:就是把内存中的所有数据都记录到磁盘中,当Redis实例故障重启后,从磁盘中读取快照文件,恢复数据。

RDB执行有两种命令:

save由主线程来执行RDB,会阻塞所有的命令

save

bgsave开启子进程执行RDB,避免主进程受到影响

bgsave

(2)AOF是通过追加文件的方式:Redis处理的每个命令都会记录到AOF文件中,可以看做命令日志文件。

AOF默认是关闭的,需要修改redis.conf配置文件来开启AOF:

appendonly yes

修改redis.conf配置文件AOF文件的名称: 

appendfilename "appendonly.aof"

 AOF命令记录的频率:

通过修改redis.conf文件命令记录的频率

命令记录的三种频率:always、everysec、no

  • always:同步刷盘,可靠性高,几乎不丢失数据,性能低
  • everysec:每秒刷盘,性能适中,最多丢失1秒数据
  • no:操作系统控制,性能最好,可靠性差,可能丢失大量数据

5.Redis数据过期策略(删除策略)

(1)懒惰删除:设置的key过期后,不去管它,只有访问该key时,进行判断是否过期,若过期则进行删除

(2)定期删除:每隔一段时间,对一些key进行检查,删除里面过期的key

定期删除的两种模式:

  • slow:执行频率固定,每秒默认10hz,每次不超过25ms,可以通过修改配置文件redis.conf中的hz频率
  • faset:执行频率不固定,但两次间隔不低于2hz,每次耗时不超过1ms

6.Redis数据淘汰策略

Redis的数据淘汰策略主要针对Redsi内存不够用的情况,在Redis中添加key,那么Redis会按照某个规则将内存中的数据删除掉,这种数据的删除规则称为内存的淘汰策略(简单的说就是内存不够,要想再加入新的key需要释放内存空间先)

八大淘汰策略:

  • noeviction:默认策略,不会删除任何键,只是拒绝写入操作。这适用于只读或只写缓存,或者当你不希望Redis自动删除键时。

  • allkeys-lru:淘汰最近最少使用的键(LRU)。这种策略会从所有键中挑选出最少使用的键进行淘汰。

  • allkeys-lfu:淘汰最不经常使用的键(LFU)。这种策略会从所有键中挑选出使用频率最低的键进行淘汰。

  • volatile-lru:淘汰设置了过期时间的键中最近最少使用的键。

  • volatile-lfu:淘汰设置了过期时间的键中最不经常使用的键。

  • volatile-random:随机淘汰设置了过期时间的键。

  • volatile-ttl:淘汰设置了过期时间的键中,剩余存活时间最短的键。

  • allkeys-random:随机淘汰所有键。

老实说这多么你要是死记硬背的话很痛苦的,你只要记得默认noeviction和常用的allkeys-lru即可,其余的你可以理解,仔细观察可以发现淘汰策略跟随机、过期时间、最近最少使用(LRU)、最近不经常使用(LRU)相关

接下来就是Redis集群面试常见的问题了(Redis集群方案 )


7.Redis主从复制

单节点Redis的并发能力有一定上限的,为了提高Redis的并发能力,搭建主从集群,实现读写分离。

将写的操作写入主库中,然后主库再将数据同步到从库中;从库读取数据。

主从同步的原理(同步数据的流程):

replication Id:在主从同步过程中,主节点和从节点都维护一个复制ID。复制ID是一个唯一的标识符,用于在同步过程中识别主从关系。

offset:每个Redis服务器在执行写操作时都会生成一个日志,记录了写操作的偏移量。这个偏移量反映了写操作在日志中的位置。

(1)全量同步:

主节点

  • 开始一个后台保存过程,生成当前数据集的快照(RDB文件)。
  • 同时,缓冲所有在快照生成期间收到的写命令。
  • 将生成的RDB文件和缓冲的写命令发送给从节点。

从节点

  • 接收RDB文件和写命令。
  • 载入RDB文件,以恢复主节点的数据状态。
  • 执行主节点发送的写命令,以确保与主节点的数据一致。

(2)增量同步:

主节点

  • 在全量同步完成后,主节点会持续将新的写命令发送给从节点。
  • 这些写命令会包含命令本身和执行命令的偏移量。

从节点

  • 接收并执行这些写命令。
  • 执行命令时,从节点会记录自己的偏移量,并与主节点的偏移量进行比较,以确保数据的一致性。

8.Redis哨兵模式

哨兵模式是实现集群自动故障恢复

Sentinel 会不断检查master和slave节点是否按预期工作;

如果master故障,Sentinel会将一个slave提升为master。当故障实例恢复后也将新的master为主

Sentinel充当Redis客户端的服务发现来源,当集群发生故障迁移时,会将最新信息推送到Redis客户端。

Sentinel进行服务状态监控,Sentinel基于心跳机制监测服务状态,每隔1秒向集群中每个实例发送ping命令,当某个sentinel节点发现某个实例未在规定时间内响应,则认为该实例主观下线。若超过指定数量的sentinel都认为该实例主观下线,则该实例客观下线;指定的数量最好超过Sentinel实例数量的一半。如果是master节点客观下线,那么需要从该从节点的slave中选举出作为新master节点。

哨兵选主的规则:

  • 首先判断主与从节点离开断开的时间长短,如果超过指定值就排该从节点。
  • 判断从节点的slave-prority值,越小优先级越高。
  • 如果slave-prority一样,则判断slave节点的offset值,越大优先级越高。
  • 最后判断slave节点运行的id大小,越小优先级越高。

选举新的master可能导致脑裂问题的产生(Redis脑裂问题)

由于网络问题或其他原因导致集群中的节点无法相互通信,从而使得集群分裂成多个不相互连接的子集群。在这种情况下,每个子集群都可能认为自己是整个集群的唯一有效部分,并独立地继续处理客户端的请求,这可能导致数据一致性问题,因为不同子集群可能会对相同的数据进行不同的修改。

解决的方式:

  • 配置超时时间:合理设置节点之间的超时时间,使得在出现网络分区时,节点能够快速识别并作出响应。

  • 设置最小节点数:通过设置最小节点数,确保只有在足够多的节点可用时,集群才提供服务,这可以减少脑裂的发生。

分别对应redis中的两个配置参数:

min-replicas-to-write 1 表示最少的slave节点为1个

min-replicas-max-lag 5 表示数据复制和同步的延迟不能超过5秒

9.Redis分片集群

分片集群解决:

  • 海量数据存储问题
  • 高并发写的问题

使用分片集群可以解决上述问题,分片集群特征:

  • 集群中有多个master,每个master保存不同数据
  • 每个master都有多个slave节点
  • master之间通过ping监测彼此健康状态
  • 客户端请求可以访问集群任意节点,最终都会被转发到正确节点

分片集群结构-数据读写:

Redis分片集群通过哈希槽的方式进行划分,Redis集群中有16384个哈希槽,每个key通过CRC16校验后对 16384 取模来决定放置到哪个槽中,集群的每个节点负责一部分 hash 槽。

  


http://www.mrgr.cn/news/34411.html

相关文章:

  • Matplotlib-数据可视化详解
  • 【项目开发】跨学科合作平台原型设计
  • 如果在事务中使用update语句更新但是条件中没有使用主键,会使用什么级别的锁?
  • 利用代码,玩转腾讯云脱敏服务:Java、Python、PHP案例集
  • 【常见框架漏洞】ThinkPHP、struts2、Spring、Shiro
  • mysql数据库设置主从同步
  • 828华为云征文|Flexus云服务器X实例实践:部署Alist文件列表程序
  • Web端云剪辑解决方案,可实现移动端、PC、云平台无缝兼容
  • 项目总结,路径匹配的业务逻辑
  • 软件测试常见面试题
  • 部署wordpress项目
  • VBA日历进度
  • 【十八】MySQL 8.0 新特性
  • 面试速通宝典——3
  • mybatis 配置文件完成增删改查(五) :单条件 动态sql查询,相当于switch
  • CMake 构建Qt程序弹出黑色控制台
  • ArcGIS Desktop使用入门(三)图层右键工具——拓扑(上篇:地图拓扑)
  • Spring Boot CLI命令行工具
  • deepin桌面版连接windows远程桌面
  • LeeCode打卡第三十天