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 ...
随机推荐
- C语言判断文件是否存在
用函数access,头文件是io.h,原型: int access(const char *filename, int amode); amode参数为0时表示检查文件的 ...
- LOAD DATA INFILE Syntax--官方
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name' [REPLACE | IGNORE] INTO TABLE tbl_n ...
- RSA 非对称加密 数字签名 数字证书
什么是RSA加密算法 RSA加密算法是一种非对称加密算法,算法的数学基础是极大数分解难题. RSA加密算法的强度也就是极大数分解的难度,目前700多位(二进制)的数字已经可以破解,1024位认为是比较 ...
- 富文本 Htmll类 html标签
HTML类可解析的标签 在手机上显示从网络端获取的数据有两种方式,一种是WebView,另一种是TextView,WebView大家都知道,功能强大但不灵活,下面主要说下TextView. 通过查看a ...
- php进程继续执行
虽然浏览器提示localhost 的服务器响应时间过长.但是进程在后台继续执行,数据库的条数在增加.
- 已经不再更新新浪、网易及CSDN博客了!
RT, 将常驻以下博客: 地址1:51CTO技术博客:http://javalittleman.blog.51cto.com/ 地址2:博客园:http://www.cnblogs.com/javal ...
- Swift - 41 - swift1.2新特性(1)
更简洁的if-let import UIKit func attack(name: String, enemyName: String, weapon: String) { print("\ ...
- 学OpenGL的一些好的网站
好的资源太多,自己懂的太少,而今迈步从头越!!fighting...... 一些OpenGL资源链接 这是前几天自己简单整理的几个链接,希望对大家有用 顺便问一下http://www.spacesim ...
- assert实现
测试网站在国内国外的访问速度 关于C的右左法则 assert宏的实现(一道笔试题) 2010-11-09 13:05:48| 分类: c | 标签: |举报 |字号大中小 订阅 asser ...
- 自定义ORM框架(转转)
ORM背景 在数据库界,主流的数据库都是关系型数据库,其采用的关系型数据结构模型,无论从数学上还是实践中都相当的成熟,得到非常广泛的应用.在关系型数据结构理 论中,所有的数据都组织成一个个相互独立的二 ...