业务场景
业务中很多地方都需要任务调度。
有的任务是周期性执行,比如每隔半小时更新本地缓存数据
有的任务是延迟执行,比如订单15分钟未付款提醒,优惠券到期提醒
这显然要比第一种的难于实现很多:订单的数量/优惠券的数量(一般都是亿级/天)决定了调度任务数量庞大,触发时间分散
精度要求比较高,一般是精确到秒,
支持的最大时间越久,储存的数据量也越大
业务往往还要对任务进行修改和删除
除此以外,可用性、一致性、弹性伸缩、失败重试、监控告警也必须考虑
可见:技术方案还是要根据实际情况来选择,确定好性能指标,再选择
在生产环境的见过的实现主要有以下3类
1.使用mq的延迟消息和定时消息
- 典型代表:RocketMQ、DDmq(滴滴开源)、QMQ(去哪儿开源)
2.独立部署的任务调度平台
- 典型代表:xxl-job、elasticjob
3.快速实践型
- 典型代表:直接用redis:zset + score, 或者mysql 扫描表
想到的问题
问题1,mq的延迟消息对比独立的任务调度平台有啥优缺点?两者功能有些重合
基础设施做的好的大厂mq都集成了任意时间延迟消息,比如mafka(美团的mq)/rocketmq阿里云版本 实现上都包含了一个任务调度平台,由任务调度平台延迟发送到真正的mq topic中。那mq的任务调度 是不是 吞吐量更好可用性更加呢?
前公司 内部是既部署了自研任务调度平台,又部署了rocketMQ社区版,我觉得这样不好,因为业务开发的时候一般不会去了解很多实现原理,业务方也不想花很多时间去做选择,以及这么选择的原因,大家想的都是,能满足我的功能需求和性能需求就行,结果就是开源rocketMQ的固定级别延迟消息大家往往不用,都选择了用任务调度平台,也导致任务调度平台压力很大,多次宕机。。
问题2,时间轮的好处是什么?why use TimeWheel?
带着问题进入下部分…
方案调研和技术选型
Qmq、RocketMQ、xxl-job都是国产的,有着文档可读性高,上手更快的优势,还有国产情怀加持,下面就对比这几种实现
Qmq
- 实现原理
QMQ的延时/定时消息使用的是两层hash wheel来实现的。第一层位于磁盘上,每个小时为一个刻度(默认为一个小时一个刻度,可以根据实际情况在配置里进行调整),每个刻度会生成一个日志文件(schedule log),因为QMQ支持两年内的延迟消息(默认支持两年内,可以进行配置修改),则最多会生成 2 * 366 * 24 = 17568 个文件(如果需要支持的最大延时时间更短,则生成的文件更少)。第二层在内存中,当消息的投递时间即将到来的时候,会将这个小时的消息索引(索引包括消息在schedule log中的offset和size)从磁盘文件加载到内存中的hash wheel上,内存中的hash wheel则是以500ms为一个刻度。
我理解就是先写入磁盘缓冲一下,然后读取出来加入第一层磁盘时间轮,快到内存时间轮的范围时候,再加载到内存时间轮。
Qmq起初选择数据库作为 MQ Server 的消息存储,后来接的业务多了,不得不重新设计。
如果他们用的是分布式数据库,性能上是不是就没问题了呢。
metaserver: 部署两台应用,然后配置nginx作为负载均衡。metaserver依赖mysql,请确保mysql的可用性,但metaserver运行时不强依赖mysql,如果mysql故障,只会影响新上线的消息主题和新上线的消费者,对已有的无影响。
broker:部署两组,每组为一主一从两台,则至少部署4台
我的理解,broker都需要写磁盘,因此是有状态服务,client从metaserver拉取一个topic下的master服务器,通过rpc的形式调用master服务,master服务收到消息,同步给slave,然后ack client。
如果master宕机,slave可以继续提供读服务,但是不提供写,写请求可以路由到另一个master机器。
消费者也需要实时感知master的地址以及状态,正常情况下rpc到master获取数据,提交offset,master宕机后去slave读取消息。
性能方面没有找到相关数据支撑,但是从架构设计上看,消息比kafka多存储了几份,性能肯定得打点折扣。





















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)
![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)
