消息队列数据存储设计案例 - 模块八
假设消息队列存储的消息数据采用 MySQL 存储,如何设计?
一、存储架构设计
消息队列存储设计主要涉及的两个问题域包括:
大量消息数据如何存储
高并发消息读写如何应对
参照之前的存储架构选择逻辑:
数据存储单机无法存储所有数据,因此需要考虑数据分片存储
单机写性能肯定也无法支撑,因此也必须采用分片存储
单机读性能也无法支撑所有数据的读取,因此需要考虑主从复制
二、存储表设计
首先看一个简化的消息队列包含哪些元素,参考 kafka 队列模型:
DataNode: 数据节点, 单节点 MySQL 存储不下所有,因此需要多实例存储
Topic: 主题、队列,1 个 topic 可以有多个分区
Partition:分区/分片,主要应对前面提到的,单机无法存储,以及单机无法支撑写性能时需要分片
Consumer、Producer:生产者、消费者
ConsumerGroup:消费者分组,组内消费者共同消费同一个 topic
ConsumerOffset:消费进度,消费者消费到的位置,如果消费线程挂了,可从记录的消费位置重新进行消费, 1 个消费者可以消费多个分区的数据,但是 1 个分布不能被多个消费者消费(offset 会乱)
如果对应到存储表设计,应该包含哪些表了?可以分为队列元数据表和队列消息数据表
DataNode 元数据: 包含 data_node_id(主键),MySQL 实例 ID,账号、密码信息等信息
Topic 元数据:包括 topic_id(主键),topic 名称,topic 描述,table_name 表名
Partition 分区元数据:partition_id(主键),所属 topic_id,所属 data_node_id,分区内有序
ConsumerGroup 元数据:consumer_group_id (主键),group_code 分组标识, group_des 分组描述
Consumer 元数据:consumer_id(主键), consumer_group_id 所属消费分组,
ConsumerOffset 消费偏移量:offset_id(主键) consumer_id, partition_id 消费那个分区,分区当前消费偏移量 offset
以上为消息队列的元数据表,元数据的数据量不会很大,因此无需考虑数据做分区分表,其中 ConsumerOffset 可能会频繁刷写,需要考虑读写缓存,异步刷表,缓存丢失可能重复消费,需要业务幂等
消息数据表:存储实际的消息数据
pd_分区 ID 做表名 ,数据分区表 每个 partition 对应一张表,数量增大后,可以通过增加 DataNode, 增加新的分区表数量,增加新的分区表来扩展存储
包含字段:主键 ID(自增),biz_id 业务键 ID,msg_body 消息体
评论