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

Redis 八股面试题

Redis 的数据类型

五种基本数据类型:

  • String
  • List
  • Set
  • Hash
  • ZSet(有序集合)

三种特殊数据类型:

  • Stream (消息队列)
  • HyperLogLog(基数统计)
  • Bitmap (位图)
  • Geospatial (地理位置)
Redis 为什么快?
  • 基于内存操作,比磁盘快很多

  • redis 数据类型(结构)性能很高

  • redis 执行命令是单线程的,避免了上下文切换带来的性能问题,也不用考虑锁的问题

使用 String 还是 Hash 存储对象数据更好?
  • 当对象结构简单,而且操作是整体操作的时候使用 String 更适合

  • 如果需要操作对象的字段或者节省内存,选择 Hash 更合适

购物车信息用 String 还是 Hash 存储更好?
  • 购物车中的商品频繁修改和变动, 使用 Hash 存储
使用 Redis 的哪种数据结构实现点赞功能
  • 使用 Set 实现, Set 适用于点赞,关注/粉丝,去重(签到,注册等)场景

  • Set 支持快速添加/删除,还能自动去重

如何使用 Redis 实现一个排行榜
  • 使用 Sorted Set (有序集合)
  • 相关的一些命令:ZRANGE(从小到大排序)、ZREVRANGE(从大到小排序)、ZREVRANK(指定元素排名)
Set 的应用场景
  • Set 是无序集合,集合中的元素没有先后顺序但都唯一,类似于 Java 中的 HashSet

常见应用场景:

  • 存放的数据不能重复的场景:网站 UV 统计、文章点赞、动态点赞等等

  • 获取交集、并集和差集:共同好友(交集), 好友推荐(差集)、音乐推荐(差集)、订阅号推荐(差集+交集)等

  • 需要随机获取元素的场景:抽奖系统、随机点名等

Redis 除了做缓存, 还能做什么?
  • 分布式锁
  • 消息队列
  • 计数器与限流器
  • 延时队列
  • 分布式 session
Redis 是单线程的,但是为什么还那么快?
  • 单线程, 避免了线程切换和锁竞争开销
  • 核心原因:
    1. 基于内存操作, 读写速度快
    2. IO 多路复用:用 epoll/kqueue 等机制处理多客户端连接,单线程高效处理并发请求
    3. 高效数据结构:如跳表(Sorted Set)、压缩列表(Hash)等,操作复杂度低
    4. 无阻塞命令:核心命令(如 GETSET)执行时间短,避免单线程阻塞
Redis 持久化机制
  • RDB(快照) , 定期将内存中数据生成快照写入二进制文件(.rdb),重启时快速加载,适合大数据量的恢复

  • AOF(追加日志) , 每执行一次写操作,就把该命令追加到文件里(appendonly.aof),数据持久性最好

  • 混合持久化(Redis 4.0+): RDB + AOF

Redis事务
  • 用于保证一组命令的原子性(要么全部执行,要么全部不执行),不支持回滚操作

  • redis 事务的实现使用 MULTI(事务的开始)和EXEC(事务的结束)命令

  • 输入 MULTI 命令后,redis 返回 OK 表示事务开启,然后输入需要在本次事务中执行的所有命令,每次输入命令不会立即执行,而是返回 QUEUED,表示命令已经并排入事务队列,最后输入EXEC命令后,才会依次执行这些命令.

``

  • 核心命令:
    • MULTI:开启事务
    • 命令序列:如 SET key1 val1INCR key2 等(入队,未执行)
    • EXEC:执行事务内所有命令
    • DISCARD:取消事务
    • WATCH key:监视 key,若事务执行前 key 被修改,则事务中断(乐观锁机制)
缓存
​​问题​​​​定义​​​解决方案​​
​缓存击穿​​​热点数据的缓存突然过期,大量请求直接冲击数据库1.互斥锁
2.逻辑过期(缓存永不过期,后台异步更新)
​​缓存穿透​​查询不存在的数据,请求绕过缓存直接访问数据库1.布隆过滤器
2.缓存空值
缓存雪崩​大量Key同时过期​​,或缓存集群宕机,导致所有请求直接访问数据库1.随机过期时间​​,分散key过期时间 2.使用多级缓存 3.使用Redis 集群部署,主从 + 哨兵模式
什么是布隆过滤器?
  • 一种概率型数据结构,通过多个哈希函数将数据映射到位图(bitmap),用于快速判断元素是否 “可能存在”

  • 特点:

    • 优点:空间效率高,查询速度快
    • 缺点:可能误判,不支持删除操作
Redis 分布式锁如何实现?

方法一: 基于 RedisSET 命令实现

加锁:

SET lock:order:1001 "UUID:threadId" NX PX 30000
  • NX:当 key 不存在时才设置(保证互斥)

  • PX 30000:设置 30 秒过期时间(避免死锁)

解锁:通过 Lua 脚本原子性判断并删除锁

方法二: 使用 Redisson 框架

如何合理控制分布式锁的有效时长
  • 基础原则:设置略大于业务执行时间的过期时间(如业务需 5 秒,设 10~15 秒)

  • 动态续期:使用 RedissonWatch Dog 机制,若线程未执行完,每隔 1/3 过期时间自动延长锁有效期

Redis 双写问题是什么?如何解决?
  • 定义:同时更新数据库和缓存时,因为并发操作、网络延迟或执行顺序不当等导致缓存与数据库数据不一致

  • 解决:

    1. 先更数据库,再删缓存
    2. 延迟双删:删除缓存后延迟 100ms 再次删除,避免并发更新时的脏数据
    3. 最终一致性:通过消息队列或定时任务同步缓存与数据库差异
Redis 的数据过期策略有哪些?
  • 惰性删除:访问 key 时才检查是否过期,过期则删除
  • 定期删除:每隔一段时间随机检查部分过期 key 并删除
  • 内存淘汰:当内存达到 maxmemory 阈值时,触发淘汰策略
Redis 的数据淘汰策略有哪些?
  • volatile-lru:从设置了过期时间的 key 中,淘汰最近最少使用的
  • allkeys-lru:从所有 key 中,淘汰最近最少使用的(最常用)
  • volatile-lfu:从过期 key 中,淘汰最不经常使用的
  • allkeys-lfu:从所有 key 中,淘汰最不经常使用的
  • volatile-random:从过期 key 中随机淘汰
  • allkeys-random:从所有 key 中随机淘汰
  • volatile-ttl:淘汰过期时间最近的 key
  • noeviction:默认策略,不淘汰任何 key,写操作返回错误
Redis集群方案
  • 主从模式:一个 master 节点,多个 slave 节点,master 节点宕机, slave 自动变成主节点

  • 哨兵模式:在主从集群基础上添加哨兵节点或哨兵集群,用于监控 master 节点健康状态,通过投票机制选择 slave 成为主节点

  • 分片集群:多个 master 节点, 不同 master 保存不同的数据,master 之间通过 ping 相互监测健康状态。客户端请求任意一个节点都会转发到正确节点,因为每个master都被映射到0-16384个插槽上,集群的key是根据key的hash值与插槽绑定

什么是 Redis 主从同步?

主从同步第一次是全量同步, slave 第一次请求 master 节点根据 replid 判断是否是第一次同步,是的话 master 会生成 RDB 发送给 slave

增量同步, 后续主节点的写操作会通过复制缓冲区同步到从节点

好处:提高读吞吐量,主节点故障时从节点可切换为主节点

Redis 分片集群中数据是怎么存储和读取的?
  • 存储
    1. 集群将 16384 个哈希槽分配给各主节点(如 3 主节点分别负责 0-5460、5461-10922、10923-16383 槽)
    2. 写入 key 时,通过 CRC16(key) % 16384 计算槽位,自动路由到对应主节点
  • 读取
    1. 客户端首次连接时获取集群槽位映射表,后续直接定位节点
    2. 若槽位迁移(如扩容),节点返回 MOVED 重定向,客户端更新映射表后重试
Redis 集群脑裂是什么?如何解决?
  • 定义:主从集群中,主节点网络波动导致哨兵误判其下线,选举从节点为新主,原主节点恢复后出现 “双主”(脑裂),数据写入旧主会丢失
  • 解决方法
    1. 配置 min-replicas-to-write 1:主节点必须至少有 1 个从节点连接正常才允许写操作
    2. 配置 min-replicas-max-lag 10:从节点同步延迟超过 10 秒,主节点拒绝写操作
怎么保证 Redis 的高并发高可用?
  • 高并发
    • 分片集群(Redis Cluster)分散读写压力
    • 合理使用管道(Pipeline)和批量命令(如 MSET)减少网络交互
    • 优化数据结构(如用 Hash 替代多个 String
  • 高可用
    • 主从 + 哨兵模式,自动故障转移
    • 数据持久化(RDB+AOF)防止数据丢失
    • 限流保护(如用 redis-cell 模块)避免突发流量压垮集群
http://www.lryc.cn/news/596480.html

相关文章:

  • AI视频-剧本篇学习笔记
  • 猎板 PCB:多场景适配下印制线路板的材料选择优化策略
  • 《2025年5月鸽哒IM即时通讯原生双端APP源码解析:支持视频通话与实时语音(附实测数据)》
  • C语言:函数基础
  • 博途V18软件Automation License Manager中发生了内部错误解决方法
  • SMTP+VRRP实验
  • 14.8 LLaMA2-7B×Dolly-15K实战:从准确率63%到89%,如何用优质数据让大模型性能飙升42%?
  • C语言(20250722)
  • C语言(八)
  • es搜索实现既能模糊查询又能分词查询
  • 永不疲倦的守护者:Deepoc具身智能如何重塑安保机器人的“火眼金睛”
  • Kotlin多线程调试
  • 【机器学习】第五章 聚类算法
  • [Semantic Seg][KD]FreeKD: Knowledge Distillation via Semantic Frequency Prompt
  • JS--M端事件
  • Docker容器 介绍
  • Taro 网络 API 详解与实用案例
  • 闲庭信步使用图像验证平台加速FPGA的开发:第三十课——车牌识别的FPGA实现(2)实现车牌定位
  • STM32-第十节-DMA直接存储器存取
  • Collection接口的详细介绍以及底层原理——包括数据结构红黑树、二叉树等,从0到彻底掌握Collection只需这篇文章
  • Class10简洁实现
  • IDEA-自动格式化代码
  • 嵌入式 Qt 开发:实现开机 Logo 和无操作自动锁屏
  • C语言面向对象编程
  • linux 环境服务发生文件句柄泄漏导致服务不可用
  • 自定义HAProxy 错误界面
  • 开发板系统烧写
  • 【数学建模|Matlab】Matlab「基础知识」和「基础操作」
  • Vue3 面试题及详细答案120道(31-45 )
  • Arraylist与LinkedList区别