一、前述

Storm由数源泉spout到bolt时,可以选择分组策略,实现对spout发出的数据的分发。对多个并行度的时候有用。

二、具体原理

1. Shuffle Grouping
随机分组,随机派发stream里面的tuple,保证每个bolt task接收到的tuple数目大致相同。
轮询,平均分配

2. Fields Grouping(相同fields去分发到同一个Bolt)
按字段分组,比如,按"user-id"这个字段来分组,那么具有同样"user-id"的 tuple 会被分到相同的Bolt里的一个task, 而不同的"user-id"则可能会被分配到不同的task。

3. All Grouping
广播发送,对于每一个tuple,所有的bolts都会收到

4. Global Grouping
全局分组,把tuple分配给task id最低的task 。

5. None Grouping
不分组,这个分组的意思是说stream不关心到底怎样分组。目前这种分组和Shuffle grouping是一样的效果。 有一点不同的是storm会把使用none grouping的这个bolt放到这个bolt的订阅者同一个线程里面去执行(未来Storm如果可能的话会这样设计)。

6. Direct Grouping
指向型分组, 这是一种比较特别的分组方法,用这种分组意味着消息(tuple)的发送者指定由消息接收者的哪个task处理这个消息。只有被声明为 Direct Stream 的消息流可以声明这种分组方法。而且这种消息tuple必须使用 emitDirect 方法来发射。消息处理者可以通过 TopologyContext 来获取处理它的消息的task的id (OutputCollector.emit方法也会返回task的id)

7. Local or shuffle grouping
本地或随机分组。如果目标bolt有一个或者多个task与源bolt的task在同一个工作进程中,tuple将会被随机发送给这些同进程中的tasks。否则,和普通的Shuffle Grouping行为一致

8.customGrouping
自定义,相当于mapreduce那里自己去实现一个partition一样。

总结:前4种用的多些,后面4种用的少些。

三、具体案例

Spout(产生数据):

package com.sxt.storm.grouping;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Map; import backtype.storm.spout.SpoutOutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.IRichSpout;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Values; public class MySpout implements IRichSpout { private static final long serialVersionUID = 1L; FileInputStream fis;
InputStreamReader isr;
BufferedReader br; SpoutOutputCollector collector = null;
String str = null; @Override
public void nextTuple() {//真正发的逻辑
try {
while ((str = this.br.readLine()) != null) {
// 过滤动作
collector.emit(new Values(str, str.split("\t")[1]));//发出数据,一行和一行切分完后第二个字段。
}
} catch (Exception e) {
} } @Override
public void close() {//释放资源
try {
br.close();
isr.close();
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
} @Override
public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {//初始化(方法只调用一次)
try {
this.collector = collector;
this.fis = new FileInputStream("track.log");
this.isr = new InputStreamReader(fis, "UTF-8");
this.br = new BufferedReader(isr);
} catch (Exception e) {
e.printStackTrace();
}
} @Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {//声明发出去的字段
declarer.declare(new Fields("log", "session_id"));
} @Override
public Map<String, Object> getComponentConfiguration() {
return null;
} @Override
public void ack(Object msgId) {
System.out.println("spout ack:" + msgId.toString());
} @Override
public void activate() {
} @Override
public void deactivate() {
} @Override
public void fail(Object msgId) {
System.out.println("spout fail:" + msgId.toString());
} }

Bolt:(处理单元)

package com.sxt.storm.grouping;

import java.util.Map;

import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.IRichBolt;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Tuple; public class MyBolt implements IRichBolt { private static final long serialVersionUID = 1L; OutputCollector collector = null;
int num = 0;
String valueString = null; @Override
public void cleanup() { } @Override
public void execute(Tuple input) {
try {
valueString = input.getStringByField("log");//通过fields接收数据 if (valueString != null) {
num++;
System.err.println(input.getSourceStreamId() + " " + Thread.currentThread().getName() + "--id="//打印当前进程名字
+ Thread.currentThread().getId() + " lines :" + num + " session_id:"//打印当前进程id
+ valueString.split("\t")[1]);//这行词的第二个字母
}
collector.ack(input);
// Thread.sleep(2000);
} catch (Exception e) {
collector.fail(input);
e.printStackTrace();
} } @Override
public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
this.collector = collector;
} @Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields(""));//声明空即可
} @Override
public Map<String, Object> getComponentConfiguration() {
return null;
} }

Main方法:

package com.sxt.storm.grouping;

import backtype.storm.Config;
import backtype.storm.LocalCluster;
import backtype.storm.StormSubmitter;
import backtype.storm.generated.AlreadyAliveException;
import backtype.storm.generated.InvalidTopologyException;
import backtype.storm.topology.TopologyBuilder;
import backtype.storm.tuple.Fields; public class Main { /**
* @param args
*/
public static void main(String[] args) { TopologyBuilder builder = new TopologyBuilder(); builder.setSpout("spout", new MySpout(), 1);//拓扑名,数据源,并行度 builder.setBolt("bolt", new MyBolt(), 2).allGrouping("spout");//两个spot并行 所有都分发         //builder.setBolt("bolt", new MyBolt(), 2).shuffleGrouping("spout");// shuffleGrouping其实就是随机往下游去发,不自觉的做到了负载均衡
 
//builder.setBolt("bolt", new MyBolt(), 2).fieldsGrouping("spout", new Fields("session_id")); // fieldsGrouping其实就是MapReduce里面理解的Shuffle,根据fields求hash来取模        //builder.setBolt("bolt", new MyBolt(), 2).globalGrouping("spout"); // 只往一个里面发,往taskId小的那个里面去发送 // builder.setBolt("bolt", new MyBolt(), 2).noneGrouping("spout");   // 等于shuffleGrouping // Map conf = new HashMap();
// conf.put(Config.TOPOLOGY_WORKERS, 4);
Config conf = new Config();
conf.setDebug(false);
conf.setMessageTimeoutSecs(30); if (args.length > 0) {
try {
StormSubmitter.submitTopology(args[], conf, builder.createTopology());//集群方式
} catch (AlreadyAliveException e) {
e.printStackTrace();
} catch (InvalidTopologyException e) {
e.printStackTrace();
}
} else {
LocalCluster localCluster = new LocalCluster();
localCluster.submitTopology("mytopology", conf, builder.createTopology());// 本地模拟参数分别为名称,配置,构建拓扑结构。
} } }

 结果:

1. builder.setBolt("bolt", new MyBolt(), 2).allGrouping("spout");//两个spot并行 所有都分发

 2. builder.setBolt("bolt", new MyBolt(), 2).shuffleGrouping("spout")其实就是随机往下游去发,不自觉的做到了负载均衡

3.builder.setBolt("bolt", new MyBolt(), 2).fieldsGrouping("spout", new Fields("session_id")); // fieldsGrouping其实就是MapReduce里面理解的Shuffle,根据fields求hash来取模,相同的名称的fields分发到一个bolt里面。

4.builder.setBolt("bolt", new MyBolt(), 2).globalGrouping("spout"); // 只往一个里面发,往taskId小的那个里面去发送

企业中常用的也就是这几个!!!

【Storm篇】--Storm分组策略的更多相关文章

  1. 简单聊聊Storm的流分组策略

    简单聊聊Storm的流分组策略 首先我要强调的是,Storm的分组策略对结果有着直接的影响,不同的分组的结果一定是不一样的.其次,不同的分组策略对资源的利用也是有着非常大的不同,本文主要讲一讲loca ...

  2. Storm Grouping —— 流分组策略

    Storm Grouping: Shuffle Grouping :随机分组,尽量均匀分布到下游Bolt中 将流分组定义为混排.这种混排分组意味着来自Spout的输入将混排,或随机分发给此Bolt中的 ...

  3. storm 的分组策略深入理解(-)

    目录 storm的分组策略 根据实例来分析分组策略 common配置: Shuffle grouping shuffle grouping的实例代码 ShuffleGrouping 样例分析 Fiel ...

  4. 亿级流量场景下,大型架构设计实现【2】---storm篇

    承接之前的博:亿级流量场景下,大型缓存架构设计实现 续写本博客: ****************** start: 接下来,我们是要讲解商品详情页缓存架构,缓存预热和解决方案,缓存预热可能导致整个系 ...

  5. Storm流计算之项目篇(Storm+Kafka+HBase+Highcharts+JQuery,含3个完整实际项目)

    1.1.课程的背景 Storm是什么? 为什么学习Storm? Storm是Twitter开源的分布式实时大数据处理框架,被业界称为实时版Hadoop. 随着越来越多的场景对Hadoop的MapRed ...

  6. 【Storm篇】--Storm从初始到分布式搭建

    一.前述 Storm是一个流式处理框架,相比较于SparkStreaming是一个微批处理框架,hadoop是一个批处理框架. 二 .搭建流程 1.集群规划 Nimbus    Supervisor  ...

  7. 分布式流式处理框架:storm简介 + Storm术语解释

    简介: Storm是一个免费开源.分布式.高容错的实时计算系统.它与其他大数据解决方案的不同之处在于它的处理方式.Hadoop 在本质上是一个批处理系统,数据被引入 Hadoop 文件系统 (HDFS ...

  8. 【Storm】Storm实战之频繁二项集挖掘

    一.前言 针对大叔据实时处理的入门,除了使用WordCount示例之外,还需要相对更深入点的示例来理解Storm,因此,本篇博文利用Storm实现了频繁项集挖掘的案例,以方便更好的入门Storm. 二 ...

  9. 【Storm】Storm实战之频繁二项集挖掘(附源码)

    一.前言 针对大叔据实时处理的入门,除了使用WordCount示例之外,还需要相对更深入点的示例来理解Storm,因此,本篇博文利用Storm实现了频繁项集挖掘的案例,以方便更好的入门Storm. 二 ...

随机推荐

  1. python:PATH、PYTHONPATH 和 sys.path 的区别

    python:PATH.PYTHONPATH 和 sys.path 的区别 共同点 所有在它们的路径里面的 moduel 都可以被 import PATH 在 PATH 中的一些命令,例如 *.exe ...

  2. Emgucv使用中常用函数总结

    Emgucv常用函数总结: 读取图片 Mat SCr = new Mat(Form1.Path, Emgu.CV.CvEnum.LoadImageType.AnyColor); //根据路径创建指定的 ...

  3. 研究比对搞定博客 canvas-nest.js

    经过比对网站源码,发现大的差异,复制代码添加成功. 参考:https://www.cnblogs.com/kexing/p/7264767.html 申请js权限 编辑   具体编辑请自行实验, 附上 ...

  4. A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header

    使用arduino烧写esp32模块遇到的无法烧录问题,时钟无法烧录遇到如下提示 后来搜索在如下连接找到解决方法: https://github.com/espressif/esptool/issue ...

  5. 大数据平台Hive数据迁移至阿里云ODPS平台流程与问题记录

    一.背景介绍 最近几天,接到公司的一个将当前大数据平台数据全部迁移到阿里云ODPS平台上的任务.而申请的这个ODPS平台是属于政务内网的,因考虑到安全问题当前的大数据平台与阿里云ODPS的网络是不通的 ...

  6. git 配置 .ssh key

    1.安装git软件: 2.打开本地git bash,使用如下命令生成ssh公钥和私钥对: ssh-keygen -t rsa -C 'xxx@xxx.com'    然后一路回车(-C 参数是你的邮箱 ...

  7. [LeetCode] Car Fleet 车队

    N cars are going to the same destination along a one lane road.  The destination is target miles awa ...

  8. ARouter基础使用(一)

    一个用于帮助 Android App 进行组件化改造的框架 —— 支持模块间的路由.通信.解耦1.新建一个Android项目 "ARouterDemo"2.添加依赖和配置 andr ...

  9. ORACLE 查询近一天,近半小时内的数据

    SELECT 字段  FROM 表名  WHERE 时间字段  BETWEEN SYSDATE-1 AND SYSDATE; //查询一天内的数据 sysdate+1 加一天sysdate+1/24 ...

  10. C#嵌套类

    { "children" : [{ "children" : [{ "children" : [], "name" : ...