写点什么

设计消息队列存储消息数据的 MySQL 表格

作者:哈喽
  • 2022 年 6 月 08 日
  • 本文字数:1481 字

    阅读完需:约 5 分钟

总体分三类表:消息信息表、消息消费记录表、消息消费进度表


1、消息信息表

这是一套表,表名为:xxx_message_info_x。其中前面的 xxx 表示 topic 名称;后面的 x 表示时间,例如 202206;

如表名 topicA_message_info_202206,表示存储的是主题为 topicA 的 2022 年 6 月的全量消息。

由于消息会越积越多,因此使用 topic 和日期分表,一个 topic 一个月分一张表,可以减小每张表的容量,增加查询效率。

其中消息 ID 要使用分布式 ID 生成器生成,保证 ID 顺序

索引:由于会使用消息 ID 查询,且消息 ID 是唯一的,因此需要将消息 ID 创建为唯一索引

为了方便用户根据业务信息查询,增加 message_key,可以存储业务数据,例如订单号等,用户可以在控制台提供 主题 + 日期 + 业务 key 查询,由于已经根据 topic 和日期分表,因此只需要创建 message_key 的索引即可。

CREATE TABLE `xxx_message_info_x` (  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',  `message_id` int(11) NOT NULL COMMENT '消息ID',	`message_key` VARCHAR(50) DEFAULT NULL COMMENT '消息Key',	`message_data` json NOT NULL COMMENT '消息内容',	`ip` int(10) DEFAULT NULL COMMENT '生产者ip',	`port` int(5) DEFAULT NULL COMMENT '生产者端口',	`group` varchar(255) DEFAULT NULL COMMENT '生产者组',  `send_time` varchar(255) NOT NULL COMMENT '消息发送时间',  PRIMARY KEY (`id`),  UNIQUE KEY `i_message_id` (`message_id`) USING BTREE,	KEY `i_message_key` (`message_key`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;
复制代码

2、消费记录表

跟消息信息表一样采用 topic 和日期分表,但是消息 ID 不再是唯一索引,因为可能存在一条消息被不同的消费组消费的情况,同时还可能存在人为消息回拨的情况。

记录每一条信息的消费情况,主要是消费者组、消费者的 ip 和端口、消费时间等信息

CREATE TABLE `xxx_message_info_consumption_x` (  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',  `message_id` int(11) NOT NULL COMMENT '消息ID',	`message_key` VARCHAR(50) DEFAULT NULL COMMENT '消息Key',	`consumer_group_id` varchar(255) NOT NULL COMMENT '消费者组',	`ip` int(10) DEFAULT NULL COMMENT '消费者ip',	`port` int(5) DEFAULT NULL COMMENT '消费者端口',  `consumeption_time` varchar(255) NOT NULL COMMENT '消息发送时间',  PRIMARY KEY (`id`),  KEY `i_message_id` (`message_id`) USING BTREE,	KEY `i_consumeption_time` (`consumeption_time`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;
复制代码

3、消费进度表

该表不做分表处理,所有的 topic 存储在一张表,只记录每一 topic 下所有消费者组的消费进度,每一次消费时查询该表获取需要消费的消息,然后再从消息表中查询具体的消息内容。

索引:由于需要根据 topic 和消费者组查询待消费的数据,因此消费组 ID+消费进度分区需要作为索引

CREATE TABLE `message_consumption` (  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '消费进度表ID',	`topic_id` varchar(255)  NOT NULL COMMENT 'topic ID',  `next_message_id` int(11) NOT NULL COMMENT '下一条可以消费的消息ID',  `consumer_group_id` varchar(255) NOT NULL COMMENT '消费者组',  `message_date` int(8) NOT NULL COMMENT '消费进度分区',  `update_time` datetime DEFAULT NULL,  PRIMARY KEY (`id`),	KEY `i_message` (topic_id,consumer_group_id) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;
复制代码


用户头像

哈喽

关注

还未添加个人签名 2018.11.14 加入

还未添加个人简介

评论

发布
暂无评论
设计消息队列存储消息数据的 MySQL 表格_「架构实战营」_哈喽_InfoQ写作社区