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. MySQL中的数据类型以及完整性约束

    数据类型 数据库mysql中也是分很多数据类型的,最常用的就是:数字类型.字符类型.日期类型.枚举与集合类型 一.数字类型: 默认都是有符号的,即正负号,若想无符号,在创建表时加unsigned.指定 ...

  2. 20165236 2017-2018-2 《Java程序设计》第八周学习总结

    20165236 2017-2018-2 <Java程序设计>第八周学习总结 一.第十二章教材内容总结: 1.Java的多线程机制: 多线程是指一个应用程序中同时存在几个执行体,按几条不同 ...

  3. pycharm的安装和使用

    python开发IDE:  pycharm.eclipse 1.要专业版 2.不要汉化版 一.运算符 +  -  * ./  **   %  // 判断某个东西是否在东西里面包含 in   not   ...

  4. Spark History Server产生背景

    以standalone运行模式为例,在运行Spark Application的时候,Spark会提供一个WEBUI列出应用程序的运行时信息:但该WEBUI随着Application的完成(成功/失败) ...

  5. Scala对class/object反射

    近期有需求,要根据解析字符串,根据字符串的内容去调用方法.想到的基本就是使用反射.但是基本上能找到的资料,全没有讲scala的反射.只有零星点点的讲解.大部分都是用scala的语法写java反射最后翻 ...

  6. poj3259: Wormholes(BF模板题)

    http://poj.org/problem?id=3259 Description While exploring his many farms, Farmer John has discovere ...

  7. confd动态生成配置文件

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

  8. JS通过类名判断是否都必填

    //判断class='required' 是否都必填 function required() { var flag = true; $(".required").each(func ...

  9. 监督学习之knn算法

    1.1  KNN(K-Nearest Neighbor)工作原理: 存在一个样本数据集合,也称为训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类对应的关系.输入没有标签 ...

  10. cocos2d JS-(JavaScript) 类型检测与判断

    //检测类型 var str = "Hello World"; if (typeof str=="string") {//使用typeof来判断对象类型的一个例 ...