首页 > 范文大全 > 正文

基于Twitter Storm的数据实时分析处理工具研究

开篇:润墨网以专业的文秘视角,为您筛选了一篇基于Twitter Storm的数据实时分析处理工具研究范文,如需获取更多写作素材,在线客服老师一对一协助。欢迎您的阅读与分享!

【摘要】过去的十年是数据处理变革的十年,MapReduce,Hadoop以及一些相关的技术使得我们能处理的数据量比以前要大得多得多。但是这些数据处理技术都不是实时的系统,它们设计的目的也不是为了实时计算。没有什么办法可以简单地把hadoop变成一个实时计算系统。然而大规模的实时数据处理已经越来越成为一种业务需求了,而缺少一个“实时版本的hadoop”已经成为数据处理整个生态系统的一个巨大缺失。twitter storm的出现弥补了hadoop在实时处理方面的不足,本文就twitter storm在实时数据计算方面的优点和架构实现进行研究

【关键词】twitter storm 实时计算 实时数据处理

一、Twitter Storm的优点

Storm出现之前,你可能需要自己手动维护一个由消息队列和消息处理者所组成的实时处理网络,消息处理者从消息队列取出一个消息进行处理,更新数据库,发送消息给其它队列,等等等等。不幸的是,这种方式有以下几个缺陷:

(1)单调乏味:你花费了绝大部分开发时间去配置把消息发送到哪里,部署消息处理者,部署中间消息节点 — 你的大部分时间花在设计,配置这个数据处理框架上,而你真正关心的消息处理逻辑在你的代码里面占的比例很少。

(2)脆弱:不够健壮,你要自己写代码保证所有的消息处理者和消息队列正常运行。

(3)伸缩性差:当一个消息处理者的消息量达到阀值,你需要对这些数据进行分流,你需要配置这些新的处理者以让他们处理分流的消息。

虽然对于一个大量消息处理系统来说,分解到最后就是消息队列和消息处理者的组合,而消息处理无疑是实时计算的基础。那么现在问题就是:怎样去做才能不丢失数据,可以很好的扩展到更大的消息量并且非常容易操作呢?

Storm定义了一批实时计算的原语。如同hadoop大大简化了并行批量数据处理,storm的这些原语大大简化了并行实时数据处理。storm的一些关键特性如下:

(1)适用场景广泛: storm可以用来处理消息和更新数据库(消息流处理), 对一个数据量进行持续的查询并返回客户端(持续计算), 对一个耗资源的查询作实时并行化的处理(分布式方法调用),storm的这些基础原语可以满足大量的场景。

(2)可伸缩性高:Storm的可伸缩性可以让storm每秒可以处理的消息量达到很高。为了扩展一个实时计算任务,你所需要做的就是加机器并且提高这个计算任务的并行度设置(parallelism setting)。作为Storm可伸缩性的一个例证, 一个Storm应用在一个10个节点的集群上每秒处理1000000个消息,包括每秒一百多次的数据库调用。Storm使用ZooKeeper来协调集群内的各种配置使得Storm的集群可以很容易的扩展很大。

(3)保证无数据丢失: 实时系统必须保证所有的数据被成功的处理。 那些会丢失数据的系统的适用场景非常窄, 而storm保证每一条消息都会被处理, 这一点和S4相比有巨大的反差。

(4)异常健壮:不像Hadoop—出了名的难管理,storm集群非常容易管理。容易管理是storm的设计目标之一。

(5)容错性好:如果在消息处理过程中出了一些异常,storm会重新安排这个出问题的处理逻辑。storm保证一个处理逻辑永远运行,除非你显式杀掉这个处理逻辑。

(6)语言无关性:健壮性和可伸缩性不应该局限于一个平台。Storm的topology和消息处理组件可以用任何语言来定义,这一点使得任何人都可以使用storm。

二、Twitter Storm的关键概念

(1)计算拓补(Topologies) :一个实时计算应用程序的逻辑在storm里面被封装到topology对象里面,我把它叫做计算拓补。Storm里面的topology相当于Hadoop里面的一个MapReduce Job,它们的关键区别是:一个MapReduce Job最终总是会结束的,然而一个storm的topoloy会一直运行,除非你显式的杀死它。 一个Topology是Spouts和Bolts组成的图状结构, 而链接Spouts和Bolts的则是Stream groupings。

(2)消息流(Streams):消息流是storm里面的最关键的抽象。一个消息流是一个没有边界的tuple序列, 而这些tuples会被以一种分布式的方式并行地创建和处理。对消息流的定义主要是对消息流里面的tuple的定义,我们会给tuple里的每个字段一个名字。并且不同tuple的对应字段的类型必须一样。也就是说: 两个tuple的第一个字段的类型必须一样,第二个字段的类型必须一样,但是第一个字段和第二个字段可以有不同的类型。在默认的情况下,tuple的字段类型可以是:integer,long,short,byte,string,double,float,boolean和byte array。你还可以自定义类型,只要你实现对应的序列化器。

每个消息流在定义的时候会被分配给一个id,因为单向消息流是那么的普遍,OutputFieldsDeclarer定义了一些方法让你可以定义一个stream而不用指定这个id。在这种情况下这个stream会有个默认的id:1。

(3)消息源(Spout):消息源Spouts是storm里面一个topology里面的消息生产者。一般来说消息源会从一个外部源读取数据并且向topology里面发出消息:tuple。消息源Spouts可以是可靠的也可以是不可靠的。一个可靠的消息源可以重新发射一个tuple如果这个tuple没有被storm成功的处理,但是一个不可靠的消息源Spouts一旦发出一个tuple就把它彻底忘了,也就不可能再发了。

消息源可以发射多条消息流stream。要达到这样的效果,使用OutFieldsDeclarer.declareStream来定义多个stream,然后使用poutOutputCollector来发射指定的sream。Spout类里面最重要的方法是nextTuple要么发射一个新的tuple到topology里面或者简单的返回如果已经没有新的tuple了。要注意的是nextTuple方法不能block Spout的实现, 因为storm在同一个线程上面调用所有消息源Spout的方法。

另外两个比较重要的Spout方法是ack和fail。storm在检测到一个tuple被整个topology成功处理的时候调用ack, 否则调用fail。storm只对可靠的spout调用ack和fail。

(4)消息处理者:Bolts所有的消息处理逻辑被封装在bolts里面。Bolts可以做很多事情:过滤,聚合,查询数据库等。Bolts也可以简单的做消息流的传递。复杂的消息流处理往往需要很多步骤,从而也就需要经过很多Bolts。比如算出一堆图片里面被转发最多的图片就至少需要两步:第一步算出每个图片的转发数量。第二步找出转发最多的前10个图片。(如果要把这个过程做得更具有扩展性那么可能需要更多的步骤)。

三、Twitter Storm的设计思想

在Storm中也有对于流stream的抽象,流是一个不间断的无界的连续tuple,注意Storm在建模事件流时,把流中的事件抽象为tuple即元组。

Storm认为每个stream都有一个stream源,也就是原始元组的源头,所以它将这个源头抽象为spout,spout可能是连接twitter api并不断发出tweets,也可能是从某个队列中不断读取队列元素并装配为tuple发射。

有了源头即spout也就是有了stream,那么该如何处理stream内的tuple呢,同样的思想twitter将流的中间状态转换抽象为 Bolt,bolt可以消费任意数量的输入流,只要将流方向导向该bolt,同时它也可以发送新的流给其他bolt使用,这样一来,只要打开特定的 spout(管口)再将spout中流出的tuple导向特定的bolt,又bolt对导入的流做处理后再导向其他bolt或者目的地。

我们可以认为spout就是一个一个的水龙头,并且每个水龙头里流出的水是不同的,我们想拿到哪种水就拧开哪个水龙头,然后使用管道将水龙头的水导向到一个水处理器(bolt),水处理器处理后再使用管道导向另一个处理器或者存入容器中。 为了增大水处理效率,我们很自然就想到在同个水源处接上多个水龙头并使用多个水处理器,这样就可以提高效率。

对应上文的介绍,我们可以很容易的理解,就像一张有向无环图,Storm将这个图抽象为Topology即拓扑。拓扑是storm中最高层次的一个抽象概念,它可以被提交到storm集群执行,一个拓扑就是一个流转换图,图中每个节点是一个spout或者 bolt,图中的边表示bolt订阅了哪些流,当spout或者bolt发送元组到流时,它就发送元组到每个订阅了该流的bolt(这就意味着不需要我们 手工拉管道,只要预先订阅,spout就会将流发到适当bolt上)。

为了做实时计算,我们需要设计一个拓扑图,并实现其中的Bolt处理细节,Storm中拓扑定义仅仅是一些Thrift结构体(请google一下Thrift),这样一来我们就可以使用其他语言来创建和提交拓扑。

四、Twitter Storm的架构实现

Storm集群表面类似Hadoop集群。但在Hadoop上你运行的是”MapReduce jobs”,在Storm上你运行的是”topologies”。”Jobs”和”topologies”是大不同的,一个关键不同是一个 MapReduce的Job最终会结束,而一个topology永远处理消息(或直到你kill它)。

Storm集群有两种节点:控制(master)节点和工作者(worker)节点。控制节点运行一个称之为”nimbus”的后台程序,它类似于Haddop的”JobTracker”。Nimbus负责在集群范围内分发代码、为worker分配任务和故障监测。每个工作者节点运行一个称之”Supervisor”的后台程序。Supervisor监听分配给它所在机器的工作,基于Nimbus分配给它的事 情来决定启动或停止工作者进程。每个工作者进程执行一个topology的子集(也就是一个子拓扑结构);一个运行中的topology由许多跨多个机器 的工作者进程组成。

一个Zookeeper集群负责Nimbus和多个Supervisor之间的所有协调工作(一个完整的拓扑可能被分为多个子拓扑并由多个supervisor完成)。

此外,Nimbus后台程序和Supervisor后台程序都是快速失败(fail-fast)和无状态的;所有状态维持在Zookeeper或本地磁 盘。这意味着你可以kill -9杀掉nimbus进程和supervisor进程,然后重启,它们将恢复状态并继续工作,就像什么也没发生。这种设计使storm极其稳定。这种设计 中Master并没有直接和worker通信,而是借助一个中介Zookeeper,这样一来可以分离master和worker的依赖,将状态信息存放 在zookeeper集群内以快速回复任何失败的一方。