总体分三类表:消息信息表、消息消费记录表、消息消费进度表
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;
复制代码
评论