示例代码:

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. iPhone 各版本屏幕分辨率

    参考:http://www.paintcodeapp.com/news/iphone-6-screens-demystified

  2. spring配置文件位置

    参考http://name327.iteye.com/blog/1628884

  3. C#Css/Js静态文件压缩--Yui.Compressor.Net

    一.Asp.Net 自带静态文件压缩工具包 Microsoft.AspNet.Web.Optimization http://www.nuget.org/packages/Microsoft.AspN ...

  4. MongoDB与PHP的添加、修改、查询、删除

    链接数据库使用下面的代码创建一个数据库链接 <?php$connection = new Mongo(); //链接到 localhost:27017$connection = new Mong ...

  5. 星座物语APP

    效果图: 这里的后台管理用的是duducat,大家可以去百度看说明.图片,文字都在duducat后台服务器上,可以自己修改的.(PS:图片这里是随便找的) http://www.duducat.com ...

  6. SQL Server 和CLR集成

    通过在 Microsoft SQL Server 中托管 CLR(称为 CLR 集成),可以在托管代码中编写存储过程.触发器.用户定义函数.用户定义类型和用户定义聚合函数. 因为托管代码在执行之前会编 ...

  7. ORACLE外键和锁

    在oracle中,如果外键未加索引,对父表的修改,会导致子表被加上全表锁.这包括两种情况: 1.删除父表中的行,如果外键上没有索引,会导致子表被加上全表锁 2.更新父表的主键(根据关系数据库的原则,更 ...

  8. [BZOJ]3737 [Pa2013]Euler

    从这个FB开始写博客啦. 也不知道会坚持多久…… = =似乎要加一句转载请注明出处 http://www.cnblogs.com/DancingOnTheTree/p/4026076.html htt ...

  9. canvas 绘制矩形

    XXX(x,y,width,height)   x矩形左上角x坐标                                   y矩形左上角y坐标                       ...

  10. php发送post请求的三种方法示例

    本文分享下php发送post请求的三种方法与示例代码,分别使用curl.file_get_content.fsocket来实现post提交数据,大家做个参考. php发送post请求的三种方法,分别使 ...