首页 > 编程知识 正文

开源物理计算平台,简述hadoop的开源计算框架

时间:2023-05-04 07:47:56 阅读:112580 作者:1208

随着场景信息技术日新月异的发展,信息呈现出爆炸性的膨胀,人们获取信息的方式也更加多样、更加便捷,同时对信息时效性的要求也越来越高。 举个搜索场景的例子,当一个卖家发布phdws信息时,他想要的当然是这个phdws很快被卖家搜索、点击、购买。 相反,如果这个phdws被搜索到第二天或更久,哥哥就会骂妈妈。 再举一个推荐的例子,如果用户昨天在淘宝上买袜子,今天想买游泳镜去游泳,但发现系统毫不吝惜地推荐袜子和鞋子,而他今天对找游泳镜的行为视而不见,这对兄弟在心里其实懂一点背景知识的循环农户们都知道。 这是因为后台系统每天做一次全量处理,大多是晚上做的很晚。 那样的话,今天中午做的事情当然会反映在明天。

实现一个实时计算系统海量数据处理多使用著名的hadoop和hive,作为批处理系统,hadoop以吞吐量大、自动容错等优点,广泛用于海量数据处理但是,hadoop不擅长实时计算。 因为天然是为了批处理而产生的。 这也是业界的共识。 否则,近两年,s4、storm、puma等实时计算系统不会像雨后春笋般冒出来。 首先,暂且不谈s4、storm、puma这些系统,让我们看看如果我们自己设计实时计算系统,会解决什么样的问题。

低延迟。 我说了实时计算系统,但是延迟一定要低。 高性能。 性能不高是浪费机器。 机器的浪费会被批评的哦。 分散。 系统都是为应用场景而产生的,如果你的应用场景、你的数据和计算只需要一个单元,就没有必要考虑这些复杂的问题。 我们说的是单机行不通的情况。 可扩展。 随着业务的发展,我们的数据量、计算量可能会越来越大,所以我们希望这个系统是可扩展的。 容错。 这是分布式系统中的共同问题。 一个节点锁定,不能影响我的APP应用。 是的,如果只解决这五个问题的话,可能有无数个方案。 另外,各有千秋。 列举一个方案,使用消息队列分散在各机器上的工作流程就可以了。 我们继续往下看。

在上面容易开发APP应用程序。 在您设计的系统中,APP应用程序开发人员是否需要考虑每个处理组件的分布和消息的传递? 如果是这样的话,那就有点麻烦了。 开发者可能用不好,也可能不想用。 消息不会丢失。 用户发布的phdws消息在无法实时处理时丢失了,对吧? 更严格地说,如果是正确的数据统计应用,它处理的信息也不少。 这个要求有点高哦。 新闻严谨有序。 虽然某些消息之间存在很强的相关性,如相同的phdws更新和删除操作消息,但处理时弄错顺序会产生完全不同的效果。 我不知道大家对这些问题是否有自己的答案,拿这些问题来看看storm的解决方案吧。

用一句话表达33558www.Sina.com/storm,可能如下: 分布式实时计算系统。 storm作者表示,storm对实时计算的意义类似于hadoop对批处理的意义。 我知道由谷歌地图实现的hadoop为我们提供了map,reduce原语,使我们的批处理程序非常简单优美。 同样,storm为实时计算提供了简单而美丽的原语。 我们在第三节详细介绍。

让我们看看storm的应用场景。

流数据处理。 Storm可用于处理源源不断的消息,并在处理后将结果写入存储。 分布式rpc。 storm的处理组件是分布式的,处理延迟很低,因此可以用作通用的分布式rpc框架。 当然,其实我们的搜索引擎本身也是分布式rpc系统。 说了半天,好像很含糊。 下面,具体说明一下storm的基本概念及其内部的实现原理。

Storm是什么首先,通过storm和hadoop的比较,了解storm的基本概念。

http://www.Sina.com/http://www.Sina.com /系统角色jobtrackernimbustasktrackersupervisorchildworker APP应用程序名称JobTopology组件

让我们具体看看这些概念。

Nimbus :负责资源分配和任务调度。 supervisor--负责接受nimbus分配的任务,启动和停止自己管理的工作器进程。 工作器- -执行具体处理组件逻辑的过程。 任务:工作器中每个spout/bolt的线程都称为任务。 从storm0.8开始,task不再支持物理线程,同一spout/bolt中的task可能共享一个称为执行程序的物理线程。 下图显示了这些角色之间的关系。

图3-1

拓扑:在storm中运行的实时APP应用程序。 因为组件之间的消息流形成逻辑拓扑。 spout :拓扑中源数据流的组件。 spout通常从外部数据源读取数据,并将其转换为拓扑内部的源数据。 Spout是活动角色,界面中有nextT

uple()函数,storm框架会不停地调用此函数,用户只要在其中生成源数据即可。 Bolt:在一个topology中接受数据然后执行处理的组件。Bolt可以执行过滤、函数操作、合并、写数据库等任何操作。Bolt是一个被动的角色,其接口中有个execute(Tuple input)函数,在接受到消息后会调用此函数,用户可以在其中执行自己想要的操作。 Tuple:一次消息传递的基本单元。本来应该是一个key-value的map,但是由于各个组件间传递的tuple的字段名称已经事先定义好,所以tuple中只要按序填入各个value就行了,所以就是一个value list. Stream:源源不断传递的tuple就组成了stream。

10. stream grouping:即消息的partition方法。Storm中提供若干种实用的grouping方式,包括shuffle, fields hash, all, global, none, direct和localOrShuffle等

相比于s4, puma等其他实时计算系统,storm最大的亮点在于其记录级容错和能够保证消息精确处理的事务功能。下面就重点来看一下这两个亮点的实现原理。

Storm记录级容错的基本原理

首先来看一下什么叫做记录级容错?storm允许用户在spout中发射一个新的源tuple时为其指定一个message id, 这个message id可以是任意的object对象。多个源tuple可以共用一个message id,表示这多个源 tuple对用户来说是同一个消息单元。storm中记录级容错的意思是说,storm会告知用户每一个消息单元是否在指定时间内被完全处理了。那什么叫做完全处理呢,就是该message id绑定的源tuple及由该源tuple后续生成的tuple经过了topology中每一个应该到达的bolt的处理。举个例子。在图4-1中,在spout由message 1绑定的tuple1和tuple2经过了bolt1和bolt2的处理生成两个新的tuple,并最终都流向了bolt3。当这个过程完成处理完时,称message 1被完全处理了。

图4-1

在storm的topology中有一个系统级组件,叫做acker。这个acker的任务就是追踪从spout中流出来的每一个message id绑定的若干tuple的处理路径,如果在用户设置的最大超时时间内这些tuple没有被完全处理,那么acker就会告知spout该消息处理失败了,相反则会告知spout该消息处理成功了。在刚才的描述中,我们提到了”记录tuple的处理路径”,如果曾经尝试过这么做的同学可以仔细地思考一下这件事的复杂程度。但是storm中却是使用了一种非常巧妙的方法做到了。在说明这个方法之前,我们来复习一个数学定理。

A xor A = 0.

A xor B…xor B xor A = 0,其中每一个操作数出现且仅出现两次。

storm中使用的巧妙方法就是基于这个定理。具体过程是这样的:在spout中系统会为用户指定的message id生成一个对应的64位整数,作为一个root id。root id会传递给acker及后续的bolt作为该消息单元的唯一标识。同时无论是spout还是bolt每次新生成一个tuple的时候,都会赋予该tuple一个64位的整数的id。Spout发射完某个message id对应的源tuple之后,会告知acker自己发射的root id及生成的那些源tuple的id。而bolt呢,每次接受到一个输入tuple处理完之后,也会告知acker自己处理的输入tuple的id及新生成的那些tuple的id。Acker只需要对这些id做一个简单的异或运算,就能判断出该root id对应的消息单元是否处理完成了。下面通过一个图示来说明这个过程。

图4-1 spout中绑定message 1生成了两个源tuple,id分别是0010和1011.

图4-2 bolt1处理tuple 0010时生成了一个新的tuple,id为0110.

图4-3 bolt2处理tuple 1011时生成了一个新的tuple,id为0111.

图4-4 bolt3中接收到tuple 0110和tuple 0111,没有生成新的tuple.

可能有些细心的同学会发现,容错过程存在一个可能出错的地方,那就是,如果生成的tuple id并不是完全各异的,acker可能会在消息单元完全处理完成之前就错误的计算为0。这个错误在理论上的确是存在的,但是在实际中其概率是极低极低的,完全可以忽略。

Storm的事务拓扑

事务拓扑(transactional topology)是storm0.7引入的特性,在最近发布的0.8版本中已经被封装为Trident,提供了更加便利和直观的接口。因为篇幅所限,在此对事务拓扑做一个简单的介绍。

事务拓扑的目的是为了满足对消息处理有着极其严格要求的场景,例如实时计算某个用户的成交笔数,要求结果完全精确,不能多也不能少。Storm的事务拓扑是完全基于它底层的spout/bolt/acker原语实现的,通过一层巧妙的封装得出一个优雅的实现。个人觉得这也是storm最大的魅力之一。

事务拓扑简单来说就是将消息分为一个个的批(batch),同一批内的消息以及批与批之间的消息可以并行处理,另一方面,用户可以设置某些bolt为committer,storm可以保证committer的finishBatch()操作是按严格不降序的顺序执行的。用户可以利用这个特性通过简单的编程技巧实现消息处理的精确。

Storm在淘宝

由于storm的内核是clojure编写的(不过大部分的拓展工作都是java编写的),为我们理解它的实现带来了一定的困难,好在大部分情况下storm都比较稳定,当然我们也在尽力熟悉clojure的世界。我们在使用storm时通常都是选择java语言开发应用程序。

在淘宝,storm被广泛用来进行实时日志处理,出现在实时统计、实时风控、实时推荐等场景中。一般来说,我们从类kafka的metaQ或者基于hbase的timetunnel中读取实时日志消息,经过一系列处理,最终将处理结果写入到一个分布式存储中,提供给应用程序访问。我们每天的实时消息量从几百万到几十亿不等,数据总量达到TB级。对于我们来说,storm往往会配合分布式存储服务一起使用。在我们正在进行的个性化搜索实时分析项目中,就使用了timetunnel + hbase + storm + ups的架构,每天处理几十亿的用户日志信息,从用户行为发生到完成分析延迟在秒级。

Storm的未来

Storm0.7系列的版本已经在各大公司得到了广泛使用,最近发布的0.8版本中引入了State,使得其从一个纯计算框架演变成了一个包含存储和计算的实时计算新利器,还有刚才提到的Trident,提供更加友好的接口,同时可定制scheduler的特性也为其针对不同的应用场景做优化提供了更便利的手段,也有人已经在基于storm的实时ql(query language)上迈出了脚本。在服务化方面,storm一直在朝着融入mesos框架的方向努力。同时,storm也在实现细节上不断地优化,使用很多优秀的开源产品,包括kryo, Disruptor, curator等等。可以想象,当storm发展到1.0版本时,一定是一款无比杰出的产品,让我们拭目以待,当然,最好还是参与到其中去吧,同学们。

参考文献

[1]storm官方wiki及code. https://github.com/nathanmarz/storm

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。