参考:

  1. http://xumingming.sinaapp.com/736/twitter-storm-transactional-topolgoy/
  2. http://xumingming.sinaapp.com/811/twitter-storm-code-analysis-coordinated-bolt/

示例代码:

package com.lky.topology;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test; import com.lky.util.FileUtil;
import com.lky.util.RunStorm; import backtype.storm.Config;
import backtype.storm.coordination.BatchOutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.testing.MemoryTransactionalSpout;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseBatchBolt;
import backtype.storm.topology.base.BaseTransactionalBolt;
import backtype.storm.transactional.ICommitter;
import backtype.storm.transactional.TransactionAttempt;
import backtype.storm.transactional.TransactionalTopologyBuilder;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Tuple;
import backtype.storm.tuple.Values; @SuppressWarnings({ "deprecation", "serial", "rawtypes" })
/**
* @Title: TransactionalGlobalCount.java
* @Package com.lky.topology
* @Description: 事务topology(模拟实时统计消息数量)
* @author lky
* @date 2015年10月25日 上午11:23:12
* @version V1.0
*/
public class TransactionalGlobalCount {
private static Log log=LogFactory.getLog(TransactionalGlobalCount.class);
public static final int PARTITION_TAKE_PER_BATCH = 3;
public static final Map<Integer, List<List<Object>>> DATA = new HashMap<Integer, List<List<Object>>>() {
{
put(0, new ArrayList<List<Object>>() {
{
add(new Values("cat"));
add(new Values("dog"));
add(new Values("chicken"));
add(new Values("cat"));
add(new Values("dog"));
add(new Values("apple"));
}
});
put(1, new ArrayList<List<Object>>() {
{
add(new Values("cat"));
add(new Values("dog"));
add(new Values("apple"));
add(new Values("banana"));
}
});
put(2, new ArrayList<List<Object>>() {
{
add(new Values("cat"));
add(new Values("cat"));
add(new Values("cat"));
add(new Values("cat"));
add(new Values("cat"));
add(new Values("dog"));
add(new Values("dog"));
add(new Values("dog"));
add(new Values("dog"));
}
});
}
}; public static class Value {
int count = 0;
BigInteger txid;
} public static Map<String, Value> DATABASE = new HashMap<String, Value>();
public static final String GLOBAL_COUNT_KEY = "GLOBAL-COUNT"; /**
* @Title: TransactionalGlobalCount.java
* @Package com.lky.topology
* @Description: processing阶段(可以并行处理)
* @author lky
* @date 2015年10月25日 下午12:14:26
* @version V1.0
*/
public static class BatchCount extends BaseBatchBolt {
BatchOutputCollector collector;
Object id;
Integer _count = 0; @Override
public void prepare(Map conf, TopologyContext context, BatchOutputCollector collector, Object id) {
this.collector = collector;
this.id = id;
} @Override
public void execute(Tuple tuple) {
_count++;
log.info("-------------->"+_count);
} @Override
public void finishBatch() {
log.info("--------"+_count+"----------");
collector.emit(new Values(id, _count));
} @Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("id", "count"));
} } /**
* @Title: TransactionalGlobalCount.java
* @Package com.lky.topology
* @Description: committer 汇总阶段(强顺序流)
* @author lky
* @date 2015年10月25日 下午12:14:54
* @version V1.0
*/
public static class UpdateGlobalCount extends BaseTransactionalBolt implements ICommitter { BatchOutputCollector collector;
TransactionAttempt id;
Integer _size = 0; @Override
public void prepare(Map conf, TopologyContext context, BatchOutputCollector collector, TransactionAttempt id) {
this.collector = collector;
this.id = id;
} @Override
public void execute(Tuple tuple) {
Integer sum = tuple.getInteger(1);
log.info("sum---------->"+sum);
if (sum > 0) {
_size += sum;
}
} @Override
public void finishBatch() {
Value oldValue = DATABASE.get(GLOBAL_COUNT_KEY);
Value newValue; // 如果没有存储过,或者有新的事务到达,更新
if (null == oldValue || !oldValue.txid.equals(id.getTransactionId())) {
newValue = new Value();
newValue.txid = id.getTransactionId();
if (null == oldValue) {
newValue.count = _size;
} else {
newValue.count = _size + oldValue.count;
collector.emit(new Values(id, newValue.count));
FileUtil.strToFile(Integer.valueOf(newValue.count).toString(), "sum.txt", true);
} DATABASE.put(GLOBAL_COUNT_KEY, newValue);
} else {
newValue = oldValue;
}
} @Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("id", "size"));
} } @Test
public void test() {
MemoryTransactionalSpout spout = new MemoryTransactionalSpout(DATA, new Fields("word"), PARTITION_TAKE_PER_BATCH);
TransactionalTopologyBuilder builder = new TransactionalTopologyBuilder("global-count", "spout", spout, 3);
builder.setBolt("partial-count", new BatchCount(), 5).noneGrouping("spout");
builder.setBolt("sum", new UpdateGlobalCount()).globalGrouping("partial-count"); Config config = new Config();
config.setDebug(true);
config.setMaxSpoutPending(3); RunStorm.runStormLocally(builder.buildTopology(), "ss", config, 5);
}
}

storm高级原语-Transactional topology的更多相关文章

  1. (转)STORM启动与部署TOPOLOGY

    STORM启动与部署TOPOLOGY 启动ZOOPKEEPER zkServer.sh start 启动NIMBUS storm nimbus & 启动SUPERVISOR storm sup ...

  2. storm源代码分析---Transactional spouts

    Transactionalspouts Trident是以小批量(batch)的形式在处理tuple.而且每一批都会分配一个唯一的transaction id.不同spout的特性不同,一个trans ...

  3. storm(4)-topology的组成-stream/spout/blot/

    topology包含:stream.spout.blot. topology会一直运行,除非进程被杀死. 1.stream stream=tuple=event(CEP中的)=发送的报文.键值对(一个 ...

  4. Storm基本概念以及Topology的并发度

    Spouts,流的源头 Spout是Storm里面特有的名词,Stream的源头,通常是从外部数据源读取tuples,并emit到topology Spout可以同时emit多个tupic strea ...

  5. Storm概念学习系列之Topology拓扑

    不多说,直接上干货!   Hadoop 上运行的是 MapReduce 作业,而在 Storm 上运行的是拓扑 Topology,这两者之间是非常不同的.一个关键的区别是:一个MapReduce 作业 ...

  6. 第3节 storm高级应用:1、上次课程回顾,今日课程大纲,storm下载地址、运行过程等

    上次课程内容回顾: ConcurrentHashMap是线程安全的,为什么多线程的时候还不好使,为什么还要加static关键字 1.storm的基本介绍:strom是twitter公司开源提供给apa ...

  7. 第3节 storm高级应用:6、定时器任务;7、与jdbc的整合使用;8、与jdbc整合打包集群运行

    ======================================= 5.storm的定时器以及与mysql的整合使用 功能需求:实现每五秒钟打印出当前时间,并将发送出来的数据存入到mysq ...

  8. 第3节 storm高级应用:4、5、ack机制,以及其验证超时

    4.  消息不丢失机制 4.1.ack是什么 ack 机制是storm整个技术体系中非常闪亮的一个创新点. 通过Ack机制,spout发送出去的每一条消息,都可以确定是被成功处理或失败处理, 从而可以 ...

  9. 第3节 storm高级应用:2、storm与hdfs的整合工程环境准备;3、整合代码开发

    ======================================== 3.  storm与hdfs的整合使用 3.1.功能需求: 实现随机发送订单数据,从计算订单的总金额,然后将订单中的数 ...

随机推荐

  1. [转] GMT、UTC与24时区 等时间概念

    许多人都知道两地时间表简称为GMT或UTC,而世界时区表则通称为World Time,那么GMT与UTC的实质原意又是为何?世界时区又是怎么区分的?面盘上密密麻麻的英文单字代表着什么意义与作用呢?这些 ...

  2. 判断线段相交(hdu1558 Segment set 线段相交+并查集)

    先说一下题目大意:给定一些线段,这些线段顺序编号,这时候如果两条线段相交,则把他们加入到一个集合中,问给定一个线段序号,求在此集合中有多少条线段. 这个题的难度在于怎么判断线段相交,判断玩相交之后就是 ...

  3. SuperSocket快速入门(一):什么是SuperSocket

    什么是SuperSocket SuperSocket(下文简称SS)是一个轻量级, 跨平台而且可扩展的 .Net/Mono Socket 服务器程序框架.你无须了解如何使用 Socket, 如何维护 ...

  4. mysql sql语句分析

    1. SELECT     a.id    ,b.order_id,b.attr  FROM    tourist_order a     LEFT JOIN order_attr b     ON ...

  5. C#中yield用法

    yield 关键字向编译器指示它所在的方法是迭代器块.编译器生成一个类来实现迭代器块中表示的行为.在迭代器块中,yield 关键字与 return 关键字结合使用,向枚举器对象提供值.这是一个返回值, ...

  6. 工作中部署使用MP平台的一些问题

    1.首先先把项目导入到myeclipse中,如果没有.classpath和.mymetadata和.project等文件,就自己创建一个web项目,然后把里面的src覆盖,webroot等文件覆盖. ...

  7. Android_Touch_Test

                      }                               }          });      }    }  

  8. QT5-控件-QTimeEdit和QTime

    #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QTimeEdit> #i ...

  9. jsp连接MySQL操作GIS地图数据,实现添加point的功能

    index_map.jsp中的代码: <%@ page language="java" pageEncoding="utf-8"%> <%@ ...

  10. 快速入门cocos2d-x jsbinding

    如果你是一个cocos2d-x的老手,那你可以忽略这篇博文,如果你是一个接触过javascript,想通过HTML5做游戏的,但是苦于不知道如何下手,那么这篇博文可能会帮到你. cocos2dx-js ...