storm的基本概念别人总结的,
https://blog.csdn.net/pickinfo/article/details/50488226 
编程模型最关键最难就是实现局部聚合的业务逻辑
聚合类实现Aggregator接口重写方法aggregate,聚合使用存储中间聚合过程状态的类,本地hashmap的去重逻辑
还有加入redis后进行的一些去重操作,数据的持久(判断三天内的带播控量)
public class SaleSum implements Aggregator<SaleSumState> {
private Logger logger = org.slf4j.LoggerFactory.getLogger(SaleSum.class); /**
*
*/
private static final long serialVersionUID = -6879728480425771684L; private int partitionIndex ;
@Override
public SaleSumState init(Object batchId, TridentCollector collector) {
return new SaleSumState(); } @Override
public void aggregate(SaleSumState val, TridentTuple tuple, TridentCollector collector) {
double oldSum=val.saleSum;
double price=tuple.getDoubleByField("price");
double newSum=oldSum+price;
val.saleSum=newSum;
} @Override
public void complete(SaleSumState val, TridentCollector collector) {
collector.emit(new Values(val.saleSum));
} @Override
public void prepare(Map conf, TridentOperationContext context) { } @Override
public void cleanup() { }
}

public class TridentDemo {

    public static final String SPOUT_ID = "kafak_spout";

    public static void main(String[] args) {

1、创建一个strom此程序的topology 为TridentTopology
TridentTopology topology = new TridentTopology();
2、连接kafka的三要素:zk地址:port topic
//1.从kafak读取数据,
//只会被成功处理 一次 ,有且只有此一次 提供容错机制 处理失败会在后续的批次进行提交
BrokerHosts zkHost = new ZkHosts("hadoop01:2181,hadoop02:2181,hadoop03:2181");
TridentKafkaConfig kafkaConfig = new TridentKafkaConfig(zkHost, "test");//两种构造器
定义从哪消费相当于spark中earliest与largest
kafkaConfig.startOffsetTime = kafka.api.OffsetRequest.LatestTime();
kafkaConfig.scheme = new SchemeAsMultiScheme(new StringScheme());
//透明事务kafka的spout
OpaqueTridentKafkaSpout kafkaSpout = new OpaqueTridentKafkaSpout(kafkaConfig);
//严格模式的事务级别
TransactionalTridentKafkaSpout kafkaSpout1 = new TransactionalTridentKafkaSpout(kafkaConfig);
//普通的kafak级别 {"str","msg"}
//严格的kafak级别 {"str","msg",上一批次的值}
Stream stream = topology.newStream(SPOUT_ID, kafkaSpout);
// stream.each(new Fields("str"),new PrintTestFilter2());
3.进行日志数据的解析,自定义解析类实现了Funtion接口,重写execute方法进行字段解析,在发送出来collector.emit(new Values(timestamp,yyyyMMddStr,yyyyMMddHHStr,yyyyMMddHHmmStr,consumer,productName,price,country,province,city));
   进去的字段名定义为"str",出来的解析字段分别定义了字段名 ,后续做打印测试
Stream hasPraseSteam = stream.each(new Fields("str"), new ParseFunction(), new Fields("timeStamp", "yyyyMMddStr", "yyyyMMddHHStr", "yyyyMMddHHmmStr", "consumer", "productNmae", "price", "country", "provence", "city"));
// .each(new Fields("str", "timeStamp", "yyyyMMddStr", "yyyyMMddHHStr", "yyyyMMddHHmmStr", "consumer", "productNmae", "price", "country", "provence", "city"), new PrintTestFilter2()); 4.进行一个同时进行次数与求和统计的例子,storm是一个服务器节点多个work(jvm),一个work中的task执行自己spout,bolt任务
trident中最重要的地方就是自定义聚合的实现(SaleSum类),常常是实现业务逻辑的地方,规定如何进行数据的聚合, 进行的是各个分区的局部聚合
        //1. 对每天电商的销售额
//去掉用不到的自地段 保留需要用到的字段
//分区统计的流
Stream partitionStatStream = hasPraseSteam.project(new Fields("yyyyMMddStr", "price"))
.shuffle()
.groupBy(new Fields("yyyyMMddStr"))
.chainedAgg()
.partitionAggregate(new Fields("price"), new SaleSum(), new Fields("saleTotalpartByDay")) //进行同一批次各个分区的局部销售额统计
.partitionAggregate(new Fields("price"), new Count(), new Fields("oderNumOfpartDay"))//同一批次中各个分区的订单数
.chainEnd()
.toStream()
.parallelismHint(2); 5. //全局统计 每天的总销售额进行 进行分组全局聚合一般的 顺序=============先进行分区统计,在进行全局统计(相当于hadoop的combine与spark中reducebykey)
TridentState saleGlobalState = partitionStatStream.groupBy(new Fields("yyyyMMddStr"))
.persistentAggregate(new MemoryMapState.Factory(), new Fields("saleTotalpartByDay"), new Sum(), new Fields("saleGlobalAmtDay"));
//测试
saleGlobalState.newValuesStream().each(new Fields("yyyyMMddStr", "saleGlobalAmtDay"), new PrintTestFilter2());
//全局统计 每天的订单总数
TridentState oderGlobalState = partitionStatStream.groupBy(new Fields("yyyyMMddStr"))
.persistentAggregate(new MemoryMapState.Factory(), new Fields("oderNumOfpartDay"), new Sum(), new Fields("oderGlobalAmtDay"));
oderGlobalState.newValuesStream().each(new Fields("yyyyMMddStr", "oderGlobalAmtDay"), new PrintTestFilter2()); //2.给与地域时段 维度 统计 // "timeStamp","yyyyMMddStr","yyyyMMddHHStr","yyyyMMddHHmmStr","consumer","productNmae","price","country","provence","city" TridentState state = hasPraseSteam.project(new Fields("yyyyMMddHHStr", "price", "country", "provence", "city"))
.each(new Fields("yyyyMMddHHStr", "country", "provence", "city"), new ContactKey(), new Fields("addrAndHour"))
// .project()
.groupBy(new Fields("addrAndHour"))
.persistentAggregate(new MemoryMapState.Factory(), new Fields("price"), new Sum(), new Fields("saleAmtOfAddrAndHour")); //测试
state.newValuesStream().each(new Fields("addrAndHour"), new PrintTestFilter2()); //3.使用hbase存入 结果状态
/**rowkey
* value
* 非实物 :就简单存储一个value
* 严格的事实控制: 存储: batchId和统计值
* 透明事务控制 : batchId和统计值和上个批次的统计值 */
HBaseMapState.Options<OpaqueValue> opts=new HBaseMapState.Options<OpaqueValue>();
opts.tableName="test";
opts.columnFamily="info";
//1.1以后设置列名使用下面类
TridentHBaseMapMapper mapMapper= new SimpleTridentHBaseMapMapper("saleAmtOfAddrAndHour");
opts.mapMapper = mapMapper;
StateFactory Hbasefactory=HBaseMapState.opaque(opts); 6.进行hbase存储,storm在给apache后,(1.0版本?后)已经实现与hbase的集成接口,事物类型要与topoloy一致
persistentAggregate为最终的持久化函数,存储可以为内存/hbase,返回值为tridentState
//        HBaseMapState.Options<Object> opts=new HBaseMapState.Options<Object>();
// opts.tableName="test";
// opts.columnFamily="info";
// //1.1以后设置列名使用下面类,存入hbase的列名
// TridentHBaseMapMapper mapMapper= new SimpleTridentHBaseMapMapper("saleAmtOfAddrAndHour");
// opts.mapMapper = mapMapper;
// StateFactory Hbasefactory1=HBaseMapState.nonTransactional(opts); TridentState HbaseState = hasPraseSteam.project(new Fields("yyyyMMddHHStr", "price", "country", "provence", "city"))
.each(new Fields("yyyyMMddHHStr", "country", "provence", "city"), new ContactKey(), new Fields("addrAndHour"))
// .project()
.groupBy(new Fields("addrAndHour"))
.persistentAggregate(Hbasefactory, new Fields("price"), new Sum(), new Fields("saleAmtOfAddrAndHour")); //进行drpc查询
LocalDRPC localDRPC = new LocalDRPC();
topology.newDRPCStream("saleAmtOfDay", localDRPC)
.each(new Fields("args"), new SplitFunction1(), new Fields("requestDate"))
.stateQuery(saleGlobalState, new Fields("requestDate"), new MapGet(),
new Fields("saleGlobalAmtOfDay1"))
.project(new Fields("requestDate", "saleGlobalAmtOfDay1"))
.each(new Fields("saleGlobalAmtOfDay1"), new FilterNull())
// .each(new Fields("requestDate", "saleGlobalAmtOfDay1"), new PrintTestFilter2())
; topology.newDRPCStream("numOrderOfDay", localDRPC)
.each(new Fields("args"), new SplitFunction1(), new Fields("requestDate"))
.stateQuery(oderGlobalState, new Fields("requestDate"), new MapGet(),
new Fields("numOrderGlobalOfDay1"))
.project(new Fields("requestDate", "numOrderGlobalOfDay1"))
.each(new Fields("numOrderGlobalOfDay1"), new FilterNull())
; topology.newDRPCStream("saleTotalAmtOfAddrAndHour", localDRPC)
.each(new Fields("args"), new SplitFunction1(), new Fields("requestAddrAndHour"))
.stateQuery(HbaseState, new Fields("requestAddrAndHour"),
new MapGet(), new Fields("saleTotalAmtOfAddrAndHour"))
.project(new Fields("requestAddrAndHour", "saleTotalAmtOfAddrAndHour"))
.each(new Fields("saleTotalAmtOfAddrAndHour"), new FilterNull())
; 7.提交本地还是集群运行,drpc可以进行对持久化后的state进行数据查询
Config conf = new Config();
if (args == null || args.length <= 0) {
// 本地测试
LocalCluster localCluster = new LocalCluster();
// topology名称唯一
localCluster.submitTopology("odeR", conf, topology.build());
while (true) { try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String saleAmtResult =
localDRPC.execute("saleAmtOfDay", "20160828 20160827"); System.err.println("saleAmtResult=" + saleAmtResult); String numberOrderResult =
localDRPC.execute("numOrderOfDay", "20160828 20160827");
System.err.println("numberOrderResult=" + numberOrderResult); String saleTotalAmtOfAddrAndHourRessult =
localDRPC.execute("saleTotalAmtOfAddrAndHour", "苏州_江苏_中国_2016082815"); System.err.println(saleTotalAmtOfAddrAndHourRessult);
}
} else {
try {
StormSubmitter.submitTopology(args[0], conf, topology.build());
} catch (AlreadyAliveException e) {
e.printStackTrace();
} catch (InvalidTopologyException e) {
e.printStackTrace();
} catch (AuthorizationException e) {
e.printStackTrace();
}
}
}
}

storm的trident编程模型的更多相关文章

  1. Storm架构和编程模型总结

    1. 编程模型 DataSource:外部数据源 Spout:接受外部数据源的组件,将外部数据源转化成Storm内部的数据,以Tuple为基本的传输单元下发给Bolt Bolt:接受Spout发送的数 ...

  2. Storm集成Kafka编程模型

    原创文章,转载请注明: 转载自http://www.cnblogs.com/tovin/p/3974417.html 本文主要介绍如何在Storm编程实现与Kafka的集成 一.实现模型 数据流程: ...

  3. Storm 第一章 核心组件及编程模型

    1 流式计算 流式计算:数据实时产生.实时传输.实时计算.实时展示 代表技术:Flume实时获取数据.Kafka/metaq实时数据存储.Storm/JStorm实时数据计算.Redis实时结果缓存. ...

  4. Storm介绍及核心组件和编程模型

    离线计算 离线计算:批量获取数据.批量传输数据.周期性批量计算数据.数据展示 代表技术:Sqoop批量导入数据.HDFS批量存储数据.MapReduce批量计算数据.Hive批量计算数据.azkaba ...

  5. storm介绍,核心组件,编程模型

    一.流式计算概念 利用分布式的思想和方法,对海量“流”式数据进行实时处理,源自业务对海量数据,在“时效”的价值上的挖掘诉求,随着大数据场景应用场景的增长,对流式计算的需求愈发增多,流式计算的一般架构图 ...

  6. Storm编程模型及组件流程图

    一.Storm编程模型 二.Storm组件流程图

  7. Storm集群组件和编程模型

     Storm工作原理: Storm是一个开源的分布式实时计算系统,常被称为流式计算框架.什么是流式计算呢?通俗来讲,流式计算顾名思义:数据流源源不断的来,一边来,一边计算结果,再进入下一个流. 比 ...

  8. 第1节 storm编程:4、storm环境安装以及storm编程模型介绍

    dataSource:数据源,生产数据的东西 spout:接收数据源过来的数据,然后将数据往下游发送 bolt:数据的处理逻辑单元.可以有很多个,基本上每个bolt都处理一部分工作,然后将数据继续往下 ...

  9. Storm编程模型及Worker通信机制

    1.编程模型 2.Worker通信机制

随机推荐

  1. Linux软件包的安装(rpm+yum)

    概述: 1.rpm软件包管理命令软件包的获取a.光盘镜像中有很多软件包可以使用:先挂载光盘,再查看软件包b.从软件的官网获取 .rpm 安装rpm包 ipm -ivh 软件包名称删除rpm包 ipm ...

  2. c# 文件或者文件夹改名的最简单方法

    使用cmd命令 ren Process.Start( "cmd", "/C " + "ren f:\\first c code.txt zhou.tx ...

  3. vue中less的使用

    1.安装:npm install less less-loader --save 2.修改webpack.config.js文件,配置loader加载依赖,让其支持外部的less,在原来的代码上添加 ...

  4. maven 转myeclipse eclipse 项目 命令

    我们在网上下载的开源Maven工程想要转换成Eclipse能够识别的工程,需要执行如下命令: Jar工程: mvn eclipse:eclipse 或 mvn eclipse:myeclipse We ...

  5. confd动态生成配置文件

    下载安装confd $ mkdir -p $GOPATH/src/github.com/kelseyhightower $ git clone https://github.com/kelseyhig ...

  6. React.createClass 、React.createElement、Component

    react里面有几个需要区别开的函数 React.createClass .React.createElement.Component 首选看一下在浏览器的下面写法: <div id=" ...

  7. 使用github(一)

    一.使用Github(目的.基本概念) 1.目的 借助github托管项目代码 2.基本概念 (1)仓库(Repository) 仓库即项目的意思,你想在github上开源一个项目,那就必须要新建一个 ...

  8. RNN/LSTM/GRU/seq2seq公式推导

    概括:RNN 适用于处理序列数据用于预测,但却受到短时记忆的制约.LSTM 和 GRU 采用门结构来克服短时记忆的影响.门结构可以调节流经序列链的信息流.LSTM 和 GRU 被广泛地应用到语音识别. ...

  9. leetcode473 Matchsticks to Square

    一开始想求所有结果为target的组合来着,但是所选元素不能重叠.用这个递归思想很简单,分成四个桶,每次把元素放在任意一个桶里面,最后如果四个桶相等就可以放进去,有一个地方可以剪枝,假如任意一个桶的元 ...

  10. CentOS7 开放服务端口

    CentOS 7 默认是firewall防火墙 如果你想让一个web服务可以被其它机子访问,就得开放这个服务的端口,不然就会被拦截 1. 开放端口命令 firewall-cmd --add-port= ...