参考:

  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. 【解决】hive动态添加partitions不能超过100的问题

    Author: kwu [解决]hive动态添加partitions不能超过100的问题,全量动态生成partitions超过100会出现例如以下异常: The maximum number of d ...

  2. java/php/c#版rsa签名以及java验签实现--转

    在开放平台领域,需要给isv提供sdk,签名是Sdk中需要提供的功能之一.由于isv使用的开发语言不是单一的,因此sdk需要提供多种语言的版本.譬如java.php.c#.另外,在电子商务尤其是支付领 ...

  3. java Serializable和Externalizable序列化反序列化详解--转

    一.什么是序列化? “对象序列化”(Object Serialization)是 Java1.1就开始有的特性. 简单地说,就是可以将一个对象(标志对象的类型)及其状态转换为字节码,保存起来(可以保存 ...

  4. i利用图片按钮 和 input type="image" 为背景提交表单

    <img src="img/cancel.jpg" onclick="javascript:document.getElementByIdx_x('loginFor ...

  5. spring07 JDBC

    1.创建对应的数据库 2.在MyEclipse中创建项目  引入需要的jar包 3.创建数据访问层 public interface StudentDao { //新增学生 int addStuden ...

  6. web03--session

    1.创建session1.jsp <body> <form action="session2.jsp" method="post"> & ...

  7. 在winform程序中实现按照不同的角色或用户展现不同的页面

    SqlConnection cn = new SqlConnection();             cn.ConnectionString = "Data Source=192.168. ...

  8. id名和class名有什么区别

    从概念上来说: id是先找到结构/内容,再给它定义样式: class是先定义好一种样式,再套给多个结构/内容. 从样式效果上来说:    id的优先级要比class高出一个层次 html中不管有几个i ...

  9. css新增属性

    圆角,border-radius: 1-4个数字/1-4个数字,前面是水平,后面是垂直,不给“/”表示水平和垂直一样,举例如下: <head> <meta http-equiv=&q ...

  10. vs2012加载EntityFrameWork框架,连接Oracel

    近日公司用到.net MVC框架做接口,需连接到Oracel数据库,从网上查阅了一些资料,当然,从咱们博客园获益匪浅.然后结合自己所做,把使用过程中遇到的一些问题,及如何解决的整理如下,方便查阅,也有 ...