面试之Redis

第一篇。redis复习

reids使用场景:

方法一:缓存空数据

解决方法二:布隆过滤器

布隆过滤器:

每次请求的数据会计算其hash值,如果不存在,那么在布隆过滤器中的值为1,否则为0,在redis缓存预热的时候,也要把布隆过滤器给预热

布隆过滤器可能产生误判

布隆过滤器本质是一个二进制数组(bit array,每个元素只有 0/1 两种状态) + 多个独立的哈希函数,它不存储 “值本身”,只存储 “值存在的痕迹”

二、关键逻辑:布隆过滤器与 MySQL 的 “数据同步关系”

布隆过滤器的 “零假阴性”(判断不存在则一定不存在),需要一个前提:所有 MySQL 中 “存在的值”,都已经提前写入了布隆过滤器

在实际业务中,这个前提是通过 “数据写入流程的强绑定” 实现的:

  • 当我们向 MySQL 插入一条新数据(比如新增 user_id=789)时,会同步执行 “将该值写入布隆过滤器” 的操作(即完成上述 “哈希映射 + 位设为 1” 的步骤);
  • 当 MySQL 中删除一条数据时(虽然布隆过滤器不支持直接删,但可通过 “定期重建布隆过滤器” 确保一致性:用 MySQL 现有所有数据重新构建一个新的布隆过滤器,替换旧的)。

解决方案:1:互斥锁 2 :逻辑过期

互斥锁可以保证数据强一直性,缺点就是性能差

逻辑过期:高可用,性能优

根据具体业务场景进行选择

总结:

三:缓存雪崩

总结:

问:redis作为缓存,mysql的数据如何与redis进行同步呢?(双写一致性)

第一种情况:要求强一致性

读写锁:

排他锁:

第二种情况(可以接收短暂不一致):

方案一:

异步通知保证数据的最终一致性:基于mq

方案二:

基于canal的异步通知:

总结:

方式一:RDB

方式二:AOF

RDB和aof在redis数据失效重启后如果查询到有rdb或者aof文件会自动恢复,无需人工干预

AOF 和 RDB 文件不存在内存中,而是持久化存储在磁盘中的文件 —— 这正是 Redis “持久化” 的核心意义:将内存中易失的数据(断电 / 重启即丢失)保存到磁盘,避免数据因服务中断而丢失。

问:假如redis的key过期后,会立即删除吗

有两种解决方案,第一种 惰性删除 第二种 立即删除

惰性删除:

定期删除:

总结:

问题八:分布式锁

抢卷场景:

也就是超卖现象,由于线程是交替执行,如果第一个还剩一个,在第一个线程扣减库存之前,第二个线程又查询库存为一,这样两个线程就会扣减两次,最终库存为-1

第一种方法加锁:synchronized

如果是单体项目没问题,如果是集群模式,就不行了

synchronized属于jvm,每个服务器都有各自的jvm

这就是分布式锁

redisson其实已经封装好了现成的分布式锁解决方案:

假如锁的释放时间是30秒,如果业务还没完成,那么看门狗就会以10秒的时间进行续期

如果另一个线程未抢到锁,那么就会触发redisson的重试机制,到一定次数可以停止

如果填了锁的释放时间,那么redisson就会取消看门狗,不会给你续期,否则会续期

redisson实现的分布式锁可重入

如果是第一个锁那么value就是1,再加一个锁就会是2,释放锁后减一,释放锁

redisson主从一致性:如果主节点(用来写操作),从节点(用来读操作),如果主节点宕机后,那么就会选择一个从节点当做主节点

解决方法:RedLock(红锁)

红锁缺点:

红锁

要理解 红锁(Redlock),首先需明确其核心定位:它是 Redis 官方提出的一种分布式锁实现方案,用于解决单机 Redis 锁在 “主从架构 / 集群环境下的可靠性问题”—— 本质是通过多节点冗余,规避单节点故障导致的锁失效风险,确保分布式场景下锁的 “安全性” 与 “可用性”。

一、红锁(Redlock)的诞生背景:解决单机 Redis 锁的致命缺陷

在了解红锁前,需先明确其要解决的核心问题:单机 Redis 锁在主从架构下的 “锁丢失” 风险

常规的单机 Redis 锁(如用 SET key value NX EX 命令实现)逻辑是:客户端向 Redis 节点发送 “互斥指令”,成功则获取锁,失败则等待 / 放弃。但在 Redis 主从架构中,存在一个致命问题:

  • Redis 主从复制是异步的:主节点(Master)处理完锁请求(如 SET lock 1 NX EX 10)后,会直接返回 “锁成功”,但数据同步到从节点(Slave)需要时间。
  • 若主节点在同步锁数据到从节点前突然宕机,哨兵 / 集群会将从节点提升为新主节点。此时新主节点中没有之前的锁记录,其他客户端会误以为 “锁已释放”,重新获取到锁 —— 导致 “一把锁被两个客户端同时持有”,破坏锁的 “互斥性”,引发业务数据冲突(如重复下单、并发修改同一数据)。

红锁的设计目标,就是通过多独立 Redis 节点的冗余,彻底解决这种 “单节点故障导致的锁丢失” 问题。

二、红锁(Redlock)的核心原理:“多节点投票,少数服从多数”

红锁的核心逻辑基于 “分布式系统的冗余容错思想”,具体实现需满足两个前提:

  1. 部署 N 个独立的 Redis 节点(通常 N=5,奇数,避免投票平局):这些节点之间无主从关系,不进行数据复制,完全独立运行(可单机、可容器,甚至跨机房)。
  2. 客户端实现红锁逻辑时,需通过 “多节点请求 + 投票” 的方式获取锁,而非仅请求单个节点。

红锁的完整执行流程(以 N=5 为例)

红锁的获取与释放过程严格遵循 “少数服从多数” 原则,具体步骤如下:

1. 锁的获取阶段(核心:满足 “多数节点成功”)

客户端要获取红锁,需依次执行以下操作:

  • 步骤 1:生成唯一标识(UUID)
    客户端生成一个全局唯一的 Value(如 UUID + 线程 ID),用于后续区分 “自己的锁” 和 “其他客户端的锁”,避免误释放他人的锁。
  • 步骤 2:设置超时时间(TTL)
    定义一个 “锁获取超时时间”(如 50ms),确保客户端向单个 Redis 节点请求锁时,不会因节点故障导致长时间阻塞(超过该时间则放弃该节点,视为请求失败)。
  • 步骤 3:向所有 N 个节点发起锁请求
    客户端同时(或串行但快速)向 5 个独立 Redis 节点发送 “获取锁” 的指令,指令格式与单机锁一致:
    SET lock_key 唯一UUID NX EX 锁有效期NX 表示 “不存在则创建”,EX 表示 “设置过期时间”,如 10 秒,避免锁永久占用)。
    注意:每个节点的请求都需独立计时,超过 “锁获取超时时间”(如 50ms)则视为该节点请求失败。
  • 步骤 4:判断是否获取锁成功
    客户端统计 “请求成功的节点数量”,若满足两个条件,则认为红锁获取成功:
    ① 成功的节点数量 ≥ (N/2) + 1(即多数节点,N=5 时需 ≥3);
    ② 所有成功节点的总耗时 ≤ 锁有效期的 1/3(避免因耗时过长,导致部分节点的锁已过期)。
    若不满足,则立即进入 “锁释放阶段”(释放所有已成功的节点的锁),避免残留无效锁。
2. 锁的持有阶段(核心:续期避免锁过期)

获取锁成功后,客户端需注意:

  • 锁的 “实际有效时间” = 锁有效期 – 锁获取总耗时(如锁有效期 10 秒,获取耗时 2 秒,则实际有效时间为 8 秒)。
  • 若客户端的业务逻辑执行时间可能超过 “实际有效时间”,需在锁过期前向 “所有成功的节点” 发起 “锁续期” 请求(如 Redisson 中的 renewExpiration 机制),避免锁提前过期被其他客户端抢占。
3. 锁的释放阶段(核心:清理所有节点的锁)

无论业务逻辑执行成功或失败,客户端都必须释放锁,避免死锁:

  • 客户端向所有 5 个节点发送 “释放锁” 的指令(即使某个节点在获取锁时请求失败,也需尝试释放,防止节点恢复后残留锁)。
  • 释放锁的指令需带 “唯一 UUID”,确保只释放自己持有的锁(避免误释放他人的锁),指令逻辑通常用 Lua 脚本实现:
    if redis.call('get', 'lock_key') == '唯一UUID' then return redis.call('del', 'lock_key') else return 0 end

三、红锁的核心特性:安全性 vs 可用性

红锁通过多节点冗余,解决了单机 Redis 锁的 “锁丢失” 问题,其核心特性可总结为:

特性说明
安全性只要多数节点(≥3/5)正常,即使少数节点(≤2/5)故障,锁仍能正常获取 / 释放,避免单节点故障导致的锁失效。
可用性支持少数节点故障(如 5 节点中最多允许 2 个节点宕机),集群仍能提供锁服务,可用性高于单机锁。
最终一致性释放锁时需向所有节点发起请求,即使部分节点暂时不可达,后续也会因锁过期自动清理,无数据残留。

如果是从节点第一次同步,主从repid不一致,主节点同步repid,生成rob文件,从节点会保存数据,如果下次再次同步,只需要在距离上次同步期间的时间内,将新增的数据文件repi-baklog文件中的数据进行恢复即可

主从数据同步之增量同步:

八股:

Mysql:

mysql-优化

问:在mysql中如何定位慢查询?(m1)

方案一:使用工具

一个是可以使用Arthas,还可以使用Skywalking等

方案二:Mysql自带慢日志

如果一个sql语句执行很慢,如何分析?

问:了解过索引吗,什么是索引?

B树和B+树的区别就是B+树的非叶子节点不存储数据,只存储指针,存储和查询压力都比B数小

问:什么是聚簇索引,什么是非聚簇索引?

用图像来描绘一下二级索引和聚集索引

可以看到,聚集索引结构的叶子节点存储的是该行数据

而二级索引存储的是唯一索引(某个索引的值)来用作索引

问:回表查询

简单的说就是通过二级索引去找到主键值,再去聚集索引里去查整行数据

问:知道什么是覆盖索引吗?

第一个sql由于where条件是id那么就会走聚集索引,查出来全部数据

第二个sql的where条件是name,会走二级索引,但是二级索引还存储了id,而sql的返回值刚好要得是id和name,一次性返回

第三个sql与第二个sql的区别就是sql查询值中多了一个gender,这个性别需要根据id再查一次,需要回表

答:

MYSQL超大分页处理:

用覆盖索引去解决超大分页的问题

答:

索引创建原则有哪些?

什么情况下索引会失效?

聚合索引中必须遵守最左匹配原则,不能跳着查
正例:

反例:

这个的情况下是下面两个都已经失效,因为违反了最左匹配原则

第三个,只有name符合最左匹配原则,所以虽然使用了索引,

但是只用到了name,未用到address

第二种情况:

第三种情况:

第四种情况:


第五种情况:

总结:

谈一谈你对sql优化的理解:

Mysql其他面试题:

什么是事务?

事务特性:ACID

并发事务问题:

问:Mysql主从同步原理

答:

问:分库分表:

博客内容均系原创,未经允许严禁转载!
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇