RocketMQ 于2012年开源,并在2017年从社区毕业成为Apache的顶级项目。经过6年多的社区与市场检验,RocketMQ在互联网金融在线交易领域取得了非常好的结果。据不完全统计,单单在中国,RocketMQ覆盖了40%以上的消息领域场景。这两年Apache社区的全球化发展,这种发展态势已经蔓延到全亚洲,欧洲,包括整个美洲,RocketMQ也被应用到金融、电力、物流、游戏、电子商务、共享出行等十几个行业。
然而,随着云计算、大数据、人工智能等技术在全球范围的深入推进,催生出了如IoT、区块链、AI、边缘计算等新的应用场景,这对RocketMQ提出了更高的要求。近期,关于如何演进RocketMQ的架构能够更好的适应新的场景,推动RocketMQ成为云计算的核心基础设施,社区展开了激烈的讨论,并就关键的技术架构形成了共识。关于RocketMQ 5.0如何进行架构升级,如何服务好下一个十年,冯嘉在邮件列表中进行了系统的阐述,社区的贡献者把它翻译成中文分享给大家。
整体架构会采取存储计算分离与可插拔架构,关于存储计算分离,我知道在工业界这是一个饱受争议的话题,大家可能也看到了Twitter将自己的messaging解决方案EventBus这种存储计算分离的方式,切换回传统的一体式架构,它们给出的原因在于”introduces an additional hop”。没错,通常情况下,确实不需要这么多此一举。但这里我想表达的是,存储计算分离带来的价值就如同我们设计模式里面的单一职责一样,让专注更加专注。举个例子,假如你的引擎部署在IoT边缘云端,你需要你的计算节点按需部署,因为是计算密集型的任务,我们可以将关注点放到如何提升计算能力与响应速度上,而无需关心存储带来的机器成本,运维成本等。再比如,RocketMQ的默认存储我们都看做是时间序列存储的一种,它不但提供了单一数据的存储能力,还有批量存储的能力,但无论如何它是一种数据类型无关的顺序追加存储,在这种架构下,如果希望实现目前事务这种能力,还是有一些复杂的,尤其是当希望将RocketMQ打造成一站式的微服务事务解决方案时,这个我们已经做过一些尝试。据我和很多来自银行的朋友了解到,它们在金融体系中对存储是做了一些改造的,如将文件存储替换成关系型,NoSQL抑或是NewSQL存储,带来的收益就是可维护性增强,增强了事务的处理能力。从这个意义上讲,5.0的架构我希望它是可插拔设计,默认我们会提供极致的顺序追加能力的存储,这也最符合磁盘寻道算法的存储实现。但也带来了另外一个问题,如何提升对数据的查询,处理能力。这里我想分享的是另外一个初步的设计思路,我们继续沿用Commitlog这样的数据结构存储原始数据,然后基于 Commitlog 构建索引或者中间聚合结果,目前我们的索引结构没有达到很好的融合与利用。接下来一个重要方向,就是对索引的改造与优化。另外,我们可以利用 DPDK/SPDK 、写 Pos 原子递增的方式达到最佳的无锁设计,即只有当 HeaderLog 的内容全部分发到索引或者聚合中才认为是已经 committed 的数据,这一系列都需要很大程度上去探索,甚至包括和一些其它社区与高校的合作。所以在这个层面上,我认为我们要让RocketMQ具备分离的能力,同时存储能力又是可插拔,可按需替换的。
全面拥抱OpenMessaging标准,相信不少同学已经留意到包括阿里巴巴,Yahoo在内的多家公司起草的云原生时代下的消息标准,在这个标准的蓝图里,解决的一个很重要的问题是互操作性,这种互操作性不仅仅来自不同消息厂家之间,还包括消息上下游之间的互操作性。而这种互操作性反应到用户那里,便是API或者协议的一致性,虽然我们认为API也是协议的一种,但我这里分开是想强调,协议的一致性已经被无数场景在努力尝试,但到目前为止,我个人并没有看到一个特别通用且简单的方案,无论是AMQP,MQTT,包括最近被大家开始认识到的RSocket,要想在这一层工作,创新点不会太多,而我们希望避免一些重复的创新,这个时候API层的标准就显得格外重要,所以RocketMQ 5.0在API侧,会重点投入支持OpenMessaging的标准化。未来的多语言,我们希望通过这套API彻底解决大家目前使用RocketMQ多语言遇到的所有问题。
多协议的天然支持,这一点我觉得也特别重要,所以在5.0里面,我们重构remoting层,在计算节点提供可插拔的传输层协议支持,将会有可能提供HTTP1.1/2的支持。在此基础上,我们也要考虑集成基于TCP的MQTT,UDP的CoAP。当然,我们也清晰的看到随着5.0G网络的逐渐普及,我们可能要积极去跟进市场这块的需求,无论怎么说,保持协议的灵活插拔,一定要成为5.0重点考虑的。
流计算的天然支持,这是目前最为热议的一个话题。我本人也是流计算的早期探索者,但是前些年我们做的所谓流计算,严格意义上来说都是伪场景。为什么是伪场景呢,因为在我看来,一个轻量级的MQ加上简单的处理就是可以实现的。另外,在流计算场景里,消息与存储都是非常重要的一环,那我们为何不让消息天然支持任务节点的调度与计算呢,加上我们内置的存储,可以更好的帮助我们更好的解决状态计算这个痛点。我们只需要提供一个lib包,就可以轻松的让messaging具备流处理的能力。至于后续的SQL处理,CEP,FAAS等,我相信都是这种编程模式的进化。
据悉:经过社区多次的充分讨论,大家一致认定在RocketMQ新架构向前演进的过程中,最重要的就是要保证升级过程的平滑性以及做到向前向后兼容。因此,社区决定采用逐步迭代的方式进行演进,这也是大多数顶级开源项目所采用的向后兼容演进的最佳路径,大致思路可能是:计划通过多个版本迭代逐步演进到上述理想的架构,其中,首先将带来基于raft算法的多副本存储;之后将提供真正的推送方式;随之而来的版本将带来协议的可插拔以及MQTT协议的支持;紧接着就是计划将提供服务端的负载均衡方案,使得客户端更加的轻量级,还将带来基于OpenMessaging的客户端全新解决方案;最后将提供完整的存储计算分离解决方案,用以更好的支撑IOT,多协议,边缘云等新特性,但是我们在传统的消息领域仍将保持简洁的计算存储一体架构,提高资源利用率。
本文作者:冯嘉,社区昵称vongosling ,Apache RocketMQ 创始人,Linux OpenMessaging 创始人,Google编程夏令营导师,Apache孵化器导师,阿里巴巴 Messaging 开源技术负责人。
关注RocketMQ官微 掌握最新技术资讯
关注RocketMQ官微
加入RocketMQ官方钉钉群
更多关于Apache RocketMQ的文章:
· SpringBoot与RocketMQ客户端集成原理解读与示例
· 滴滴出行基于RocketMQ构建企业级消息队列服务的实践