架构实战训练营 - 模块 8 - 作业
作业
作业:设计消息队列存储消息数据的 MySQL 表格
【作业要求】
包括表名、字段、索引;
用文字描述设计思路和理由,例如:为什么设计某个索引?
一页 PPT 即可。
【提示】
需要考虑每个消息队列一张表,还是所有消息放一张表,里面加一个“队列名称”的字段。
答
前提
自研消息队列结构
消息发布
消息队列系统设计两个角色:生产者和消费者,每个角色都有唯一的名称。
消息队列系统提供 SDK 供各业务系统调用,SDK 从配置中读取所有消息队列系统的服务器信息,SDK 采取轮询算法发起消息写入请求给主服务器。
如果某个主服务器无响应或者返回错误,SDK 将发起请求发送到下一台主服务,相当于在客户端实现了分片的功能。
消息读取
消息队列系统提供 SDK 供各业务系统调用,SDK 从配置中读取所有消息队列系统的服务器信息,轮流向所有服务器发起消息读取请求。
消息队列服务器需要记录每个消费者的消费状态,即当前消费者已经读取到了哪条消息,当收到消息读取请求时,返回下一条未被读取的消息给消费者。
默认情况下主服务器提供读写服务,当主服务器挂掉后,从服务器提供读消息服务
表设计实现说明
partition_message_[topic_name]__[XX]表:每个数据分组,每个 topic 一个表
XX 为预先设定的编号。topic_name 为 topic 表的对应的数据。
写入流程:
根据轮询算法,确定写入的机器 ,
查询 ip_partition 表获取,partition_key
拼接表名 partition_message_[topic_name]__[partition_key ]表,写入数据
读取数据时:
1.根据轮询算法,确定读取的机器 ,
查询 ip_partition 表获取,partition_key
根据 consumer_id,topic_name,partition_key ,查询 consumer_offset 表,获取 offset (之前消费的 msg_id)
由于 msg_id 自增,target_msg_id=offset +1 查询,若没有 offset 取第一条
拼接表名 partition_message_[topic_name]__[partition_key ]表,根据 target_msg_id 查询表。
查到数据后,更新 consumer_offset 表,的 offset =查询的消息的 Id
具体表设计
topic 主题表
所属库:配置库
topic_id 自增 id
topic_name varchar(50) 唯一键索引
ip_partition 分区信息表
id 自增 Id
ip 机器 ip
partition_key 预设分区 key
索引
ip 唯一索引
producer 生产者表
所属库:配置库
producer_id 自增 id
producer_name varchar(50) 唯一键索引
topic_id topic 表 Id
consumer 表消费者
所属库:配置库
consumer_id 自增 id
consumer_name varchar(50) 唯一索引
consumer_offset 表消费者点位表
id
consumer_id, consumer 表 Id
topic_name topic 表 Id
partition_key 分区 Id,就是 message 表的尾号,message 表是分表的,每张表上有尾号。
offset 消费点位 对应 partition_message_XX 的 msg_id。
索引:
(consumer_id,topic_name,partition_key ) 联合唯一索引
partition_message_[topic_name]__[partition_key ]表
每个数据分区集群, 每个 topic 一张表
XX 预设的数据分组号,topic_id 为 topic 表中的 name
msg_id 自增 id 主键
msg_body 消息体 varchar(500)
版权声明: 本文为 InfoQ 作者【温安适】的原创文章。
原文链接:【http://xie.infoq.cn/article/3009838b2ec314c2a6054aa4f】。
本文遵守【CC BY-NC-ND】协议,转载请保留原文出处及本版权声明。
评论