消息队列消息数据存储 MySQL 表设计
1. 介绍
根据自研消息队列的需求,本文使用 MySQL 数据库设计消息队列消息数据的存储。
消息队列支持多个队列主题,使用生产者/消费者设计模式。
消息生产者可创建队列主题,并把消息提交到自定义的队列主题。
消息消费者从主题队列中提取消息。
队列中的消息可以只被消费一次、也可以被多个消费者阅读。
2. 消息队列数据表设计
3. 关键设计
3.1 使用同一库表存储所有主题
所有队列主题放同一张逻辑数据表中(数据表按以上设计)。
这里对比两种可选的设计方案:
每个队列主题使用一张表
所有队列主题放在同一张表
设计方案一的最大问题是消息生产者可用自定义建队列主题,为每个队列主题建新表,太浪费系统资源。而且也不清楚队列主题里会放多少消息,当队列消息被读完后,是否要删表会成为很大问题。
设计方案二把所有消息放在同一张表,上面的问题就都解决了,队列主题的增加和减少变成表的“增删”操作,操作更快,也方便扩展。我们可以对队列主题建立索引,提高查询和读取消息的速度。
本设计选择设计方案二。
3.2 数据库表 Sharding
在具体实现上,我们可以对逻辑数据表进行 Sharding,建立多个有同样设计的表,并把队列消息放在多个表中(比如消息队列表 001、消息队列表 002、消息队列表 003、消息队列表 004、......)。
优点:
提高性能,每张表存储部分消息,提高消息读取查询速度。
方便数据集群化,当建立集群时,只需把部分表移动到其他服务器上。
方便数据备份,可以备份更新的数据,无需重新备份整个表。
方便丢弃旧消息,已经消费的旧消息根据需求可以被删除,把过期的表删除即可。
Sharding 算法:
随机,把消息存在当前使用中的数据表中。
哈希,对主题计算哈希值,并根据哈希值把消息存储在相应的数据表中。
方法二实现简单,只需把新消息追加当前的消息队列表末尾。但缺点是当要查找消息时,要读取多个 Sharding 表。此方案更适用于写操作远多于读操作的场景,或者是只有少量队列主题,但队列中消息比较多的场景。
方法二实现较复杂,读写时都需要对新消息的主题字段做哈希计算。缺点是读写都变慢,但优点是无需读取多个表。适合读操作远多于写操作的场景,或者是用户需要建立大量队列,而每个队列的消息又比较少的场景。
3.2 索引
对(队列主题、消息顺序号)建立索引,方便查找某一队列主题的所有消息。
版权声明: 本文为 InfoQ 作者【泋清】的原创文章。
原文链接:【http://xie.infoq.cn/article/9947e3c2460926b17da737258】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论