ITridentSpout:最通用的Spout,可以支持事务或者不透明事务语义。
IBatchSpout: 一个非事务spout 。
IPartitionedTridentSpout: 分区事务spout,从数据源(比如一个Kafka集群)读分区数据
IOpaquePartitionedTridentSpout:不透明分区事务spout,从数据源读分区数据
接口变动
例如:
简单概括总体流程就是:
trident在执行时每批先调用 getPartitionsForBatch()如果发现返回的Partitions对象和上一批的不相等,则会先后调用 getOrderedPartitions(Integer allPartitionInfo) 和 refreshPartitions(List partitionResponsibilities) 方法,否则不会调用这两个方法。
getOrderedPartitions根据getPartitionsForBatch返回的Partitions对象生成一个Partition列表,refreshPartitions根据getOrderedPartitions返回的Partition列表做一些类似于connections to brokers的操作。
然后再调用emitPartitionBatchNew或者emitPartitionBatch方法。其中emitPartitionBatchNew的partition参数在0.9.0之前是int类型的,现在改成Partition类型,就是getOrderedPartitions返回的List中的一个元素。
其他方法和之前版本都一致。
二、Trident Bolt
唯一显性Bolt接口:ITridentBatchBolt,但很少用。
Trident编程特点就是Stream。
Trident的topology会被编译成尽可能高效的Storm topology。只有在需要对数据进行repartition的时候(如groupby或者shuffle)才会把tuple通过network发送出去,
三、Trident 概念之Operation
在包storm.trident.operation 及子包下
Operation类相关概念有:
· Function :如BaseFunction,类如TridentWordCount中用的Split、
如BaseQueryFunction, TridentWordCount中用的MapGet,从State中查询
· Filter:如BaseFilter ,如TridentWordCount中的FilterNull
· 聚合类:
CombinerAggregator<T>
Aggregator<T>
ReducerAggregator<T>
Functions(函数)
public class MyFunction extends BaseFunction { public void execute(TridentTuple tuple, TridentCollector collector) { for(int i=0; i < tuple.getInteger(0); i++) { collector.emit(new Values(i)); } } }
假设有一个叫“mystream”输入流有[“a”,“b”,“c“]三个字段
[1, 2, 3]
[4, 1, 6]
[3, 0, 8]
运行:mystream.each(new Fields("b"), new MyFunction(), new Fields("d")))
运行的结果将会有4个字段[“a”,“b”,“c”,“d”],如下:
[1, 2, 3, 0]
[1, 2, 3, 1]
[4, 1, 6, 0]
Filters(过滤)
Filters接收一个元组(tuple),决定是否需要继续保留这个元组。比如:
public class MyFilter extends BaseFilter{ public booleanisKeep(TridentTuple tuple) { return tuple.getInteger(0) == 1 && tuple.getInteger(1) == 2; } }
假设有如下输入:
[1, 2, 3]
[2, 1, 1]
[2, 3, 4]
运行下面的代码:
mystream.each(new Fields("b","a"), new MyFilter())
结果将会如下:
[2, 1, 1]
聚合
聚合接口:
CombinerAggreator:在每个tuple上运行init,使用combine去联合结果 。如果批次没有数据,运行zero函数。
ReduceAggregator:在init()初始化的时候产生一个值,每个输入的元组在这个值的基础上进行迭代并输出一个单独的值。
Aggregate:功能最强大
1. Init函数在执行批次操作之前被调用,并返回一个state对象,这个对象将会会传入到aggregate和complete函数中。
2. Aggregate会对批次中每个tuple调用,这个方法可以跟新state也可以发射(emit)tuple。
3. 当这个批次分区的数据执行结束后调用complete函数。
aggregate和persistentAggregate函数对流做聚合。Aggregate在每个批次上独立运行,persistentAggregate聚合流的所有的批次并将结果存储下来。