Yelp开源了一个名叫MRJob的框架,是用来在AWS基础设施上运行大MapReduce Job的。不幸的是,随着使用MRJob的服务数量巨增,运行和调度任务开始变得越来越复杂。

实时核算和数据转化,为何Yelp弃用Storm和Heron,自建流处理器PaaStorm?  Yelp Storm Heron 第1张

美中不足

在2010年时,Yelp开源了一个名叫MRJob的结构,是用来在AWS基础设施上运转大MapReduce Job的。Yelp的工程师们用MRJob完结了许多功用,从广告推送到翻译,举目皆是。事实证明,MRJob是一个十分强壮的东西,能够在咱们其时丰厚的数据集合上完结核算和集合操作。

不幸的是,跟着运用MRJob的服务数量巨增,运转和调度使命开端变得越来越杂乱。由于许多使命都是要依托上游使命的,所以就要好好地组织整个体系的拓扑。MapReduce使命并不是用于实时处理的,所以使命的拓扑要每天调度一次。更糟的是,假如上游的使命失利了,下流的也会失利,终究会输出过错的成果。因而就要有十分专业的才能来判别应该从哪个使命开端、以什么次序从头运转,终究输出正确的成果。

爱考虑的人就会问了:咱们有没有什么办法来更高效地完结核算和转化使命呢?咱们还想支撑一个杂乱的数据流中不同数据转化操作之间的依托联系,特别是要能高雅地处理办法改动及上游的毛病。咱们还期望体系能实时或许近实时地运转。这样,体系就能够用于事务剖析及方针监控。换句话说,咱们需求的是一个流处理器。

Storm之类现成的核算体系原本也是十分不错的。但由于许多干流的流处理结构对Python的支撑都不太好,因而要把咱们的其他后台程序与Storm或许其他现有流处理体系结合起来就会十分苦楚。

咱们***用的是Pyleus,这是一个让开发者能够用Python处理和转化数据的开源结构。Pyleus的底层仍然是运用Storm的,构建耗时比较久,运转得也慢。Twitter Heron宣告开源后,咱们发现咱们也碰上了许多他们碰到过的问题。Yelp自己有功用十分强壮的用于布置服务的Platform-as-a-Service渠道PaasTA,相比之下咱们更喜爱运用PaaSTA,而不是运转专用的Storm集群。

从2015年7月开端,有一帮工程师们开端研制一种新式的数据仓库,也碰上了典型的扩展和功用问题。最开端时他们想用Pyleus来先清洗数据,再拷贝到Redshift上。后来他们意识到布置一整套Storm集群来运转些简略的Python逻辑实在太没必要了:用Yelp自己的运转服务的渠道去布置一套根据Python的流处理器就足够了。咱们的流处理器是根据Samza规划的,意图是供给一些简略的接口,用一种“处理音讯”的办法来做数据转化。

工程师们在Hackathon 17上构建了运转在PyPy上的流处理器的原型,这样PassStorm就诞生了。

这姓名中有什么意义?

PaaStorm的姓名其实是PaaSTA和Storm的组合。那PaaStorm到底是干什么的呢?要回答这个问题,咱们先看看数据管道的根本架构:

实时核算和数据转化,为何Yelp弃用Storm和Heron,自建流处理器PaaStorm?  Yelp Storm Heron 第2张

首要看看“Transformer”那一步,就会知道大多数存储在Kafka中的音讯都并不能直接被导入方针体系。想象有一套Redshift集群是用来存储广告推送数据的。广告推送集群想存储的仅仅上游体系的某一个字段(比方某个事务的均匀权重),不然它就要保存原始数据并对其进行聚合核算。假如Redhift广告推送集群要存储全部上游数据的话,就会糟蹋存储空间,导致体系功用下降。

在曩昔,各个服务都会写杂乱的MapReduce使命,在把数据写到方针数据存储之前先进行数据处理。但是,这些MapReduce使命都碰到了上文所述的功用和扩展问题。数据管道给咱们供给的优点之一是顾客程序能够拿到它所需求的数据的办法,不论上游数据原本是什么样。

削减示例代码

原本咱们是能够让每个顾客程序自己按自己需求的办法做数据转化的。比方,广告推送体系能够自己写一个转化服务,从Kafka中的事务数据中提取出查看计算量,并自己保护这个转化服务的。这种办法开端作业得很好,但终究体系上规模时咱们就碰上问题了。

咱们想供给一个转化结构是根据以下考虑:

  • 许多转化逻辑是通用的,能够在多个团队之间同享。比方把标志位转化成有意义的字段。
  • 这样的转化逻辑通常会需求许多示例代码。比方衔接数据源或数据意图、保存状况、监控吞吐量、毛病康复等。这样的代码原本并不需求在各种服务之间拷来拷去。
  • 要确保能对数据进行实时处理的话,数据转化操作要尽或许地快,要根据流。
  • 削减示例代码最天然的办法便是供给一个转化接口。咱们的服务完结接口中完结一次转化操作的详细逻辑,然后,剩余的作业就由咱们的流处理结构完结。

把Kafka作为音讯总线

开端PaaStorm是一个Kafka-to-Kafka的转化结构,慢慢地才演进成也支撑了其他类型的终端节点。把Kafka做为PaaStorm的终端节点简化了许多东西:每个对数据感兴趣的服务都能够注册到Topic上,重视恣意转化过的数据或许原始数据,有新音讯到来就处理就好了,彻底不必介意是谁创立了这个Topic。转化过的数据按Kafka的保存战略耐久化。由于Kafka是一个发布-订阅体系,下流体系也能够在任何它想的时分消费数据。

用Storm处理全部

当采用了PaaStorm之后,咱们该怎样把咱们的Kafka Topic之间的联系可视化呢?由于有些Topic中的数据会依照源到端的办法流向其他Topic,咱们能够把咱们的拓扑结构当成一个有向无环图:

实时核算和数据转化,为何Yelp弃用Storm和Heron,自建流处理器PaaStorm?  Yelp Storm Heron 第3张

每个节点都是一个Kafka Topic,箭头表明PaaStorm供给的转化操作。这时分“PaaStorm”这个姓名就变得更有意义了:象Storm相同,PaaStorm经过转化模块(象Bolt相同)供给对数据流的源(象Spout相同)的实时转化。

PaaStorm内部机制

PaaStorm的中心笼统叫做Spolt(Spout和Bolt的结合物)。象姓名表明的相同,Spolt接口也界说了两个重要的东西:一个输入数据源,一种对那个源的音讯数据进行的某种处理。

下面比方界说了一个最简略的Spolt:

实时核算和数据转化,为何Yelp弃用Storm和Heron,自建流处理器PaaStorm?  Yelp Storm Heron 第4张

这个Spolt会处理“refresh_primary.business.abc123efg456”这个Topic中的每一条音讯,添加一个字段,保存原始音讯中的‘name’字段的大写的值,然后再把这条处理过的新版别的音讯发送出去。

值得一提的是数据管道中的全部音讯都是不行修正的。要得到一条修正过的音讯,就要创立一个新的方针。并且,由于咱们在为音讯体中添加一个新字段(便是那个添加的“大写字母的name”字段),新音讯的办法现已改动了。在出产环境中,音讯的办法ID是历来都不能写死的。咱们要依托Schematizer服务来为一条修正过的音讯注册并供给适宜的办法。

***提一句,数据管道的客户端库供给了好几种十分类似的用姓名空间、Topic名、源名和办法ID的组合来生成“spolt_source”的办法。这样就能够很容易地让某个Spolt去找到它需求的全部源并从中读取数据。要了解更多信息,请参阅Schematizer的文章。

与Kafka相关的处理是怎样的?

或许你现已发现上面的Spolt中没有什么代码是与Kafka Topic相交互的。这是由于在PaaStorm中,全部真实的Kafka接口相关处理都是由一个内部实例(刚好也叫PaaStorm)完结的。PaaStorm实例会把一个特定的Spolt与对应的源和意图相关起来,并把音讯送给Spolt处理,再把Spolt输出的音讯发布到正确的Topic上去。

实时核算和数据转化,为何Yelp弃用Storm和Heron,自建流处理器PaaStorm?  Yelp Storm Heron 第5张

每个PaaStorm实例都用一个Spolt初始化。比方,下面的指令就用上文中界说的UppercaseNameSpolt敞开了一次处理:

  1. PaaStorm(UppercaseNameSpolt()).start()

这就意味着全部有意写一个新转化器的人都能够简略地界说一个新的Spolt子类,压根不必修正任何PaaStorm运转体相关的东西。

从内部来看,PaaStorm运转体的主办法也是惊人的简略,伪码如下:

实时核算和数据转化,为何Yelp弃用Storm和Heron,自建流处理器PaaStorm?  Yelp Storm Heron 第6张

这个运转体先做了一些设置:初始化了出产者和顾客,以及音讯计数器。然后,它一向等候上游Topic中的新数据。假如有新数据到来,就用Spolt处理它。Spolt处理之后会输出一条或多条音讯,出产者再把它发布到下流的Topic。

别的简略提一下,PaaStorm运转体也供给了比方顾客注册、心跳机制(名叫“tick”)等。比方某个Spolt要常常性地清空它的内容,那就能够用tick来触发。

关于状况保存

PaaStorm确保能够可靠地从毛病中康复。假如产生了溃散,咱们就该从正确的偏移方位开端从头消费。但不幸的是,这个正确的偏移量一般状况下都并不是咱们从上游的Topic中消费的***那一条音讯。原因是虽然咱们现已消费了它,但事实上咱们还没来得及把转化后的版别发布出去。

所以从头启动时正确的方位应该是上游Topic与现已成功发布到下流的***一条音讯对应的方位。在知道发到下流的***一条音讯的状况之后,咱们需求知道它对应的上游的音讯是哪一条,这样就能够从那里康复了。

为了便利完结这个功用,PaaStorm的Spolt在处理一条原始音讯时,会把与这条原始音讯相对应的在上游Topic中的Kafka偏移量也加到转化后的包里。转化后的音讯随后会在出产者的回调函数中把这个偏移量传回来。这样,咱们就能够知道与下流Topic中***一条音讯对应的上游Topic的偏移量了。由于回调函数只要在出产者成功地把转化后的音讯发布出去之后才会调用,也就意味着原始音讯现已被成功处理了,在这种状况下,顾客就能够很定心的在那个回调函数中提交这个偏移量了。假如产生溃散,咱们能够直接从还没有被彻底处理的上游音讯那里开端持续处理。

从上面的伪码中能够看到,PaaStorm也会计算消费掉的音讯数和发布的音讯数。这样,感兴趣的用户能够查看上游和下流Topic中的吞吐量。这让咱们很轻松地有了对恣意转化操作的监控和功用查看功用。在Yelp,咱们是把咱们的计算信息发给SignalFX的:

实时核算和数据转化,为何Yelp弃用Storm和Heron,自建流处理器PaaStorm?  Yelp Storm Heron 第7张

SignalFX图能够显现出在一个PaaStorm实例中出产者和顾客的吞吐量。在这个比方中,输入输出音讯量并不匹配。

在PaaStorm中对出产者和顾客分隔做计算的优点之一是咱们能够把这两个吞吐量放在一同,看看瓶颈是在哪里。假如到不了这个粒度,是很难发现管道中的功用问题的。

PaaStorm的未来

PaaStorm供给了两个东西:一个接口,并完结了一套结构来支撑这个接口。虽然咱们并不期望PaaStorm的接口很快就被改动,但现已有一些孵化项目在方案处理“转化并衔接”的问题了。在将来,咱们期望能把PaaStorm的内部换成Kafka Stream或许Apache Beam,首要的妨碍是对Python的支撑程度怎么,咱们特别垂青的是对终端节点的支撑。总归,在有开源的Python流处理项目老练之前,咱们会一向把PaaStorm用下去。

咱们系列的下一篇

咱们现已评论了PaaStorm是怎么从源到意图做数据的实时转化的。PaaStorm的开端规划是做一个Kafka-to-Kafka的体系,可事实上许多内部服务并不是要把数据输出到Kafka的,它们或许会把数据导入Redshift或MySQL之类的数据存储然后再做事务相关的东西。即便数据现已被转成了需求的格局,也还需求进一步:数据要被上传到方针数据存储中。

回忆一下上文的内容就会发现,PaaStorm的Spolt接口其实并没有限制有必要输出到Kafka中。事实上,只需求少数的改动,Spolt就能够直接把音讯发布到Kafka之外的体系中。在后续的文章里,咱们会谈谈Yelp的Salesforce Connector:一个用PaaStorm来很多、高效地把数据从Kafka导入Salesforce的服务。

转载请说明出处
知优网 » 实时核算和数据转化,为何Yelp弃用Storm和Heron,自建流处理器PaaStorm?

发表评论

您需要后才能发表评论