关于阿里云:Apache-RocketMQ-50-在Stream场景的存储增强

本文作者:刘振东,Apache RocketMQ PMC Member

RocketMQ根底介绍

RocketMQ的诞生是为了解决微服务解耦的问题。微服务解耦指将传统的微小服务拆分为分布式的微服务。

拆分之后,产生了一个新的问题:服务之间须要进行通信能力对外造成残缺的服务。通信形式分为两种:其一为RPC形式,也称为同步通信;其二为异步通信形式,比方RocketMQ。

RocketMQ的宽泛应用证实异步通信形式存在极大劣势。最显著的特点即异步解耦,所谓解耦指一个服务不须要晓得另外一个服务的存在。比方开发A服务,即便其余服务须要A服务的数据,A服务也并不需要晓得它们的存在,不须要依赖其余服务的公布,其余服务的新增也不会对A服务造成影响,从而实现了团队的解耦,指一个微服务由一个特定的团队去实现,而其余团队并不需要晓得该团队的存在,只须要依据当时约定的数据格式,通过RocketMQ实现异步通信。这种组织形式大大促成了生产力的倒退,天然也促使RocketMQ失去广泛应用。

在异步解耦过程中,有的组件生产音讯,有的组件生产音讯。RocketMQ的API model是其异步解耦过程的抽象概念。API model 的两端是RocketMQ畛域最典型的两个概念:其一为producer,指音讯的生产方或者数据生产方;其二为consumer,指音讯的生产方。

除此之外,topic也是API model的一个重要概念。因为异步解耦的须要,一条数据从producer收回到最终被consumer生产的过程并不是间接连贯,两头有一个形象层,这个抽象概念称为topic,相当于一个逻辑地址。topic就像一个仓库,当一条数据被发送到一个topic时,它会负责将音讯暂存,其余组件须要应用时能够拿取。

RocketMQ是一个分布式的消息中间件,因而topic本质上是一个逻辑概念,真正的物理概念是散布在每一个broker上的队列,即message queue。一个topic能够具备很多message queue,能够散布在很多broker上,从而具备了有限扩大的能力,这是topic的一个根本个性。

此外,topic接管音讯还有一个十分重要的个性,即音讯不可变。音讯的不可变个性使其能够被反复地读取。通过引入consumer group 的概念,能够看到不同组的消费者读取音讯的行为相互之间不会造成影响。Topic里的数据不会因为有consumer去读取而隐没,可实现一处发送多处生产的能力。比方在一个组织内,订单团队发了一条音讯到订单topic,该组织内的其余所有团队都能够间接进行读取,且一个团队的读取并不会影响其余团队的读取,实现了读取的互相独立。

MQ的一个重要个性是异步解耦,在互联网的超大流量场景下,异步解耦之后往往会跟随着削峰填谷问题。为了实现削峰填谷,须要长久化的能力。MQ是一个存储引擎,它能够暂存发送者的数据。如果消费者临时无奈解决,数据能够先沉积在MQ ,等到有足够的能力生产时再读取数据。

长久化也更好地反对了异步解耦的个性,即便consumer 全副不在线也并不影响producer的发送。长久化是MQ的一项重要能力。在长久化能力里,为了配合程序的个性,MQ的引擎是一个顺序存储的引擎。

RocketMQ设计时稍微有所不同,它将所有音讯集中式地存储,再依据不同的topic、不同的队列别离建设索引。这种设计是RocketMQ针对微服务场景特地优化的,它具备可能很好地反对同步刷盘的能力,在海量Topic的场景下写入提早仍然可能放弃安稳,这也是RocketMQ可与其余音讯引擎竞争的重要个性。

流场景最后利用于用户行为剖析。用户行为剖析指依据用户的行为日志去猜想用户的爱好。比方举荐零碎的搜寻举荐广告等业务就是流场景最典型的场景。

流场景的第一步为将各个系统里产生的用户行为,包含日志、数据库记录等,集中导入到某些剖析引擎。过程中数据起源多,数据的剖析引擎也很多,包含离线引擎、实时引擎等。

为了升高复杂度,咱们引入了相似MQ的工具,使得数据源和数据使用者不间接交互,而是先将数据发送到MQ里,整个零碎的连贯复杂度会从O(N2)变为O(N),复杂度大大降低。

从用户行为或者流解决的角度剖析MQ表演的角色以及它最终所冀望的IT架构,能够发现其与微服务解耦的架构十分类似,两者之间的所有概念比方consumer、producer、topic、message queue、分片等,都能够一一对应。因而,如果只思考RocketMQ的性能,它自身就能反对流解决场景。

目前有很多公司在应用RocketMQ进行流解决,但RocketMQ在解决流解决问题时依然存在可优化的空间。

Stream场景特征分析

流解决的场景具备三个特点:

(1)单条音讯size很小:微服务解耦中,一条音讯个别就是一条订单,蕴含的数据十分多,买家、卖家等各种信息糅杂在一起发给上游,一条音讯通常会达到至多1KB甚至几KB。但在流场景里,数据相似于用户的行为日志,比方某个用户登录、某个用户下线、某个用户浏览某个页面等形容。用户行为的表白很可能只占几个字节到100个字节。

(2)音讯数量很多:用户的浏览行为数量远远大于操作行为数量,整体音讯数量急剧增多。通常在微服务解耦场景中,单机不会超过10万TPS。然而在流场景或者日志收集等场景当中,单机百万TPS很常见。

(3)Catch Up读常态化:在流场景中,常常有工作的replay,即读取历史数据再计算历史后果,也称为cache up read。绝对于微服务解耦场景,catch up read在流场景中会更常见。

总而言之,在整个流场景里,吞吐变得更加重要。

存储加强三步曲——批、分、合

RocketMQ起初为微服务解耦设计时,是面向单条记录,因而吞吐并不高。RocketMQ 5.0针对吞吐引入了一个新个性batch。

在传统RocketMQ里,一条音讯一条记录,一条音讯一条索引。这种传统设计的长处是可能保障提早更加稳固,但也意味着吞吐不高。因为通信链路层的RPC次数太多,对CPU的耗费太大。因而,RocketMQ 5.0针对该问题,推出了batch性能。

Batch的根本逻辑是:在客户端主动组装,将多条音讯依照topic和队列合并,作为一个申请发送到服务端;服务端收到音讯个别不解压,而是间接存储;生产端一次拿下一批,将多个byte的音讯拿到本地,再进行解压。如果每个 batch蕴含10条音讯,TPS能够很轻松地回升10倍。本来一条音讯要发一次近程申请,而退出batch后10条音讯发一次近程申请即可。

因为服务端不进行解压,所以对服务端的CPU减少十分小,将解压和合并的性能下放到各个客户端,从而使服务端资源不容易造成瓶颈,TPS能够很轻松地失去进步。

流场景中另一个典型问题是扩容和数据重平衡。在微服务场景中,流量不大的状况下,扩容问题并不显著。然而在流场景中,单机流量原本就高,一旦扩容,扩容和数据重平衡问题就难以疏忽。在扩容过程中,如果原先是一个node,须要扩容变成两个node,则会产生重平衡的问题。

为了解决该问题,通常有两个方法:

(1)间接减少队列的数量,即“Add a Shard”。这种办法会产生一个问题,队列的数量发生变化导致整个数据的散布也发生变化。比方做word count单词个数计算,本来A单词位于队列0,队列数发生变化之后,A单词位于队列2,计算的后果会呈现问题。因而如果减少队列个数,流计算工作须要从新运行一遍来修改数据。另一问题为分片数,如果每动一次就减少分片数,则会导致分片数量收缩而且很难缩小,这也会产生问题。

(2)不减少队列,然而复制队列。比方本来队列1在node 0上,减少一个node 1,将队列1从node 0转移到 node 1,过程中队列数量没有发生变化,数据分布也没发生变化,因而客户端、发送端、生产端等流接管工作都不须要重跑。此办法对用户很敌对,但也会带来一个新的问题:复制过程会导致额定带宽耗费。在流场景中须要扩容的实质起因是机器的流量过高,然而为了将流量引走还须要新增一个复制工作,在还未实现引流之前就给零碎带来额定的性能耗费,可能会导致扩容的过程间接产生网络风暴,零碎解体。另外,复制分区时,因为流计算工作的每个分片数据量很大,复制过程耗时会很长。

因而采纳复制形式来解决大数据存储引擎的扩容其实很艰难,可用性与可靠性难以衡量。

RocketMQ针对该问题提出了logic queue解决方案。logic queue是裸露给客户的队列,一个物理queue散布在一个node上,用于理论存储数据的队列。一个logic queue由多个物理queue通过位点映射组合而成。

位点映射的原理如下:假如LogicQueue-1由Queue-1和Queue-2组成,Queue-1蕴含0到100,Queue-2蕴含101到200,可映射成一个总位点是0到 200的LogicQueue-1。

上述情况下,只需批改映射关系,将逻辑队列批改到新node上的队列里,即可实现扩容。

写入时,新进的数据写入新节点,即实现了写入端的负载平衡。而读取过程有所不同,最新的数据会从本机读取,老数据会采纳近程读取。

在流计算的整个生命周期中,数据在一直产生、一直地生产。因而在大多数状况下,如果没有产生沉积,近程读取的数量很小,简直可能霎时实现,写入和读取都在新节点上,以此实现扩容。这种扩容有两个显著劣势:其一是不须要搬运数据;其二是分片数量不必发生变化。这也意味着上下游的客户端都无需重启,也不必发生变化,数据工作都是残缺而正确的。

严格意义上来看,RocketMQ是一个流存储引擎。但RocketMQ 5.0推出了RocketMQ Streams——一个轻量级的流计算。

在RocketMQ Streams中,source 端是数据源头,两头有算子,最初数据会进入Sink端。通常它们都是有状态的,比方计算word count,每一条数据进来,一个新的单词呈现,首先要拿取过来数据的count值,加1后生成新的count值,这个两头的数据为状态村塾,个别称为state store。

State store的特色包含:

(1)本地化locality:一个轻量级的流计算如果要遵循高效的计算性能,通常须要本地化。本地化指将state store的数据和计算节点放在一起,至多要缓存到计算节点里。从state store外面取数据,就相当于从本地取数据,晋升性能。如果每次读取state store都是近程读取,可想而知性能会显著降落。

(2)长久化persistency:一旦劫难产生后,其余计算节点要能残缺地读到state store。例如本来在A计算节点计算数据,A计算节点出问题后要到B计算节点计算,在B计算节点也须要复原出state store。

(3)可搬运exchangeable:state store须要能便当地从一个零碎搬到另外一个零碎。比方算完word count,一个BI零碎或者一个网站零碎想尝试感知到该变动,则须要将数据从state store搬运到零碎里。

针对以上三个个性,RocketMQ推出了一种新的topic,称为compacted topic。compacted topic的存储形式和应用形式和与失常topic 一样,惟一区别在于其服务端会将key雷同的record删掉,进行规整。

比方图中本来offset=3的节点是K1V4,会笼罩之前的offset=0的K1V1和offset=2的K1V3,使最初只剩下一个K1V4。此设计的长处在于从新复原时须要读取的数据量非常少。

State store是一个NoSQL型的table,比方word count就是一个KV 构造,key是单词,count是单词呈现的个数,然而word count 在一直变动,须要将表转变成一个流,表产生的所有变动造成的数、记录的列表就造成了一个流,该过程称为流转,行将一个表转成一个流。RocketMQ能够通过以上形式轻松地将一张动静表存下来。

Compacted topic相当于一张动静表,且为流的模式,因而compacted topic是一种流表二象性的状态。这种非凡的topic能够充当state store的存储层——一个长久化层。

State store自身是表,且key和value一直变动。为了实现容灾的个性,须要将该表长久化,将该表的所有批改记录造成一个流,存到RocketMQ的一个compacted topic,state store即相当于被长久化。如果一个计算节点A解体,B计算节点接管工作时,能够将topic以一般API的形式读出,再在本地复原state store,以此实现流计算工作的disaster recovery,即实现了容灾个性,能够帮忙RocketMQ构建一个轻量级、没有任何内部依赖的流计算引擎。

Batch、logic queue、compacted topic三个存储的根本个性,别离用于解决加强吞吐的问题、弹性的问题以及state store的问题。将三个存储个性进行联合,再配合RocketMQ Streams,能够造成一个轻量级的流计算解决方案。只须要RocketMQ和RocketMQ Streams,即可实现一个通用的流计算存储引擎。

RocketMQ 5.0从原先的微服务解耦转变为流存储引擎,原先的异步解耦、削峰填补等个性仍然能够在新场景中充沛得以应用。

此外,RocketMQ 5.0针对流存储的场景实现了三个重大个性的加强:其一是batch,可晋升性能,将吞吐能力晋升10倍;其二是logic queue,能够实现秒级扩容,并且无需搬运数据,也无需扭转分片数量;其三是针对流计算场景中所用state store实现了compacted topic。

通过加强,RocketMQ向流存储引擎倒退的过程更进了一步。

退出 Apache RocketMQ 社区

十年铸剑,Apache RocketMQ 的成长离不开寰球靠近 500 位开发者的积极参与奉献,置信在下个版本你就是 Apache RocketMQ 的贡献者,在社区不仅能够结识社区大牛,晋升技术水平,也能够晋升集体影响力,促成本身成长。

社区 5.0 版本正在进行着热火朝天的开发,另外还有靠近 30 个 SIG(兴趣小组)等你退出,欢送立志打造世界级分布式系统的同学退出社区,增加社区开发者微信:rocketmq666 即可进群,参加奉献,打造下一代音讯、事件、流交融解决平台。

微信扫码增加小火箭进群

另外还能够退出钉钉群与 RocketMQ 爱好者一起宽泛探讨:

钉钉扫码加群

关注「Apache RocketMQ」公众号,获取更多技术干货

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理