架构训练营模块八作业
设计消息队列存储消息数据的 MySQL 表格。
【作业要求】
包括表名、字段、索引;
用文字描述设计思路和理由,例如:为什么设计某个索引?
一页 PPT 即可。
【提示】需要考虑每个消息队列一张表,还是所有消息放一张表,里面加一个“队列名称”的字段。
【每个消息队列一张表,主要原因如下】
所有消息放一张表时不同消费者需要用 where 条件筛选队列名称字段,而队列名称只会是几个固定取值,区分度很低,就算是加了索引查询效率也不高;
不同队列的消费者分别读不同的表,相比所有消费者都读一张表性能更好,MySQL 压力也更小;
所有消息放一张表的话,有处理得慢的消息就会阻塞其它快的队列;
如果有的队列消息量增长比较快,则可以针对该队列扩展多张表甚至多个库;如果都放一张表则所有其它队列也必须跟着扩展,有一定的资源浪费。
【设计方案一】
表名:队列名作为表名
字段设计如下表所示。生产者写入消息时利用数据库自动生成的自增 id 作为消息 id,消息状态 status 设置为 0;消费者读取消息时定位到 status 为 0 的最大 id 记录,修改状态 status 为 1 并读取该记录的消息内容进行消费。
消息 id 作为主键,status 字段上建索引,因为消费者需要根据 status 字段查找记录。
【设计方案二】
数据库中建两类表,消息表和元数据表。
消息表仍以各个队列名称作为表名,基本和方案一消息表的区别在于,去掉了 status 字段,只需要用主键 id 即可获取记录,速度更快。
元数据表只有一张,记录所有表最新被消费的 id;每个消费者根据队列名得到表名,再从元数据表中获取最新消费的 id,同时将该 id 加一(这样下一个消费者读的就是下一条消息),然后再拿该 id 去消息表中读取消息内容进行消费。
字段设计如后面的图所示,其中消息表
但是这种方案元数据表中的 latest_id 字段更新频繁,并且每个队列同时只能有一个消费者更新,因此这里可能会成为性能瓶颈(未来扩展可以考虑同一队列分多张表的形式,这样在元数据表中的记录会有多条,支持多个消费者同时更新)。
版权声明: 本文为 InfoQ 作者【Geek_e0c25c】的原创文章。
原文链接:【http://xie.infoq.cn/article/b12053ffb003ff514e6711d5d】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论