RocketMQ事务消息实现分析(2)

一阶段的Half消息由于是写到一个特殊的Topic,所以二阶段构建索引时需要读取出Half消息,并将Topic和Queue替换成真正的目标的Topic和Queue,之后通过一次普通消息的写入操作来生成一条对用户可见的消息。

所以RocketMQ事务消息二阶段其实是利用了一阶段存储的消息的内容,在二阶段时恢复出一条完整的普通消息,然后走一遍消息写入流程。

如何处理二阶段失败的消息

如果二阶段失败了,比如在Commit操作时出现网络问题导致Commit失败,那么需要通过一定的策略使这条消息最终被Commit。

RocketMQ采用了一种补偿机制,称为“回查”。

Broker端对未确定状态的消息发起回查,将消息发送到对应的Producer端(同一个Group的Producer),由Producer根据消息来检查本地事务的状态,进而执行Commit或者Rollback。

RocketMQ事务消息实现分析

Broker端通过对比Half消息和Op消息进行事务消息的回查并且推进CheckPoint(记录那些事务消息的状态是确定的)。

值得注意的一点是具体实现中,在回查前,系统会执行putBackHalfMsgQueue操作,即将Half消息重新写一遍到Half消息的Queue中。这么做其实是为了能有效的推进上面的CheckPoint。

RocketMQ事务消息设计总结

RocketMQ事务消息实现分析

以上是RocketMQ事务消息实现的示意图:

通过写Half消息的方式来实现一阶段消息对用户不可见

通过Op消息来标记事务消息的状态

通过读取Half消息来生成一条新的Normal消息来完成二阶段Commit之后消息对Consumer可见

通过Op消息来执行回查

优势:

Half Queue和Op Queue的数量可控,不会随着Topic的增加而增加

没有外部依赖,实现自包含

缺陷:

每条事务消息至少需要写一条Half消息(异常情况可能会有多条)和Normal,写放大了

所有Half消息都是写到全局预设的一个内部的Topic,这块可能性能会有一些问题(所有Topic的事务消息会往一个Topic上写)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/953621f65ac3eac3a101355cebb82c58.html