针对目前主流的消息中间件都有分区的概念,Storm专门提供了backtype.storm.transactional.partitioned包。这里主要介绍一下IPartitionedTransactiona
IPartitionedTransactiona
这里主要介绍一下二者的区别以及用法。IPartitionedTransactiona
但是IPartitionedTransactiona
以统计文本中词的出现次数为例:
假设目前统计的结果为:
man => [count=3]
dog => [count=4]
apple => [count=10]
新的一批次消息为:
["man"]
["man"]
["dog"]
也许这时候应该理所当然的得到新的统计结果:
man => [count=5]
dog => [count=5]
apple => [count=10]
其实没这么简单,也许该批次消费在写数据库时或其他地方出现了异常,会导致spout重发该批次消息,最终会导致重复计算。所以事务型应用最重要的一点是要判断一批消息是新的还是已来过的。IPartitionedTransactiona
man => [count=3, txid=1]
dog => [count=4, txid=3]
apple => [count=10, txid=2]
新的一批次txid=3的消息为:
["man"]
["man"]
["dog"]
计算逻辑应该是:如果保存的txid和发来的txid相等,说明是已处理过的消息,对这样的消息不做处理。如果保存的txid和发过来的txid不等,说明是新的消息,对这样的消息做正常的计算。保证这个计算逻辑正确的基础正是txid的顺序递增以及处理批次的强有序特征。
那么这一批次处理后的结果应该是:
man => [count=5, txid=3]
dog => [count=4, txid=3]
apple => [count=10, txid=2]
IPartitionedTransactiona
IPartitionedTransactiona
IPartitionedTransactiona
查看下面的文档可以很容易理解两个嵌套类的使用方法:
http://nathanmarz.github.io/storm/doc-0.8.1/index.html
重点解释一下IPartitionedTransactiona
public class BatchMeta {
}
IPartitionedTransactiona
X emitPartitionBatchNew(TransactionAttempt tx,
void emitPartitionBatch(TransactionAttempt tx,
emitPartitionBatchNew用于发送一批新的消息,而如果这批消息消费失败了,emitPartitionBatch负责重发这批消息。
类型X可以使用我们自定义的BatchMeta,emitPartitionBatchNew在处理发送逻辑时,要记录两个偏移量,一个是本批次开始的偏移量,存储在BatchMeta.offset中;一个是下一批次开始的偏移量,存储在BatchMeta.nextOffset中。emitPartitionBatchNew的第4个参数lastPartitionMeta其实就是emitPartitionBatchNew上一批次返回并保存在ZK中的BatchMeta。emitPartitionBatchNew使用lastPartitionMeta.nextOffset做为本批次的开始偏移量。
emitPartitionBatch在重发消息时,第4个参数partitionMeta也是emitPartitionBatchNew本批次返回并保存在ZK中的BatchMeta。emitPartitionBatch使用partitionMeta.offset做为本批次的开始偏移量,进行重发消息。