- 整体的执行流程如上图所示,核心理念通过lua脚本的原子性保证了数据获取(Lrange)和数据裁剪(Ltrim)的原子性执行 。
- 整体的消费流程选择pull模式,通过多线程循环轮询可消费的队列进行消费 。与借助于redis的pub/sub的通知机制实现消费流程的push模式相比,pull模式成本更低效果更佳 。
- Redis集群模式下,执行Lua脚本建议传单key,多key会报重定向错误 。
- 在不同的Redis版本下,Lua脚本针对null的返回值处理不同,参考官方文档 。
- 消费者的消费过程中通过循环遍历游戏列表,然后根据游戏去获取对应的消息对象,但是不同的游戏对应的热度不同,所以在消费端我们通过配置的方式为热门游戏单独开启消费线程进行消费,相当于针对不同游戏配置不同优先级的消费者 。
文章插图
文章插图
文章插图
- 生产和消费的QPS约为1w qps左右,整体上报QPS通过批量上报后会远低于生产的消息生产和消费的QPS 。
- 整体数据的使用游戏包名作为key进行存储,性能上不存在热点的问题 。
在描述完方案的原理和实现细节之后,进一步对适用的业务场景进行下总结 。整体方案是基于redis的基本数据结构构建一个伪消息队列,用以解决 消息的单个生产批量消费 的场景,通过多key形式实现消息队列的多Topic模式,重要的是能够借助于redis的原生能力在O(N)的时间复杂度完成批量消费 。另外该方案也可以降级作为实现先进先出定长的日志队列 。
七、总结
本文主要探索在特定业务场景下通过Redis的原生命令实现类MQ的功能,创新式的通过Lua脚本组合Redis的List的基础命令,实现了消息的分组,消息的定长队列,消息的批量消费功能;整体解决方案在线上环境落地并平稳运行,为特定场景提供了一种通用的解决方案 。
作者:Wang Zhi
来源:微信公众号:vivo互联网技术
出处
:https://mp.weixin.qq.com/s?__biz=MzI4NjY4MTU5Nw==&mid=2247494331&idx=1&sn=273c10d8c46068db850f1961be2f436b