redis面试
1.redis为什么这么快?
以下三个原因
- redis采用的是单线程。单线程会避免上下文切换,在多线程情况下会出现cpu时间片的分配导致性能降低。
- redis采用了基于非阻塞的IO多路复用机制。IO多路复用机制会监听多个Socket,会将Socket放入一个队列中排队,每次从队列种有序、同步取出一个Socket给事件分派器,事件分派器把Socket给对应的事件处理器
- redis采用的是纯内存操作。
2.redis的AOF和RDB区别
RDB
:
Redis DataBase,将某一时刻的内存闪照,以二进制的方式写入磁盘
手动触发
:
- save命令,使Redis处于阻塞状态,直到RDB持久化完成,才会响应其他客户端发来的命令,所以在生产环境中一定要慎用
- bgsave命令,fork出一个子进程执行持久化,主进程只在fork过程中有短暂的阻塞,子进程创建之后,主进程就可以响应客户端请求了
自动触发
:
- save m n :在m秒内,如果有n个键发生改变。则自动触发持久化。如果设置多个,只要满足其中一个就会被触发
- 主从同步:全量同步时会自动触发bgsave命令,生成rdb发送给从节点
优点:
1.整个redis数据库将只包含一个文件dump.rdb,方便持久化
2.方便备份
3.性能最大化,会fork一个子进程进行写操作,让主线程继续处理命令,所以使IO最大化。
4.数据集大的时候,比AOF的启动效率更高
缺点:
1.数据安全性低,RDB使间隔一段时间进行持久化,如果持久化之间redis发生了故障,会发生数据丢失
2.由于RDB使通过for子进程来协助完成数据持久化工作,因此,如果数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟。会占用cpu
AOF
:
Append Only File 以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录,调操作系统命令进程刷盘
1.所有的写命令会追加到AOF缓冲区
2.AOF缓冲区根据对应的策略向硬盘进行同步操作
3.随着AOF文件越来越大,需要定期对AOF文件进行重写
3.当Redis重启时,可以加载AOF文件进行数据恢复
同步策略:
-
每秒同步:异步完成,效率非常高,一旦出现宕机现象,那么这一秒钟之内修改的数据将会丢失
-
每修改同步:同步持久化,每次发生的数据变化都会被立即记录到磁盘中,最多丢失一条
-
不同步:由操作系统控制,可能丢失较多数据
优点:
1.数据安全
2.通过append模式写文件,即使中途服务器宕机也不会破坏已经存在的内容,可以通过 redis-check-aof工具解决数据一致性问题
3.AOF机制的rewrite模式。定期对AOF文件进行重写,以达到压缩的目的
缺点:
1.AOF文件比RDB文件大,且恢复速度慢
2.数据集大的时候,比RDB启动效率低
3.运行效率没有RDB高
3.Redis的过期键的删除策略
过期策略
-
惰性过期
:只有访问的时候,才会判断该key是否已过期,过期则清除。好处是可以最大化节省CPU资源,对内存不友好 -
定期过期
:每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。这个好处是使CPU和内存资源达到最优的平衡效果
Redis同时使用了惰性过期和定期过期
4.Redis和Mysql如何保证数据一致性
1.先更新mysql,再更新Redis,如果更新Redis失败,可能仍然不一致
2.先删除Redis缓存数据,再更新Mysql,再次查询的时候再将数据添加到缓存中,这种方案能解决1方案的问题,但是在高并发下性能较低,而且仍然会出现数据不一致的问题。
3.延时双删。先删除redis缓存数据,再更新mysql,延迟几百毫秒再删除redis缓存数据,这样就算在更新mysql时,有其他线程读了Mysql,把老数据读到了Redis中,那么也会被删除掉,从而保持数据一致性。
5.Redis集群方案
哨兵模式
redis采用的sentinel进行集群处理的。
- 集群监控:负责监控redis master和slave进程是否正常工作。
- 消息通知:如果某个redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员
- 故障转移:如果master node挂掉了,会自动转移到slave 节点上
6.Redis缓存击穿、穿透、雪崩
雪崩
通常我们会将key设置过期时间,来达到和mysql数据保持同步。当缓存数据过期后,用户访问的数据不在缓存中就会查找数据库并将值更新到缓存中。
发生雪崩会有两个原因
大量key同时过期
雪崩就是在同一时间内,大面积的热点key同时失效,这个时候大量请求请求数据库,导致数据库压力很大,严重会导致数据库宕机。
解决方法:
均匀设置过期时间:给数据过期时间设置成一个随机数,避免同时过期
互斥锁:如果发现访问的数据不在redis中,加个互斥锁,保证同一时间只有一个请求来构建缓存(从数据库读取数据,再将数据更新到redis中)构建完成再释放锁。如果未能获取互斥锁的请求,要么等待要么重新读取缓存,要么返回空或默认值。实现互斥锁最好设置超时时间,当某个请求发生了意外而一直阻塞,一直不释放锁。
Redis故障宕机
解决方法:
服务熔断或请求限流
构建redis高可用集群
击穿
相对于雪崩的大面积key失效,击穿则是单个热点key失效。
解决方法:
不给热点key设置过期时间,后台异步更新缓存
互斥锁方案
穿透
当用户访问的数据,既不在缓存中,也不在数据库中,这样每次请求缓存时发现不存在于是请求数据库数据再更新到redis,但是发现数据库也没有想访问的数据,没法构建缓存数据。给数据库造成压力。
解决方法:
非法请求的限制
缓存空值或默认值
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)