storm 事务和DRPC结合
示例代码:
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结合的更多相关文章
- storm事务
1. storm 事务 对于容错机制,Storm通过一个系统级别的组件acker,结合xor校验机制判断一个msg是否发送成功,进而spout可以重发该msg,保证一个msg在出错的情况下至少被重发一 ...
- Storm系列(十七)DRPC介绍
Storm版本0.9.5 在storm中DRPC服务应用于远程分布式计算,根据客户端提交的请求参数,而返回Storm计算的结果. DRPC服务启动流程(远程模式) 启动DRPC服务,启动命令:stor ...
- Storm事务Topology的接口介绍
ITransactionalSpout 基本事务Topology的Spout接口,内含两部分接口:协调Spout接口以及消息发送Blot接口. TransactionalSpoutBatchExe ...
- Storm流计算从入门到精通之技术篇(高并发策略、批处理事务、Trident精解、运维监控、企业场景)
1.Storm全面.系统.深入讲解,采用最新的稳定版本Storm 0.9.0.1 : 2.注重实践,对较抽象难懂的技术点如Grouping策略.并发度及线程安全.批处理事务.DRPC.Storm ...
- Storm入门(十二)Twitter Storm: DRPC简介
作者: xumingming | 可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://xumingming.sinaapp.com/756/twitter-stor ...
- Storm集群使用DRPC功能Version1.0.1
在Storm集群上开启DRPC功能, 基于Storm的1.0.1版本, 并且执行简单的例子测试. 1.DRPC概念 DRPC就是分布式远程过程调用. Storm里面引入DRPC主要是利用storm的实 ...
- Storm 实战:构建大数据实时计算
Storm 实战:构建大数据实时计算(阿里巴巴集团技术丛书,大数据丛书.大型互联网公司大数据实时处理干货分享!来自淘宝一线技术团队的丰富实践,快速掌握Storm技术精髓!) 阿里巴巴集团数据平台事业部 ...
- 1 storm基本概念 + storm编程规范及demo编写
本博文的主要内容有 .Storm的单机模式安装 .Storm的分布式安装(3节点) .No space left on device .storm工程的eclipse的java编写 http:// ...
- 2 storm的topology提交执行
本博文的主要内容有 .storm单机模式,打包,放到storm集群 .Storm的并发机制图 .Storm的相关概念 .附PPT 打包,放到storm集群去.我这里,是单机模式下的storm. wee ...
随机推荐
- IPython notebook 使用介绍
参考资料: http://mindonmind.github.io/2013/02/08/ipython-notebook-interactive-computing-new-era/ http:// ...
- Dreamweaver管理Svn控制器内容
一直以来很多人使用Dreamweaver来写css和xhtml.同时如果是应用于一个多人开发的项目的时候大家会使用svn或cvs来做版本控制的工作.但是可惜的是没有听说 Dreamweaver可以与版 ...
- 解决ajax请求cors跨域问题
”已阻止跨源请求:同源策略禁止读取位于 ***** 的远程资源.(原因:CORS 头缺少 'Access-Control-Allow-Origin').“ ”已阻止跨源请求:同源策略禁止读取位于 ** ...
- ASP.Net页面间传值
一.目前在ASP.NET中页面传值共有这么几种方式: 1.表单提交, <form action= "target.aspx" method = "post&qu ...
- 【转】Debug和Release区别
VC下Debug和Release区别 最近写代码过程中,发现 Debug 下运行正常,Release 下就会出现问题,百思不得其解,而Release 下又无法进行调试,于是只能采用printf方式逐步 ...
- Secure CRT 如何连接虚拟机里面的CentOS系统 当主机使用有线网的时候 作者原创 欢迎转载
1.虚拟机的网卡配置如下图所示: 2.在CentOS 5.8的命令行界面:输入如下指令 然后准备修改里面的网关地址和自己的IP地址 3.同时查看自己的IP地址和网关 4.在第二步里面修改,网关地址应该 ...
- Mysql 索引案例学习
理解索引最好的办法是结合示例,所以这里准备了一个索引的案例. 假设要设计一个在线约会网站,用户信息表有很多列,包裹国家,地区,城市,性别,眼睛颜色,等等.完整必须支持上面这些特征的各种组合来搜索用户, ...
- eclipse在当前项目里面批量替换所有单词
ctrl+f里面只能单个文件用,要整个项目批量替换. 1. 先选中你要替换字符串, 2. 再菜单栏中找到Search→Text→Project,这样就会在整个项目中查找单词. 3. 然后在Search ...
- Thinkphp 模版
1.显示模版 在Home/Controller/MainController.class.php中写一个方法来显示对应的模版 function text() { //变量输出 $this->as ...
- Redis+PHP扩展的安装和Redis集群的配置 与 PHP负载均衡开发方案
以前有想过用 Memcache 实现M/S架构的负载均衡方案,直到听说了 Redis 后才发现它做得更好.发了几天时间研究了一下 Redis ,感觉真的很不错,特整理一下! 以下操作都是在 SUSE ...