说一下redis变乱底层原理

[复制链接]
发表于 2025-10-21 06:21:50 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
Redis变乱

1. 变乱的根本流程

Redis 变乱通过 MULTI、EXEC、WATCH 等下令实现,底层原理可以分为以下几个步调:
(1) MULTI 下令


  • 当客户端发送 MULTI 下令时,Redis 会将客户端标记为“变乱模式”。
  • 在变乱模式下,客户端发送的全部下令不会立刻实行,而是被放入一个队列(下令队列)中。
(2) 下令入队


  • 在 MULTI 和 EXEC 之间,客户端发送的全部下令都会被追加到变乱队列中。
  • 这些下令不会立刻实行,而是等候 EXEC 下令的触发。
(3) EXEC 下令


  • 当客户端发送 EXEC 下令时,Redis 会依次实行变乱队列中的全部下令。
  • 实行过程中,全部下令是原子的,不会被其他客户端的下令打断。
(4) WATCH 下令


  • WATCH 下令用于实现乐观锁。
  • 当客户端对一个或多个键实行 WATCH 后,如果在 EXEC 实行之前,这些键被其他客户端修改,则当前变乱会失败(返回 nil)
watch我们可以指定监听一个键和多个键,然后exec批量实行
  1. WATCH key [key ...]
复制代码

2. 变乱的原子性


  • Redis 变乱的原子性是通过单线程模子实现的。
  • Redis 是单线程的,全部下令都是序次实行的。在 EXEC 实行时,变乱队列中的下令会连续实行,不会被其他客户端的下令打断。

3. 变乱的同等性


  • Redis 变乱的同等性是通过 WATCH 机制实现的。
  • 如果 WATCH 的键在变乱实行期间被修改,变乱会失败,从而包管数据的同等性。

4. 变乱的范围性


  • 不支持回滚:如果变乱中的某个下令失败,其他下令仍旧会实行,Redis 不会自动回滚。
  • 部门失败标题:变乱中的下令大概会部门乐成、部门失败。
  • 性能开销:WATCH 机制会增长额外的性能开销。

Redis 7 对变乱的优化

Redis 7 在变乱机制上并没有完全改变底层实现,但引入了一些优化和改进:
1. 性能优化


  • Redis 7 对变乱的实行流程举行了优化,镌汰了变乱模式下的性能开销。
  • 通过改进下令队列的处置惩罚方式,进步了变乱的实行服从。
2. Lua 脚本的增强


  • Redis 7 对 Lua 脚本的支持举行了增强,使得 Lua 脚本可以更好地与变乱联合使用。
  • Lua 脚本在 Redis 7 中的实行服从更高,同时支持更多的 Redis 下令。
3. 更好的错误处置惩罚


  • Redis 7 改进了变乱中的错误处置惩罚机制,使得变乱失败时的错误信息更加清晰。
  • 如果变乱中的某个下令失败,Redis 7 会返回更详细的错误信息,方便排查标题。
4. 功能增强


  • Redis 7 引入了更多的下令和功能,可以与变乱联合使用。
  • 比方,Redis 7 支持更多的数据范例和操纵,使得变乱可以处置惩罚更复杂的场景。

Redis 变乱的底层实现细节

1. 下令队列


  • 在变乱模式下,Redis 会为每个客户端维护一个下令队列。
  • 全部在 MULTI 和 EXEC 之间发送的下令都会被追加到队列中。
2. 变乱实行


  • 当 EXEC 下令被触发时,Redis 会依次实行下令队列中的全部下令。
  • 实行过程中,Redis 会包管下令的原子性,不会被其他客户端的下令打断。
3. WATCH 机制


  • WATCH 下令会监督一个或多个键。
  • 如果在 EXEC 实行之前,这些键被其他客户端修改,则当前变乱会失败。
  • WATCH 的实现基于 Redis 的键空间关照机制。

总结


  • Redis 变乱的底层原理 是基于 MULTI/EXEC/WATCH 机制,通过下令队列和乐观锁实现原子性和同等性。
  • Redis 7 在变乱机制上举行了性能优化和功能增强,但底层实现并没有本质厘革。
  • Redis 变乱的范围性 包罗不支持回滚、部门失败标题和性能开销。
  • 如果必要更强盛的变乱支持,可以联合 Lua 脚本或使用支持 ACID 变乱的数据库。

Redis+Lua脚本实现手动回滚赔偿

我们每一步实行失败,我们就依次打消前面的操纵
痛惜这个并不是真正的acid,我们的mysql实行变乱的时间宕机了,它的变乱没有提交以是数据并不会进到mysql内里
而redis是人为控制的,以是我们实行lua脚本的时间宕机了,我们之前变乱中实行的操纵数据仍旧进去了,这个是我们无法办理的
  1. local key1 = KEYS[1]
  2. local key2 = KEYS[2]
  3. local key3 = KEYS[3]
  4. local value = ARGV[1]
  5. -- 记录原始值
  6. local original_value1 = redis.call('GET', key1)
  7. local original_value2 = redis.call('GET', key2)
  8. local original_value3 = redis.call('GET', key3)
  9. -- 第一步操作
  10. redis.call('SET', key1, value)
  11. -- 第二步操作
  12. if redis.call('EXISTS', key2) == 0 then
  13.     -- 手动回滚第一步操作
  14.     redis.call('SET', key1, original_value1)
  15.     return "Key2 does not exist"
  16. end
  17. redis.call('SET', key2, value)
  18. -- 第三步操作
  19. if redis.call('EXISTS', key3) == 0 then
  20.     -- 手动回滚前两步操作
  21.     redis.call('SET', key1, original_value1)
  22.     redis.call('SET', key2, original_value2)
  23.     return "Key3 does not exist"
  24. end
  25. redis.call('SET', key3, value)
  26. return "Transaction successful"
复制代码
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表