Redis面试题

本文探讨了如何在MySQL与Redis中确保数据一致性,重点关注Redis的过期删除策略、内存淘汰策略以及主从同步机制,同时介绍了缓存一致性问题如穿透、击穿和雪崩的解决方法,以及Redis的数据持久化选项RDB和AOF的优缺点。
摘要由CSDN通过智能技术生成

MySQL 里有 2000w 数据,Redis 中只存 20w 的数据,如何保证 redis 中的数据都是热点数据?
1.Redis 过期删除策略

1)惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。
2)定期删除:每隔一段时间程序就对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库,则由算法决定。
2.内存淘汰策略
Redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。
Redis 提供 8 种数据淘汰策略:
LRU全称Least recently used,意思为淘汰掉最久未使用(即最老)的一条数据;
LFU全称Least-frequently used,意思为淘汰掉过去被访问次数最少的一条数据
淘汰策略名称
策略含义
人话
noeviction
默认策略,不淘汰数据;大部分写命令都将返回错误
不删除任意数据(但redis还会根据引用计数器进行释放),这时如果内存不够时,会直接返回错误。
volatile-lru
从设置了过期时间的数据中根据 LRU 算法挑选数据淘汰(只针对设置过期的keys)
从设置了过期时间的数据集中,选择最近最久未使用的数据释放 ,最老的删掉
allkeys-lru这个是最常用的
从所有数据中根据 LRU 算法挑选数据淘汰(所有keys)
从数据集中(包括设置过期时间以及未设置过期时间的数据集中),选择最近最久未使用的数据释放 最老的删掉
allkeys-random
从所有数据中随机挑选数据淘汰
随机选择一个数据进行释放;
volatile-random
从设置了过期时间的数据中随机挑选数据淘汰
从设置了过期时间的数据集中,随机
volatile-ttl
从设置了过期时间的数据中,挑选越早过期的数据进行删除
从设置了过期时间的数据集中,选择马上就要过期的数据进行释放操作
allkeys-lfu
从所有数据中根据 LFU 算法挑选数据淘汰(4.0及以上版本可用)
淘汰掉过去被访问次数最少的一条数据
volatile-lfu
从设置了过期时间的数据中根据 LFU 算法挑选数据淘汰(4.0及以上版本可用)
淘汰掉设置了过期时间的key过去被访问次数最少的一条数据
3.Redis主从同步机制

步骤如下:(全量)
1.从服务器向主服务器发送同步命令 sync;
2.主数据库接收到同步命令后,会执行 bgsave 命令,在后台生成一个 rdb 文件,并使用一个缓冲区记录从现在开始执行的所有写命令;
3.当主服务器执行完 bgsave 命令后,主服务器会将 bgsave 命令生成的 rdb 文件发送给从服务器;
4.从服务器接收到这个 rdb 文件,然后加载到内存 ;之后主服务器会把刚刚在缓存区的命令同步过来,从服务器就会执行这些命名。(两边就一致了)
5.以上处理完之后,之后主数据库每执行一个写命令,都会将被执行的写命令发送给从数据库。
4.Redis是单线程,但为什么快

  1. 纯内存操作
  2. 单线程操作,避免了频繁的上下文切换
  3. 合理高效的数据结构
  4. 采用了非阻塞I/O多路复用机制 epool
    5.Redis 和 Mysql 数据库数据如何保持一致性

5.1前言
我们在实际项目中经常会使用到Redis缓存用来缓解数据库压力,但是当更新数据库时,如何保证缓存及数据库一致性,一般我们采用延时双删策略。
目前系统中常用的做法是一个查询接口,先查询Redis,如果不存在则查询数据库,并将结果放入到Redis中。
为什么是删除缓存,而不是更新缓存呢?主要是如果缓存的内容是带有树型结构或者List,Map,那么更新其中一个内容相对较慢。
本文所讲操作,均是按照如果缓存不存在,查询数据库后,再放入Redis。
5.2 常见更新策略
1 先删缓存,再更新数据库
2 先更新数据库,再删除缓存
3 普通双删
4 延迟双删
5.3 图解
5.3.1 先删缓存,再更新数据库
在这里插入图片描述

1、线程A删除缓存数据,此时还没更新数据库
2、线程B查询缓存没有数据,查询数据库还是旧数据,放入缓存
3、线程C及其他线程使用旧缓存数据,缓存和数据库不一致
5.3.2 先更新数据库,再删除缓存
在这里插入图片描述

1、线程A更新数据库,此时还没有删除缓存
2、线程B及其他线程此时使用的还是旧缓存数据,和数据库内容不一致
5.3.3 普通双删在这里插入图片描述

1、线程A先删除缓存,再更新数据库,再删除缓存
2、线程B查询缓存没有数据,在线程A更新数据库之前,查询到旧数据,此时系统时间片切换到线程A执行删除缓存,之后又轮到线程B放入缓存旧数据
3、线程C针对于线程A,查询缓存没有数据,查询到旧数据,放入缓存旧数据
都不能满足缓存和数据一致性。
5.3.4 延迟双删在这里插入图片描述

1、线程A先删除缓存,之后更新数据库
2、线程B和线程C发现缓存没数据,查询数据库。线程B查询到的是旧数据,线程C查询到的是新数据。之后纷纷放入缓存
3、线程A延时3-5秒(时间一般要大于SQL执行时间+线程切换执行时间100ms足够),再将缓存删除。之后其他线程再查询缓存,发现没数据,再次查询数据库及放入缓存都是新数据
极端情况就是线程D,所以延时双删还是不一定能保证缓存及数据一致。

5.4 建议
1、在发现缓存没有数据后,在执行查询数据库前,对该Key进行加锁,查询数据库并放入缓存后再解锁,这样可以避免缓存击穿问题,当某个redis数据不存在时,大量线程并发查询数据库。
2、在需要执行双删前,对该Key进行加锁,之后执行删除缓存,更新数据库,放入新数据到缓存,在解锁。保证缓存和数据一致性。
3、加锁的Key都需要设置过期时间,避免因为宕机造成死锁。

最完美的是用阿里的canal组件,既避免了因为加锁对Redis性能的降低,也解决了延迟双删所在极端情况下的漏洞。
6.Redis集群

Redis提供了多种集群模式以适应不同场景下的高可用性和水平扩展需求。以下是Redis集群模式:
主从复制(Master-Slave)模式:
在此模式下,有一个主节点负责处理写入请求,而从节点则复制主节点的数据并提供读取服务。
优点:实现简单,能实现数据冗余,通过读写分离提高系统性能。
缺点:需要手动进行故障转移,无法自动处理主节点故障;不支持自动的数据分区(sharding),难以做到水平扩展。
哨兵(Sentinel)模式:
Sentinel是Redis提供的一个高可用性解决方案,它能监控主从节点状态,并在主节点出现故障时自动完成故障转移。
优点:解决了主从模式下手动故障转移的问题,提供了自动化监控和故障恢复机制。
缺点:虽然比主从模式增加了自动化,但仍不支持自动的数据分区,且随着节点数量增加,管理和配置的复杂性也会增大。
Redis Cluster模式:
Redis Cluster是官方正式支持的分布式解决方案,它采用了数据分片(sharding)技术,将数据分散在多个节点上。
优点:真正实现了分布式存储,每个节点都可以处理读写请求,具备良好的水平扩展能力;内置了数据自动分割、故障检测与转移功能。
缺点:相比其他模式更复杂,需要更多的网络资源和配置管理;客户端需要支持集群特性;跨slot的数据操作可能涉及多个节点,有一定复杂度。

7.缓存穿透,缓存击穿,缓存雪崩
1 穿透: 两边都不存在(皇帝的新装) (黑名单) (布隆过滤器)
2 击穿:一个热点的key失效了,这时大量的并发请求直接到达数据库. (提前预热)
3 雪崩:大量key同时失效 (避免大量的key同一时间失效,错峰)在这里插入图片描述
8.在百万keys的Redis里面,如何模糊查找某个key.
应该使用scan 命令来进行模糊查找,在百万keys进行模糊查找,使用keys是不可取的,因为它可能会阻塞 redis线程,而每次调用scan 命令都会返回一个新的游标和一批键名,可以分批查找 ,这样就不会造成线程的阻塞,提高了查询效率。
```
SCAN cursor [MATCH pattern] [COUNT count]
#例如(用SCAN遍历以name.w开头的元素每次返回2500个)
SCAN 0 MATCH name.w* COUNT 2500


9.Redis特性
面试题:为什么要用Redis?
1、内存数据库,快,很快.......
2、工作单线程worker,串行化、原子操作.  (IO线程是多线程)- 避免上下文切换
3、IO模型(epoll), 支撑高并发.
4、kv模型,v具有类型结构.
5、具有本地方法,计算向数据移动。(a,b) => 交集
二进制安全,Value最大512M
面试题:为什么要用Redis?
1、内存数据库,快,很快.......
2、工作单线程worker,串行化、原子操作.  (IO线程是多线程)- 避免上下文切换
3、IO模型(epoll), 支撑高并发.
4、kv模型,v具有类型结构.
5、具有本地方法,计算向数据移动。(a,b) => 交集
二进制安全,Value最大512M
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/62a5850c1d654e4ba3496800d77bb403.png)
10.Redis到底是多线程还是单线程?
	Redis6.0之前是单线程;
	6.0之后IO线程是多线程,worker是单线程.

11.Redis数据持久化 
	Redis提供两种持久化机制:
	RDB:存储数据结果,关注点在数据(快照)
	AOF:存储操作过程,关注点在数据的操作过程(命令)
	①.RDB(Redis DataBase):![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/23481ab123df4609b44e8c62acf19a7c.png)
RDB的触发方式:
手动触发:通过命令手动生成快照 (save,bgsave)
自动触发:通过配置参数的设置触发自动生成快照
缺点:
快照时间有间隔,不能实时备份,丢失数据可能会比较多
开启子进程备份数据,在数据集比较庞大时,fork()可能会非常耗时,造成服务器在一定时间内停止处理客户端。
优点:
1.恢复数据比较快
2.备份的文件就是原始内存数据的大小,不会额外增加数据占用,
AOF(Append Only File):
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/4ee498c207d24741ad7c205cb0386880.png)
AOF的触发方式
1.手动触发
通过bgrewriteaof命令:重新AOF持久化生成aof文件(触发重写)
2.自动触发
默认情况,redis是没有开启AOF(默认使用RDB持久化),需要通过配置文件开启

AOF的优缺点
优点:
数据安全性高,不易丢数据
AOF文件有序保存了所有写操作,可读性强
缺点:
AOF方式生成文件体积变大
数据恢复速度比RDB慢
  • 12
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值