关注

【从零开始学习Redis|第七篇】Redis 进阶原理篇:消息队列、分布式锁、缓存击穿与事务实现

一、Redis 如何实现消息队列?

1 为什么需要消息队列?
先想一个常见场景:

用户下单:

用户 → 下单服务 → 库存服务 → 物流服务 → 通知服务

如果全部 同步执行:

用户请求会非常慢

于是我们把流程改成:

用户

下单服务

写入消息队列

库存服务消费
物流服务消费
通知服务消费

这样:

下单接口立即返回

消息队列负责:

异步处理任务

2 Redis 如何实现队列?
Redis 最早使用的是:

List

Redis List 本质是一个 双端链表

支持操作:

LPUSH
RPUSH
LPOP
RPOP

我们可以实现一个队列。

生产者

RPUSH queue msg1
RPUSH queue msg2

消息进入队列。

消费者

LPOP queue

取出消息。

流程:

生产者 → RPUSH → Redis队列 → LPOP → 消费者

3 阻塞队列
普通队列有个问题:

如果队列为空
消费者要不断轮询

浪费 CPU。

Redis 提供:

BLPOP
BRPOP

作用:

如果队列为空
消费者阻塞等待

流程:

消费者等待

生产者写入

立即唤醒消费者

这就是 Redis 阻塞队列

二、Redis 分布式锁如何实现?

1 为什么需要分布式锁?
在分布式系统中:

多个服务实例
同时操作同一资源

例如:

秒杀库存

如果没有锁:

库存可能被超卖

所以需要:

分布式锁

2 Redis 实现锁的核心
Redis 有一个关键能力:

命令是原子执行

我们可以使用:

SET key value NX EX

含义:

NX = key不存在才设置
EX = 过期时间

3 加锁流程
客户端执行:

SET lock_key uuid NX EX 10

意思:

如果锁不存在 → 创建锁
10秒自动过期

如果成功:

获得锁

如果失败:

说明别人已经加锁

4 为什么 value 要用 UUID?
因为释放锁时需要校验:

只有锁的拥有者才能删除锁

释放锁:

if value == uuid
    DEL key

为了保证原子性,一般用 Lua脚本

5 Redis 锁的问题
Redis 锁有一个经典问题:

主从切换
锁丢失

解决方案:

RedLock算法

即:

多个 Redis 节点同时加锁
多数成功才算成功

三、Redis 缓存击穿问题

缓存系统有三个经典问题:

缓存穿透 缓存击穿 缓存雪崩

这里重点讲 缓存击穿

什么是缓存击穿?
场景:

某个热点数据:

key = product_100

有 10万请求/秒。

突然:

缓存过期

瞬间:

10万请求 → 数据库

数据库会被打爆。

这就是:

缓存击穿

解决方案1:互斥锁
流程:

请求发现缓存不存在

获取分布式锁

查询数据库

写入缓存

释放锁

其他线程:

等待缓存恢复

解决方案2:逻辑过期
缓存结构:

value + expireTime

流程:

缓存过期

返回旧数据

后台线程更新缓存

这样:

不会打爆数据库

四、Redis 事务实现原理

Redis 的事务非常特殊。

很多人误以为 Redis 事务和数据库一样。

其实不是。

Redis 事务核心命令:

MULTI
EXEC

流程:

MULTI
SET a 1
INCR a
EXEC

Redis 事务本质
Redis 事务:

命令队列

执行过程:

1 MULTI
2 命令进入队列
3 EXEC统一执行

流程:

客户端

MULTI

命令入队

EXEC

Redis顺序执行

Redis事务的特点
Redis 事务 不支持回滚

原因:

Redis 设计目标是:

简单 + 高性能

而回滚会导致:

性能下降 实现复杂

所以 Redis 的事务保证:

命令顺序执行

但不保证:

失败回滚

五、如何查看 Redis 全量同步日志?

主从复制 时,会发生:

全量同步

流程:

Slave → Master 请求同步
Master → 生成RDB
发送给 Slave

如果你想查看日志,可以看 Redis 的日志文件。

常见位置:

/var/log/redis/redis.log

或者在 Redis 配置中:

logfile /var/log/redis.log

查看同步日志
可以使用:

grep SYNC redis.log

或者:

grep PSYNC redis.log

常见日志:

Full resync from master
Background saving started
Synchronization with slave succeeded

含义:

开始全量同步 生成RDB 同步成功

转载自CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/2501_92547326/article/details/158889383

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--