Trident是基于Storm进行实时留处理的高级抽象,提供了对实时流4的聚集,投影,过滤等操作,从而大大减少了开发Storm程序的工作量。Trident还提供了针对数据库或则其他持久化存储的有状态的,增量的更新操作的原语。

  若我们要开发一个对文本中的词频进行统计的程序,使用Storm框架的话我们需要开发三个Storm组件:

    1.一个Spout负责收集文本信息并分段,做为sentence字段发送给下游的Bolt

    2.一个Bolt将将每段文本粉刺,将分词结果以word字段发送给下游的Bolt

    3.一个Bolt对词频进行统计,把统计结果记录在count字段并存储

  如果使用Trident我们可以使用一下代码完成上述操作:

 FixedBatchSpout spout = new FixedBatchSpout(new Fields("setence"),,
new Values("the cow jump over the moon"),
new Values("the man went to the store and bought some candy"),
new Values("four score and seven years ago"),
new Values("how many apples can you eat"));
spout.setCycle(true);
TridentTopology topology = new TridentTopology();
TridentState workcount = topology.newStream("spout",spout)
.each(new Fields("setence"),new Split(),new Fields("word"))
.groupBy(new Fields("word"))
.persistentAggregate(new MemoryMapState.Factory(),new Count(),new Fields("count"))
.parallelismHint();

  上述这段代码会被Trident框架转为为使用Storm开发时的三个步骤

  代码的前两行使用FixedBatchSpout不断循环生成参数里列出的四个句子,第7行声明了TridentTopology对象,并在第8行的newStream方法中引用了FixedBatchSpout。Trident是按批处理数据的,FixedBatchSpout生成的数据是按照下图的方式一批一批的发送到下一个处理单元的,后续处理单元也是按照这种方式把数据发送到其他节点。

  

  在上述的第9行使用Split对文本分词,并发分词结果存储到Word字段中Split的定义如下:

 public class Split extends BaseFunction {

     @Override
public void execute(TridentTuple tuple, TridentCollector collector) {
for(String word: tuple.getString().split(" ")) {
if(word.length() > ) {
collector.emit(new Values(word));
}
}
} }

  在each方法宏也可以实现过滤,如只统计单词长度超过10个字母长度的单词的过滤可以定义如下:

.each(new Fields("word"), new BaseFilter() {
public boolean isKeep(TridentTuple tuple) {
return tuple.getString().length() > ;
}
})

  代码gropuBy(new Fields("word"))对word进行聚集操作,并在其后使用Count对象进行计数。之后将得到的结果储存到内存中。Trident不仅支持将结果存储到内存中,也支持将结果存储到其他的介质,如数据库,Memcached。如要将最终结果以key-value的方式存储到Memcached,可以使用下面的方式:

persistentAggregate(new Memcached.transactional(local),new Count(),new Fields("count"))

  实时任务的关键问题是如何处理对数据更新的幂等问题,任务可能失败或则重启,因此更新操作可能被重复执行。以上述为例,发送到Count的数据可能因为节点的重启或则网络故障导致的其他原因致使被重复发送,从而引起数据的重复统计,为了避免这个问题Trident提供了事物支持,由于数据是按批发送到Count节点的,Trident对每批单词都分配一个Transaction id。上面的代码中,每完成一批单词的统计,就将这批数据的统计结果连同Transaction id一起存储到Memcached中。数据更新的时候,Trident会比较Memcached中的Transaction id和新到达数据的Transaction id,如果同一批数据被重复发送,其Transaction id就会等于Memcached存储的Transaction id,新数据将会被忽略。另外每批数据的Transaction id是有严格的顺序的Transaction id 为2的数据没有处理完的情况下,绝对不会处理Transaction id为3的数据。

  有时,一个任务有多个数据源,每一个数据源都是以TridentState的形式出现在任务定义中的,比如上面提到的wordcount任务生成的数据就可以被其他的任务所使用,可以使用stateQuery方法引用别的TridentState,stateQuery的定义如下:

Stream stateQuery(TridentState state, QueryFunction function, Fields functionFields)

  Trident的数据模型称作"TridentTuple"---带名字的Values列表。在Topology中,tuple是在顺序的操作集合中增量生成的。Operation通常包含一组输入字段和提交的功能字段。Operation的输入字段通常是将tuple中的一个子集作为操作集合的输入,而功能字段则是命名提交的字段。

  例如,声明一个名为"students"的Stream,可能包含名字,性别,学号,分数等字段。添加一个按分数过滤的过滤器ScoreFilter,使得tuples只过滤分数大于60的学生,定义一个分数过滤器,当选择输入字段的时候Trident会自动过滤出一个子集,该操作十分的高效。

class ScoreFilter extends BaseFilter{

        public boolean isKeep(TridentTuple tuple) {
return tuple.getInteger() >= ;
}
}

  如果我们相对字段进行计算,并且提交给TridentTuple,可以模拟一下计算。

class AddAndSubFuction extends BaseFunction{

        public void execute(TridentTuple tuple, TridentCollector collector) {
int res1 = tuple.getInteger();
int res2 = tuple.getInteger();
int sub = res1 > res2 ? res1 - res2 : res2 - res1;
collector.emit(new Values(res1+res2,sub));
}
}

  此函数接收两个整数作为参数,并计算两个数的和以及差,作为两个新的Fields提交。

Storm Trident详解的更多相关文章

  1. Storm配置项详解【转】

    Storm配置项详解 ——阿里数据平台技术博客:storm配置项详解 什么是Storm? Storm是twitter开源的一套实时数据处理框架,基于该框架你可以通过简单的编程来实现对数据流的实时处理变 ...

  2. Storm命令详解

    在Linux终端直接输入storm,不带任何参数信息,或者输入storm help,可以查看storm命令行客户端(Command line client)提供的帮助信息.Storm 0.9.0.1版 ...

  3. 【转】Storm并行度详解

    1.Storm并行度相关的概念 Storm集群有很多节点,按照类型分为nimbus(主节点).supervisor(从节点),在conf/storm.yaml中配置了一个supervisor,有多个槽 ...

  4. storm配置详解

    storm的配置文件在${STORM_HOME}/conf/storm.yaml.下面详细说明storm的配置信息. java.libary.path:storm本身依赖包的路径,有多个路径的时候使用 ...

  5. Storm之详解spout、blot

    1.Topology的构造backtype.storm.topology.TopologyBuilder 2.Spout组件的编写实现接口 backtype.storm.topology.IRichS ...

  6. Storm并行度详解

    一.Storm并行度相关的概念 Storm集群有很多节点,按照类型分为nimbus(主节点).supervisor(从节点),在conf/storm.yaml中配置了一个supervisor,有多个槽 ...

  7. Storm 学习之路(二)—— Storm核心概念详解

    一.Storm核心概念 1.1 Topologies(拓扑) 一个完整的Storm流处理程序被称为Storm topology(拓扑).它是一个是由Spouts 和Bolts通过Stream连接起来的 ...

  8. Storm 系列(二)—— Storm 核心概念详解

    一.Storm核心概念 1.1 Topologies(拓扑) 一个完整的 Storm 流处理程序被称为 Storm topology(拓扑).它是一个是由 Spouts 和 Bolts 通过 Stre ...

  9. Storm流计算从入门到精通之技术篇(高并发策略、批处理事务、Trident精解、运维监控、企业场景)

    1.Storm全面.系统.深入讲解,采用最新的稳定版本Storm 0.9.0.1 :   2.注重实践,对较抽象难懂的技术点如Grouping策略.并发度及线程安全.批处理事务.DRPC.Storm ...

随机推荐

  1. Ubuntu部分快捷键的使用简介

    1.切换到字符界面 Ctrl+Alt+F1 切换到tty1字符界面 Ctrl+Alt+F2 切换到tty2字符界面 Ctrl+Alt+F3 切换到tty3字符界面 Ctrl+Alt+F4 切换到tty ...

  2. gdb 调试带参数程序

    在gdb中,运行程序使用r或是run命令. 程序的运行,你有可能需要设置下面四方面的事. 1.程序运行参数. set args 可指定运行时参数.(如:set args 10 20 30 40 50) ...

  3. 安卓编译 translate error Lint: How to ignore “<key> is not translated in <language>” errors?

    Add following at the header of your strings.xml file <resources xmlns:tools="http://schemas. ...

  4. Microsoft DirectX SDK 2010 版本下载

    Microsoft DirectX SDK 2010 版本下载 Version:Date Published:9.29.19626/7/2010File name:File size:DXSDK_Ju ...

  5. 安装指定版本的docker

    安装 Docker 从 2017 年 3 月开始 docker 在原来的基础上分为两个分支版本: Docker CE 和 Docker EE. Docker CE 即社区免费版,Docker EE 即 ...

  6. 客户被绑,蒙眼,惊问:“想干什么?” 对方不语,鞭笞之,客户求饶:“别打,要钱?” 又一鞭,“十万够不?” 又一鞭,“一百万?” 又一鞭。客户崩溃:“你们TMD到底要啥?” “要什么?...

    1.  客户被绑,蒙眼,惊问:“想干什么?”     对方不语,鞭笞之,客户求饶:“别打,要钱?”     又一鞭,“十万够不?”     又一鞭,“一百万?”     又一鞭.客户崩溃:“你们TMD ...

  7. 2018.10.18 bzoj1185: [HNOI2007]最小矩形覆盖(旋转卡壳)

    传送门 不难看出最后的矩形一定有一条边与凸包某条边重合. 因此先求出凸包,然后旋转卡壳求出当前最小矩形面积更新答案. 代码: #include<bits/stdc++.h> #define ...

  8. 2018.09.01 poj3071Football(概率dp+二进制找规律)

    传送门 概率dp简单题. 设f[i][j]表示前i轮j获胜的概率. 如果j,k能够刚好在第i轮相遇,找规律可以发现j,k满足: (j−1)>>(i−1)" role=" ...

  9. 动词的时态(Les temps du verbe )

    在开始讲解直陈式现在时的主要用法之前,我们有必要先搞清楚两个基本概念:▶语式(mode):语式是动词表达动作的方式.一个动作,可以作为实在的事表达出来,也可以作为希望或单纯设想的事表达出来,法语动词共 ...

  10. Series转成list

    直接list(series)就可以的 最佳的方式是将列表转换成Python中的科学计算包numpy包的array类型,再进行加减. 1 2 3 4 import numpy as np a = np. ...