1. 概述
Apache Storm是一个经典的分布式流式计算编程框架,但编写程序比较麻烦。通常,一个基本的基于Storm的流式计算程序需要有以下几个部分:一个Spout、若干个Bolt、一个Topology。Spout和Bolt程序编写,以及Topology的编排不是太友好。今天,我要介绍的是,基于Storm的更高层次的抽象——Trident。它的API要比Storm更加简洁,而且支持迭代计算,不需要反复的创建Bolt来进行操作。
2. 主要内容2.1 Trident程序架构
简单解释下上图:
-
TridentSpout负责读取数据源,并将数据以batch为基本单位,发射到下游,一个batch包含若干个tuple
-
每一个Trident的Stream操作都是针对一个batch来进行操作的,同时一些Stream操作需要实现特定的接口来自定义计算方式,并且需要在Stream操作中定义输入和输出的Field字段名。Stream操作可以将一个batch转换为另外一个batch(其实内部是tuple转换成另外一个tuple)
-
groupBy操作,groupBy操作会将指定字段的相同的tuple放到一个组里,方便后边的聚合算子(aggregate)进行计算,这个操作对tuple的结构并不会有影响
2.2 Trident程序设计
编写基于Storm Trident的程序,可以参考以下几个步骤:
-
创建一个TridentTopologyTridentTopology是Trident自己封装的流式拓扑结构抽象,它可以以链式操作的方式组织流式计算的具体步骤,语法结构对比Storm要更加简单。按照链式操作,将整个流式计算的过程简洁地描述出来。
tridentTopology.newStream("textLineSpout", textLineSpout)
.each(new Fields("line"), new SplitFunc(), new Fields("word"))
.groupBy(new Fields("word"))
.aggregate(new Fields("word"), new SumFunc(), new Fields("duWord", "count"))
.each(new Fields("duWord", "count"), new PrintFunc(), new Fields("none"))
.parallelismHint(1);
-
创建一个用于发射数据的Spout
Trident对Spout有自己的封装,Spout的作用和Storm中一致,它是流式计算的源头,数据都是从Spout发射到其他计算任务的
-
基于Trident算子构建TridentTopology
前面那段代码中的each、groupBy、aggregate都是针对一个小批量Batch的操作,我们也看到了,这里出现了groupBy和aggregate等批处理计算中的函数,因为Trident可以以Batch的方式来操作流,这样可以在一定程度上提高计算效率
-
定义用于Trident算子的函数操作(例如:累加、求个数等)
当我们要使用each、aggregate这类操作时,Trident并不知道我们到底要如何进行遍历、分组或者聚合。所以,Trident提供了一系列的接口,这些接口的目的就是要让我们提供具体的实现
-
将TridentTopology转换为StormTopology
TridentTopology最终还是以StormTopology提交到Storm集群上运行,所以,Trident就是一套基于Storm的高层API,它让我们更加方便地编写Storm程序
-
提交执行
-
Trident Topology
基于Storm Trident的流式计算拓扑图
-
Trident Spout
Trident封装的Spout,就是流的源头,获取并发射数据的组件