示例代码:

package com.lky.topology;

import backtype.storm.Config;
import backtype.storm.LocalCluster;
import backtype.storm.LocalDRPC;
import backtype.storm.coordination.BatchOutputCollector;
import backtype.storm.drpc.LinearDRPCTopologyBuilder;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.BasicOutputCollector;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseBasicBolt;
import backtype.storm.topology.base.BaseBatchBolt;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Tuple;
import backtype.storm.tuple.Values;
import backtype.storm.utils.Utils; import java.util.*; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; /**
* @Title: ReachTopology.java
* @Package com.lky.topology
* @Description: 计算一个包含特定url的微博,最终能被多少人看到
* @author lky
* @date 2015年10月23日 下午9:09:22
* @version V1.0
*/
public class ReachTopology {
private static Log log = LogFactory.getLog(ReachTopology.class);
public static Map<String, List<String>> TWEETERS_DB = new HashMap<String, List<String>>() {
{
put("foo.com/blog/1", Arrays.asList("sally", "bob", "tim", "george", "nathan"));
put("engineering.twitter.com/blog/5", Arrays.asList("adam", "david", "sally", "nathan"));
put("tech.backtype.com/blog/123", Arrays.asList("tim", "mike", "john"));
}
}; public static Map<String, List<String>> FOLLOWERS_DB = new HashMap<String, List<String>>() {
{
put("sally", Arrays.asList("bob", "tim", "alice", "adam", "jim", "chris", "jai"));
put("bob", Arrays.asList("sally", "nathan", "jim", "mary", "david", "vivian"));
put("tim", Arrays.asList("alex"));
put("nathan", Arrays.asList("sally", "bob", "adam", "harry", "chris", "vivian", "emily", "jordan"));
put("adam", Arrays.asList("david", "carissa"));
put("mike", Arrays.asList("john", "bob"));
put("john", Arrays.asList("alice", "nathan", "jim", "mike", "bob"));
}
}; /**
* @Title: ReachTopology.java
* @Package com.lky.topology
* @Description: 获取包含该特定url的所有用户,随机发放到下游bolt中
* @author lky
* @date 2015年10月23日 下午11:46:19
* @version V1.0
*/
@SuppressWarnings("serial")
public static class GetTweeters extends BaseBasicBolt { @Override
public void execute(Tuple input, BasicOutputCollector collector) {
Object id = null;
String url = null;
try {
id = input.getValue(0);
url = input.getString(1);
List<String> tweeters = new ArrayList<String>();//获取包含该url的所有用户 if (null != id && null != url) {
tweeters = TWEETERS_DB.get(url);
if (null != tweeters) {
for (String tweeter : tweeters) {
log.info("execute1------>[id = " + id + " ]["+url+"---->tweeter=" + tweeter + "]");
collector.emit(new Values(id, tweeter));
}
}
}
} catch (Exception e) {
log.error("execute 发射消息错误!!!!!");
}
} @Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("id", "tweeter"));
} } /**
* @Title: ReachTopology.java
* @Package com.lky.topology
* @Description:获取每一个用户的粉丝,然后按字段分组(id,fllower)到下游bolt中,保证同一类url的相同用户被分到相同的批次
* @author lky
* @date 2015年10月23日 下午11:47:45
* @version V1.0
*/
@SuppressWarnings("serial")
public static class GetFollowers extends BaseBasicBolt { @Override
public void execute(Tuple input, BasicOutputCollector collector) {
Object id = null;
String _follower = null; try {
id = input.getValue(0);
_follower = input.getString(1);
List<String> followers = new ArrayList<String>(); if (null != id && null != _follower) {
followers = FOLLOWERS_DB.get(_follower);//获取该用户的所有粉丝
if (null != followers) {
for (String follower : followers) {
log.info("execute2------>[id = " + id + " ]["+_follower+"------>follower=" + follower + "]");
collector.emit(new Values(id, follower));
}
}
} } catch (Exception e) {
log.error("execute 发射消息异常!!!");
} } @Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("id", "follower"));
} } /**
* @Title: ReachTopology.java
* @Package com.lky.topology
* @Description: 按批次统计粉丝数量
* @author lky
* @date 2015年10月23日 下午11:50:51
* @version V1.0
*/
@SuppressWarnings({ "serial", "rawtypes" })
public static class PartialUniquer extends BaseBatchBolt {
private BatchOutputCollector collector;
private Object id;
private Set<String> _followerSet = new HashSet<String>(); @Override
public void prepare(Map conf, TopologyContext context, BatchOutputCollector collector, Object id) {
this.collector = collector;
this.id = id;
} @Override
public void execute(Tuple tuple) {
String uname = null; try {
uname = tuple.getString(1);
if (null != uname) {
log.info("execute3------>[id = " + tuple.getValue(0) + " ][ uname=" + uname + "]");
_followerSet.add(uname);
}
} catch (Exception e) {
log.error("execute 接收消息异常!!!");
}
} @Override
public void finishBatch() {
log.info("execute4------>[id = " + id + " ][ size=" + _followerSet.size() + "]");
collector.emit(new Values(id, _followerSet.size()));
} @Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("id", "count"));
} } /**
* @Title: ReachTopology.java
* @Package com.lky.topology
* @Description: 按相同的id汇总批次
* @author lky
* @date 2015年10月23日 下午11:51:49
* @version V1.0
*/
@SuppressWarnings({ "serial", "rawtypes" })
public static class CountAggregator extends BaseBatchBolt {
private BatchOutputCollector collector;
private Object id;
private int _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) {
Integer count = null;
try {
count = tuple.getInteger(1);
log.info("execute5------>[id = " + tuple.getValue(0) + " ][ count=" + count + "]");
_count += count;
} catch (Exception e) {
log.error("execute 接收消息异常");
}
} @Override
public void finishBatch() {
collector.emit(new Values(id, _count));
} @Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("id", "result"));
}
} @SuppressWarnings("deprecation")
public static LinearDRPCTopologyBuilder construct() {
LinearDRPCTopologyBuilder builder = new LinearDRPCTopologyBuilder("reach");
builder.addBolt(new GetTweeters(), 4);
builder.addBolt(new GetFollowers(), 12).shuffleGrouping();
builder.addBolt(new PartialUniquer(), 6).fieldsGrouping(new Fields("id", "follower"));
builder.addBolt(new CountAggregator(), 3).fieldsGrouping(new Fields("id"));
return builder;
} @SuppressWarnings("deprecation")
public static void main(String[] args) {
LinearDRPCTopologyBuilder builder = construct(); Config conf = new Config();
conf.setMaxTaskParallelism(3);
LocalDRPC drpc = new LocalDRPC();
LocalCluster cluster = new LocalCluster();
cluster.submitTopology("reach-drpc", conf, builder.createLocalTopology(drpc)); String[] urlsToTry = new String[] { "foo.com/blog/1", "engineering.twitter.com/blog/5", "notaurl.com" };
for (String url : urlsToTry) {
System.out.println("Reach of " + url + ": " + drpc.execute("reach", url));
} Utils.sleep(1000 * 10);
cluster.shutdown();
drpc.shutdown();
}
}

storm 事务和DRPC结合的更多相关文章

  1. storm事务

    1. storm 事务 对于容错机制,Storm通过一个系统级别的组件acker,结合xor校验机制判断一个msg是否发送成功,进而spout可以重发该msg,保证一个msg在出错的情况下至少被重发一 ...

  2. Storm系列(十七)DRPC介绍

    Storm版本0.9.5 在storm中DRPC服务应用于远程分布式计算,根据客户端提交的请求参数,而返回Storm计算的结果. DRPC服务启动流程(远程模式) 启动DRPC服务,启动命令:stor ...

  3. Storm事务Topology的接口介绍

      ITransactionalSpout 基本事务Topology的Spout接口,内含两部分接口:协调Spout接口以及消息发送Blot接口. TransactionalSpoutBatchExe ...

  4. Storm流计算从入门到精通之技术篇(高并发策略、批处理事务、Trident精解、运维监控、企业场景)

    1.Storm全面.系统.深入讲解,采用最新的稳定版本Storm 0.9.0.1 :   2.注重实践,对较抽象难懂的技术点如Grouping策略.并发度及线程安全.批处理事务.DRPC.Storm ...

  5. Storm入门(十二)Twitter Storm: DRPC简介

    作者: xumingming | 可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://xumingming.sinaapp.com/756/twitter-stor ...

  6. Storm集群使用DRPC功能Version1.0.1

    在Storm集群上开启DRPC功能, 基于Storm的1.0.1版本, 并且执行简单的例子测试. 1.DRPC概念 DRPC就是分布式远程过程调用. Storm里面引入DRPC主要是利用storm的实 ...

  7. Storm 实战:构建大数据实时计算

    Storm 实战:构建大数据实时计算(阿里巴巴集团技术丛书,大数据丛书.大型互联网公司大数据实时处理干货分享!来自淘宝一线技术团队的丰富实践,快速掌握Storm技术精髓!) 阿里巴巴集团数据平台事业部 ...

  8. 1 storm基本概念 + storm编程规范及demo编写

    本博文的主要内容有 .Storm的单机模式安装 .Storm的分布式安装(3节点)   .No space left on device .storm工程的eclipse的java编写 http:// ...

  9. 2 storm的topology提交执行

    本博文的主要内容有 .storm单机模式,打包,放到storm集群 .Storm的并发机制图 .Storm的相关概念 .附PPT 打包,放到storm集群去.我这里,是单机模式下的storm. wee ...

随机推荐

  1. Java基础知识强化91:DateFormat类之DateFormat实现日期和字符串的相互转换

    1. DateFormat类概述: DateFormat 是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并解析日期或时间. 是抽象类,所以使用其子类SimpleDateFormat 2.  ...

  2. Could not reliably determine the server's fully qualified domain name

    启动apache报错: [root@namenode1 ]# service httpd start Starting httpd: httpd: Could not reliably determi ...

  3. C++关联容器<map>简单总结

    C++关联容器<map>简单总结 map提供大小可变的关联容器,基于关联键值高效检索元素值.当你处理键值对的数据是,都可以考虑使用map关联容器. 特点: 大小可变的关联容器,基于关联键值 ...

  4. Arcgis server - ' packaging failed '

    我在使用ARCCatalog发布地图服务时,报这个错:packaging failed 然后我从头试,发现它提示说我的目录'C:\Users\Administrator\AppData\Local\E ...

  5. .net 文件下载方法

    public void DownLoadMethod(string FilePath)        {            string hzm = Path.GetExtension(FileP ...

  6. XFire构建服务端Service的两种方式

    1.原声构建: 2.集成spring构建 http://blog.csdn.net/carefree31441/article/details/4000436XFire构建服务端Service的两种方 ...

  7. Windows免密码远程桌面

    1.WinKey + R,在对话框中输入“gpedit.msc”,点“确定”:   2.展开:计算机配置--Windows设置--安全设置--本地策略--安全选项,找到“帐户:使用空白密码的本地账户只 ...

  8. expected function body after function declarator

    我出现这个错误是在pch中添加了一个a.h文件 然后在其他文件的b.h文件中就出现这个错误.. 后来排查出原因是: 在pch中, 这个a.h文件在b.h文件之后, 所以在b.h中使用的时候就会报错

  9. 你好,C++(21)只要天还没黑,就一直在工地干活-4.3.1 while循环:只要…就一直…

    4.3  循环控制语句 在现实世界中,有这样一类现象: 只要油箱中的当前油量小于油箱容量100升,就一直往油箱中加油: 一直不断地为祖国辛勤工作,只要我还活着: 公司100000位员工,每个人的工资都 ...

  10. 转发——推荐一些国外高质量Java开发者的博客

    学习Java很不错的一篇博客,总结了很详尽的Java开发者博客. http://www.admin10000.com/document/3373.html 这些博客具有以下特点: 文章的可读性和有独创 ...