当前位置:网站首页>延时消息常见实现方案
延时消息常见实现方案
2022-04-23 21:57:00 【InfoQ】
前言
实现方案
1. 基于外部存储实现的方案
基于 数据库(如MySQL)
CREATE TABLE `delay_msg` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`delivery_time` DATETIME NOT NULL COMMENT '投递时间',
`payloads` blob COMMENT '消息内容',
PRIMARY KEY (`id`),
KEY `time_index` (`delivery_time`)
)
- 实现简单;
- B+Tree索引不适合消息场景的大量写入;
基于 RocksDB
- RocksDB LSM 树很适合消息场景的大量写入;
- 实现方案较重,如果你采用这个方案,需要自己实现 RocksDB 的数据容灾逻辑;
基于 Redis
- Messages Pool 所有的延时消息存放,结构为KV结构,key为消息ID,value为一个具体的message(这里选择Redis Hash结构主要是因为hash结构能存储较大的数据量,数据较多时候会进行渐进式rehash扩容,并且对于HSET和HGET命令来说时间复杂度都是O(1))
- Delayed Queue是16个有序队列(队列支持水平扩展),结构为ZSET,value 为 messages pool中消息ID,score为过期时间**(分为多个队列是为了提高扫描的速度)**
- Worker 代表处理线程,通过定时任务扫描 Delayed Queue 中到期的消息
- Redis ZSET 很适合实现延时队列
- 性能问题,虽然 ZSET 插入是一个 O(logn) 的操作,但是Redis 基于内存操作,并且内部做了很多性能方面的优化。
定时线程检查的缺陷与改进
2. 开源 MQ 中的实现方案
RocketMQ
- Level 数固定,每个 Level 有自己的定时器,开销不大
- 将 Level 相同的消息放入到同一个 Queue 中,保证了同一 Level 消息的顺序性;不同 Level 放到不同的 Queue 中,保证了投递的时间准确性;
- 通过只支持固定的Level,将不同延时消息的排序变成了固定Level Topic 的追加写操作
- Level 配置的修改代价太大,固定 Level 不灵活
- CommitLog 会因为延时消息的存在变得很大
Pulsar
- **内存开销:**维护延时消息索引的队列是放在堆外内存中的,并且这个队列是以订阅组(Kafka中的消费组)为维度的,比如你这个 Topic 有 N 个订阅组,那么如果你这个 Topic 使用了延时消息,就会创建 N 个 队列;并且随着延时消息的增多,时间跨度的增加,每个队列的内存占用也会上升。(是的,在这个方案下,支持任意的延时消息反而有可能让这个缺陷更严重)
- **故障转移之后延时消息索引队列的重建时间开销:**对于跨度时间长的大规模延时消息,重建时间可能会到小时级别。(摘自 Pulsar 官方公众号文章)
- 存储开销 :延时消息的时间跨度会影响到 Pulsar 中已经消费的消息数据的空间回收。打个比方,你的 Topic 如果业务上要求支持一个月跨度的延时消息,然后你发了一个延时一个月的消息,那么你这个 Topic 中底层的存储就会保留整整一个月的消息数据,即使这一个月中99%的正常消息都已经消费了。
QMQ
- 时间轮算法适合延时/定时消息的场景,省去延时消息的排序,插入删除操作都是 O(1) 的时间复杂度;
- 通过多级时间轮设计,支持了超大时间跨度的延时消息;
- 通过延时加载,内存中只会有最近要消费的消息,更久的延时消息会被存储在磁盘中,对内存友好;
- 延时消息单独存储(schedule log),不会影响到正常消息的空间回收;
总结
版权声明
本文为[InfoQ]所创,转载请带上原文链接,感谢
https://xie.infoq.cn/article/add4395e1eaf60c3dec4e5f2e
边栏推荐
- 在线Excel转CSV工具
- Plato farm is one of the four largest online IEOS in metauniverse, and the transaction on the chain is quite high
- Alibaba cloud responded to the disclosure of user registration information
- Resolve the "chromedriver executable needs to be in path" error
- 危机即机遇,远程办公效率为何会提升?
- C, print the source program of beautiful bell triangle
- Ali has another "against the sky" container framework! This kubernetes advanced manual is too complete
- MySQL 回表
- setInterval、setTimeout、requestAnimationFrame
- 如何发挥测试策略的指导性作用
猜你喜欢
DeNO 1.13.2 release
小米手机全球已舍弃“MI”品牌,全面改用“xiaomi”全称品牌
C#,打印漂亮的贝尔三角形(Bell Triangle)的源程序
Online Excel to CSV tool
IIS cannot load * woff,*. woff2,*. Solution of SVG file
C reads excel specific data into specific columns of DataGridView
Oracle ora-01033: Oracle initialization or shutdown in progressprocess solution
[leetcode refers to offer 21. Adjust the array order so that odd numbers precede even numbers (simple)]
2. Finishing huazi Mianjing -- 2
阿里又一个“逆天”容器框架!这本Kubernetes进阶手册简直太全了
随机推荐
ERP function_ Financial management_ The difference between red and blue words in invoices
Express ③ (use express to write interface and cross domain related issues)
Google 尝试在 Chrome 中使用 Rust
[leetcode refers to the two numbers of offer 57. And S (simple)]
Use 3080ti to run tensorflow GPU = 1 X version of the source code
Opencv application -- jigsaw puzzle
ubutnu20安装CenterNet
上海确保疫情保供生活物资质量和食品安全
Tensorflow1. X and 2 How does x read those parameters saved in CKPT
[leetcode refers to offer 22. The penultimate node in the linked list (simple)]
MySQL 回表
管道和xargs
Online Excel to CSV tool
Presto on spark supports 3.1.3 records
使用mbean 自动执行heap dump
JS merge duplicate data in array object
YOLOv5 Unable to find a valid cuDNN algorithm to run convolution
1. Finishing huazi Mianjing -- 1
[※ leetcode refers to offer 48. The longest substring without repeated characters (medium)]
Alibaba cloud responded to the disclosure of user registration information