首先,我对Storm / Trident有点新意,而且我已经困难了好几个小时。
我所拥有的是一个分区的Kafka主题。生产者每x毫秒向该主题发送元组。 TransactionalTridentKafkaSpout从该主题读取,一些Trident操作符处理它们。整个拓扑以本地模式运行(到目前为止,远程模式未经测试)。
拓扑的主要代码是:
TransactionalTridentKafkaSpout spout = new TransactionalTridentKafkaSpout(spoutConf);
TridentTopology topology = new TridentTopology();
Stream inStream = topology.newStream("kafka-spout", spout).parallelismHint(4);
TridentState state1=inStream
.groupBy(new Fields(ID_FIELD))
.persistentAggregate(new MemoryMapState.Factory(), new Fields(ID_FIELD, FIELD1, FIELD2, FIELD3), new CustomCombinerAgg1(), new Fields(COMB_AGG_1_FIELD))
.parallelismHint(4);
state1.newValuesStream().groupBy(new Fields(ID_FIELD)).
persistentAggregate(new MemoryMapState.Factory(), new Fields(ID_FIELD, COMB_AGG_1_FIELD), new CustomCombinerAgg2(), new Fields(COMB_AGG_2_FIELD))
.parallelismHint(4);
state1.newValuesStream().filter(new Fields(ID_FIELD, COMB_AGG_1_FIELD), new CustomBaseFilter1());
inStream.groupBy(new Fields(ID_FIELD))
.persistentAggregate(new MemoryMapState.Factory(), new Fields(ID_FIELD, FIELD1, FIELD2), new CustomCombinerAgg3(), new Fields(COMB_AGG_3_FIELD));
inStream.groupBy(new Fields(ID_FIELD))
.persistentAggregate(new MemoryMapState.Factory(), new Fields(ID_FIELD, FIELD1, FIELD2, FIELD3), new CustomCombinerAgg4(), new Fields(COMB_AGG_4_FIELD))
.newValuesStream().filter(new Fields(ID_FIELD, COMB_AGG_4_FIELD), new CustomBaseFilter2());
现在我遇到的问题是,生产者的消息间隔越小,执行的一些操作符越少
例如,如果生产者以100毫秒的间隔发送200个元组,则每个操作符正确地处理所有200个元组,但是如果间隔设置为20毫秒,则例如运算符只对以下数量的元组执行处理/执行:
CustomCombinerAgg1:200
CustomCombinerAgg2:50
CustomBaseFilter1:50
CustomCombinerAgg3:150
CustomCombinerAgg4:180
CustomBaseFilter2:60
据我所知(Transactional)Trident确保一次处理,并且只有在前一个完全处理后才应从spout中获取新的一批元组。这似乎不是这里的情况,它看起来像第一个运算符CustomCombinerAgg1,指示速度,然后下面的运算符无法处理给定时间内的所有元组?
我期望的是每个元组都正确执行每个操作符,并且一旦所有操作符处理了元组/批处理,就会获取下一个元组。如果使用Trident不是这种情况吗?难道我做错了什么?我怎样才能实现这种行为?
Trident甚至知道元组何时被完全处理?据我所知你必须ack()Storm中的元组,但Trident运算符没有OutputCollecter因此无法调用ack()?我的问题是否与此有关?
感谢。