redis学习:延迟队列 异步消息队列

redis延迟队列使用zset有序列表来实现 对于如加锁失败的线程 如果一直轮询会消耗资源 但如果使用sleep那么遇到死锁时就会彻底瘫痪 所以会使用延迟队列。

当获取锁失败 会把消息序列序列化为字符串作为zset的value 把时间戳作为score (如time()+5 )多个线程对延迟队列进行轮询:lua脚本(网络往返从两次变为一次 并且多线程情况下因为lua原子性不会出现多个线程查询但只有一个线程能执行的现象) 每次zrangebyscore取出范围为0到当前时间戳的第一个value 然后zrem删除(抢到了) 之后处理业务逻辑。

消息队列:可以使用redis 的list作为消息队列 生产者使用lpush/rpush 消费者使用blpop/brpop b是blocking 就是阻塞读 在消息队列为空的时候 会进入休眠状态 当有任务会立即唤醒

但redis作为消息队列有一定的缺点1.redis数据在内存中 没有持久化时宕机数据即丢失 即使开启aof每秒刷盘 但还是可能会丢失一秒的数据 如果开启appendfsync always 那么又大大影响性能 无法支持高并发任务。 2.消息确认机制不足 不同于mq的ack/nack的消息确认机制 redis作消息队列本身没有确认机制 可能会导致重复消费或者消费失败后任务丢失 3.主从同步延时 redis主从异步复制 在故障切换时可能会丢失数据 如果redis主节点在写入或修改后 还没来得及同步到从节点就宕机 那么切换从节点后可能会丢失关键据

无法做到高一致性 4. 可能带来性能瓶颈 阻塞读需要创建tcp连接去监听队列 在高并发的情况下 大量tcp连接会占用大量资源 同时这些连接的建立 断开会带来cpu压力 如果brpop/blpop还有超时管理机制(超时将阻塞的客户端直接移除) 在高并发场景下会带来大量cpu压力( redis使用无序双向链表来存储时间事件 每次事件循环迭代,遍历时间事件链表,检查是否有事件到期 这会带来cpu消耗)

全部评论

相关推荐

头像
05-09 16:23
已编辑
华南师范大学 Java
一面后1小时通知二面——————————#面试问题记录#整整一个小时的拷打,场景题+项目拷打 几乎无八股文🧠 个人背景与项目经历1.你自我介绍一下?2.你做的两个项目中,哪个是实习?哪个是练手项目?3.实习项目主要做了什么?用到了哪些技术和框架?4.练手项目是独立做的吗?用了哪些模块和功能?    5.你对这个练手项目熟悉吗?可以详细介绍一下它的功能模块?💻 技术能力 - 后端开发1.你项目的XX流程是怎么实现的?Redis + Lua 在其中起到什么作用?2.你项目的Redis 缓存预热结构是怎样的?怎么判断用户状态?3.你用 MQ 的目的是什么?为什么不是直接操作数据库?4.MQ 消费失败的情况下你是怎么处理的?有重试机制吗?5.死信队列和超时取消使用的是同一个吗队列?怎么区分消息类型?6.redis成功执行写入了但 MQ 落库消费失败怎么办?Redis 写成功就代表成功吗?7.JWT 是怎么生成和校验的?用了什么加密算法?8.用户主动登出是怎么实现的?🧵 多线程与分布式9.Redis 的原子性是怎么保证的?10.项目中你有没有考虑幂等性?怎么防止重复请求的幂等性?11.XX场景中是否能做到最终一致性?如何通知用户成功?☁ MQ & 延迟任务12.延迟队列的作用是什么?项目中用来处理哪类业务?13.死信队列是如何配置的?超时和消费者消费失败如何分别处理?14.如果 MQ 消息失败进入死信队列,你是如何排查和处理的?15.MQ 消息失败重试到上限后该怎么办?16.使用 RabbitMQ 是为了提高性能还是为了消息可靠性?17.项目中有没有处理 MQ 消息重复消费问题?🧩 MySQL & 数据库能力18.MySQL 的 B+树结构你了解吗?聚簇索引和非聚簇索引有什么区别?19.建立索引有什么原则?如何判断字段是否适合建索引?20.用“性别”字段建索引合适吗?为啥说选择性低不适合?21.全表扫描和使用区分度低的索引扫描哪种情况下更快?22.大分页 offset 性能差怎么优化?23.在实习中是怎么优化SQL的? 🎯场景题:高并发请求失败后处理方式💡 题目背景描述:你接入了一个第三方服务,该服务每天发送约 300 万次请求给你们系统。其中,每个请求都包含一个全局唯一的 requestId(一个 40 字节的 UUID 字符串)。如果因为网络中断、超时等原因导致第三方没有收到响应,它会重新发起完全相同的请求(带相同的 requestId),业务上有几个关键限制:    1、每个 requestId 表示一次业务处理,例如支付通知、回调、交易同步等。    2、你方必须保证对于每个 requestId,只能处理一次(典型的幂等性要求)。    3、不能重复请求第三方服务(第三方服务不具备幂等性)    4、由于网络波动或响应失败,同一个 requestId 有可能会在不同时间再次被发送过来,甚至有以下复杂时间分布:        4.1、绝大部分重复请求会在20 分钟内重发;        4.2、一小部分会在1 天内重发;        4.3、极个别(例如接口挂起重试)会在一年后突然重发。🤯 关键技术难点:    如何快速识别“是否已处理过某 requestId”?    如何既不误判(重复处理)又不滥用资源(存一年)?    如何兼顾吞吐量、IO压力、成本?
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客企业服务