TMQ:定时消息队列原理与实现

TMQ

TMQ: Timing Message Queue,定时消息队列。

概念

什么是定时消息队列?

存储在队列中的消息,可以按投递时间顺序获取。

用(t,m)表示一个消息,其中t是投递时间,m是消息体,则对于先后推送至队列中的消息(t1,m1),(t1,m2),当按投递时间t1获取时,将先后获取到m1、m2。

应用场景

  • 新用户注册,第二天上午9点发放优惠券,则可以在新用户注册时推送一条定时消息,消息投递时间为第二天上午9点,消息体可以是用户ID
  • 用户下单,半小时后提醒用户付款,消息投递时间为半小时后,消息体为订单ID
  • 发起投票,截止前1小时、半小时分别提醒用户投票,则可以推送一批定时消息,每个消息携带不同的投递时间和用户ID

总的应用场景就是需要定时或延时触发的消息。

设计思路

思路1

消息存储于数据表,表中有投递时间字段,并给该字段加索引。
获取消息时按投递时间查询,并按自增ID顺序获取。
需要额外的状态字段标识消息是否已被读取。
存在的问题

  • 当一个投递时间有大量消息时,索引是低效的

思路2

在思路1的基础上,采取分表策略,基于投递时间横向拆分。
解决了索引低效的问题,按自增ID顺序获取即可。
存在的问题

  • 表数量不可控
  • 表数据量分布不均

思路3

采用思路2的分割思想,消息仍存储于数据表中,将相同投递时间的消息ID存储于同一列表中。
获取消息时,首先从列表中取出消息ID,然后从数据表中查出消息数据。

思路3解决了上述问题,满足需求。

技术选型

  • 数据库 MySQL
  • 列表 Redis LIST

Redis List有原子化的PUSH/POP操作,且性能很高,这确保能够高效获取消息。

数据存储示意

TMQ:定时消息队列原理与实现_第1张图片

源码地址

TMQ

你可能感兴趣的:(队列,java,redis)