From 2ddc8b86699829e692ab7d379a1c95ea1d1f4bdc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=BD=97=E7=A5=A5?= <1366971433@qq.com>
Date: Mon, 15 Apr 2019 16:03:12 +0800
Subject: [PATCH] =?UTF-8?q?storm=E7=BC=96=E7=A8=8B=E6=A8=A1=E5=9E=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../1027/worker.yaml | 4 +
.../1027/worker.yaml | 4 +
.../1024/worker.yaml | 4 +
.../1027/worker.yaml | 4 +
code/Storm/storm-word-count/pom.xml | 32 +++
.../heibaiying/wordcount/WordCountApp.java | 26 +++
.../wordcount/component/CountBolt.java | 40 ++++
.../wordcount/component/DataSourceSpout.java | 49 +++++
.../wordcount/component/SplitBolt.java | 35 ++++
notes/storm编程模型.md | 194 +++++++++++++++++-
pictures/storm-word-count-console.png | Bin 0 -> 39558 bytes
pictures/storm-word-count-p.png | Bin 0 -> 39514 bytes
12 files changed, 383 insertions(+), 9 deletions(-)
create mode 100644 code/Storm/storm-word-count/logs/workers-artifacts/LocalWordCountTopology-1-1555310515/1027/worker.yaml
create mode 100644 code/Storm/storm-word-count/logs/workers-artifacts/LocalWordCountTopology-1-1555311430/1027/worker.yaml
create mode 100644 code/Storm/storm-word-count/logs/workers-artifacts/LocalWordCountTopology-1-1555311784/1024/worker.yaml
create mode 100644 code/Storm/storm-word-count/logs/workers-artifacts/LocalWordCountTopology-1-1555313003/1027/worker.yaml
create mode 100644 code/Storm/storm-word-count/pom.xml
create mode 100644 code/Storm/storm-word-count/src/main/java/com/heibaiying/wordcount/WordCountApp.java
create mode 100644 code/Storm/storm-word-count/src/main/java/com/heibaiying/wordcount/component/CountBolt.java
create mode 100644 code/Storm/storm-word-count/src/main/java/com/heibaiying/wordcount/component/DataSourceSpout.java
create mode 100644 code/Storm/storm-word-count/src/main/java/com/heibaiying/wordcount/component/SplitBolt.java
create mode 100644 pictures/storm-word-count-console.png
create mode 100644 pictures/storm-word-count-p.png
diff --git a/code/Storm/storm-word-count/logs/workers-artifacts/LocalWordCountTopology-1-1555310515/1027/worker.yaml b/code/Storm/storm-word-count/logs/workers-artifacts/LocalWordCountTopology-1-1555310515/1027/worker.yaml
new file mode 100644
index 0000000..ecad21e
--- /dev/null
+++ b/code/Storm/storm-word-count/logs/workers-artifacts/LocalWordCountTopology-1-1555310515/1027/worker.yaml
@@ -0,0 +1,4 @@
+worker-id: 7b8e6dbf-1e3e-4368-8f0c-1a4936042ca7
+logs.users: []
+logs.groups: []
+topology.submitter.user: ciic
diff --git a/code/Storm/storm-word-count/logs/workers-artifacts/LocalWordCountTopology-1-1555311430/1027/worker.yaml b/code/Storm/storm-word-count/logs/workers-artifacts/LocalWordCountTopology-1-1555311430/1027/worker.yaml
new file mode 100644
index 0000000..a3d2249
--- /dev/null
+++ b/code/Storm/storm-word-count/logs/workers-artifacts/LocalWordCountTopology-1-1555311430/1027/worker.yaml
@@ -0,0 +1,4 @@
+worker-id: 931219fd-8b9a-4333-9fda-5d1df11a258c
+logs.users: []
+logs.groups: []
+topology.submitter.user: ciic
diff --git a/code/Storm/storm-word-count/logs/workers-artifacts/LocalWordCountTopology-1-1555311784/1024/worker.yaml b/code/Storm/storm-word-count/logs/workers-artifacts/LocalWordCountTopology-1-1555311784/1024/worker.yaml
new file mode 100644
index 0000000..e627b4a
--- /dev/null
+++ b/code/Storm/storm-word-count/logs/workers-artifacts/LocalWordCountTopology-1-1555311784/1024/worker.yaml
@@ -0,0 +1,4 @@
+worker-id: 9cdf2e0f-b135-41c6-b3fd-1502afddf212
+logs.users: []
+logs.groups: []
+topology.submitter.user: ciic
diff --git a/code/Storm/storm-word-count/logs/workers-artifacts/LocalWordCountTopology-1-1555313003/1027/worker.yaml b/code/Storm/storm-word-count/logs/workers-artifacts/LocalWordCountTopology-1-1555313003/1027/worker.yaml
new file mode 100644
index 0000000..677f718
--- /dev/null
+++ b/code/Storm/storm-word-count/logs/workers-artifacts/LocalWordCountTopology-1-1555313003/1027/worker.yaml
@@ -0,0 +1,4 @@
+worker-id: 9837751b-8320-4651-b325-3c64898b976d
+logs.users: []
+logs.groups: []
+topology.submitter.user: ciic
diff --git a/code/Storm/storm-word-count/pom.xml b/code/Storm/storm-word-count/pom.xml
new file mode 100644
index 0000000..da880b7
--- /dev/null
+++ b/code/Storm/storm-word-count/pom.xml
@@ -0,0 +1,32 @@
+
+
+ 4.0.0
+
+ com.heibaiying
+ storm-word-count
+ 1.0-SNAPSHOT
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 8
+ 8
+
+
+
+
+
+
+
+
+ org.apache.storm
+ storm-core
+ 1.2.2
+
+
+
+
\ No newline at end of file
diff --git a/code/Storm/storm-word-count/src/main/java/com/heibaiying/wordcount/WordCountApp.java b/code/Storm/storm-word-count/src/main/java/com/heibaiying/wordcount/WordCountApp.java
new file mode 100644
index 0000000..e46d7a3
--- /dev/null
+++ b/code/Storm/storm-word-count/src/main/java/com/heibaiying/wordcount/WordCountApp.java
@@ -0,0 +1,26 @@
+package com.heibaiying.wordcount;
+
+import com.heibaiying.wordcount.component.CountBolt;
+import com.heibaiying.wordcount.component.DataSourceSpout;
+import com.heibaiying.wordcount.component.SplitBolt;
+import org.apache.storm.Config;
+import org.apache.storm.LocalCluster;
+import org.apache.storm.topology.TopologyBuilder;
+
+public class WordCountApp{
+
+ public static void main(String[] args) {
+ TopologyBuilder builder = new TopologyBuilder();
+ builder.setSpout("DataSourceSpout", new DataSourceSpout());
+ // 指明将 DataSourceSpout 的数据发送到 SplitBolt 中处理
+ builder.setBolt("SplitBolt", new SplitBolt()).shuffleGrouping("DataSourceSpout");
+ // 指明将 SplitBolt 的数据发送到 CountBolt 中 处理
+ builder.setBolt("CountBolt", new CountBolt()).shuffleGrouping("SplitBolt");
+
+ // 创建本地集群用于测试 这种模式不需要本机安装storm,直接运行该Main方法即可
+ LocalCluster cluster = new LocalCluster();
+ cluster.submitTopology("LocalWordCountTopology",
+ new Config(), builder.createTopology());
+ }
+
+}
diff --git a/code/Storm/storm-word-count/src/main/java/com/heibaiying/wordcount/component/CountBolt.java b/code/Storm/storm-word-count/src/main/java/com/heibaiying/wordcount/component/CountBolt.java
new file mode 100644
index 0000000..5fd3170
--- /dev/null
+++ b/code/Storm/storm-word-count/src/main/java/com/heibaiying/wordcount/component/CountBolt.java
@@ -0,0 +1,40 @@
+package com.heibaiying.wordcount.component;
+
+import org.apache.storm.task.OutputCollector;
+import org.apache.storm.task.TopologyContext;
+import org.apache.storm.topology.OutputFieldsDeclarer;
+import org.apache.storm.topology.base.BaseRichBolt;
+import org.apache.storm.tuple.Tuple;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class CountBolt extends BaseRichBolt {
+
+ private Map counts = new HashMap<>();
+
+ @Override
+ public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
+
+ }
+
+ @Override
+ public void execute(Tuple input) {
+ String word = input.getStringByField("word");
+ Integer count = counts.get(word);
+ if (count == null) {
+ count = 0;
+ }
+ count++;
+ counts.put(word, count);
+ // 输出
+ System.out.print("当前实时统计结果:");
+ counts.forEach((key, value) -> System.out.print(key + ":" + value + "; "));
+ System.out.println();
+ }
+
+ @Override
+ public void declareOutputFields(OutputFieldsDeclarer declarer) {
+
+ }
+}
diff --git a/code/Storm/storm-word-count/src/main/java/com/heibaiying/wordcount/component/DataSourceSpout.java b/code/Storm/storm-word-count/src/main/java/com/heibaiying/wordcount/component/DataSourceSpout.java
new file mode 100644
index 0000000..8ca0d78
--- /dev/null
+++ b/code/Storm/storm-word-count/src/main/java/com/heibaiying/wordcount/component/DataSourceSpout.java
@@ -0,0 +1,49 @@
+package com.heibaiying.wordcount.component;
+
+import org.apache.storm.shade.org.apache.commons.lang.StringUtils;
+import org.apache.storm.spout.SpoutOutputCollector;
+import org.apache.storm.task.TopologyContext;
+import org.apache.storm.topology.OutputFieldsDeclarer;
+import org.apache.storm.topology.base.BaseRichSpout;
+import org.apache.storm.tuple.Fields;
+import org.apache.storm.tuple.Values;
+import org.apache.storm.utils.Utils;
+
+import java.util.*;
+
+public class DataSourceSpout extends BaseRichSpout {
+
+ private List list = Arrays.asList("Spark", "Hadoop", "HBase", "Storm", "Flink", "Hive");
+
+ private SpoutOutputCollector spoutOutputCollector;
+
+ @Override
+ public void open(Map map, TopologyContext topologyContext, SpoutOutputCollector spoutOutputCollector) {
+ this.spoutOutputCollector = spoutOutputCollector;
+ }
+
+ @Override
+ public void nextTuple() {
+ // 模拟产生数据
+ String lineData = productData();
+ spoutOutputCollector.emit(new Values(lineData));
+ Utils.sleep(1000);
+ }
+
+ @Override
+ public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
+ outputFieldsDeclarer.declare(new Fields("line"));
+ }
+
+
+ /**
+ * 模拟数据
+ */
+ private String productData() {
+ Collections.shuffle(list);
+ Random random = new Random();
+ int endIndex = random.nextInt(list.size()) % (list.size()) + 1;
+ return StringUtils.join(list.toArray(), "\t", 0, endIndex);
+ }
+
+}
diff --git a/code/Storm/storm-word-count/src/main/java/com/heibaiying/wordcount/component/SplitBolt.java b/code/Storm/storm-word-count/src/main/java/com/heibaiying/wordcount/component/SplitBolt.java
new file mode 100644
index 0000000..5cf1c2b
--- /dev/null
+++ b/code/Storm/storm-word-count/src/main/java/com/heibaiying/wordcount/component/SplitBolt.java
@@ -0,0 +1,35 @@
+package com.heibaiying.wordcount.component;
+
+import org.apache.storm.task.OutputCollector;
+import org.apache.storm.task.TopologyContext;
+import org.apache.storm.topology.OutputFieldsDeclarer;
+import org.apache.storm.topology.base.BaseRichBolt;
+import org.apache.storm.tuple.Fields;
+import org.apache.storm.tuple.Tuple;
+import org.apache.storm.tuple.Values;
+
+import java.util.Map;
+
+public class SplitBolt extends BaseRichBolt {
+
+ private OutputCollector collector;
+
+ @Override
+ public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
+ this.collector=collector;
+ }
+
+ @Override
+ public void execute(Tuple input) {
+ String line = input.getStringByField("line");
+ String[] words = line.split("\t");
+ for (String word : words) {
+ collector.emit(new Values(word));
+ }
+ }
+
+ @Override
+ public void declareOutputFields(OutputFieldsDeclarer declarer) {
+ declarer.declare(new Fields("word"));
+ }
+}
diff --git a/notes/storm编程模型.md b/notes/storm编程模型.md
index 21eca93..7b88c29 100644
--- a/notes/storm编程模型.md
+++ b/notes/storm编程模型.md
@@ -1,14 +1,28 @@
# Storm 编程模型
+
+
+
## 一、简介
下图为Strom的运行流程图,也是storm的编程模型图,在storm 进行流处理时,我们需要自定义实现自己的spout(数据源)和bolt(处理单元),并通过`TopologyBuilder`将它们之间进行关联,定义好数据处理的流程。
下面小结分别介绍如何按照storm内置接口分别实现spout和bolt,然后将其进行关联,最后将其提交到本地和服务器进行运行。
-
+
-## 二、IComponent
+## 二、IComponent接口
`IComponent`接口定义了Topology中所有组件(spout/bolt)的公共方法,我们实现spout或bolt都必须直接或者间接实现这个接口。
@@ -30,7 +44,7 @@ public interface IComponent extends Serializable {
}
```
-## 三、spout
+## 三、Spout
### 3.1 ISpout接口
@@ -84,7 +98,7 @@ public interface ISpout extends Serializable {
**通常情况下,我们实现自定义的Spout时不会直接去实现`ISpout`接口,而是继承`BaseRichSpout`。**`BaseRichSpout`继承自`BaseCompont`,同时实现了`IRichSpout`接口。
-
+
`IRichSpout`接口继承自`ISpout`和`IComponent`,自身并没有定义任何方法。
@@ -134,7 +148,7 @@ public abstract class BaseRichSpout extends BaseComponent implements IRichSpout
-## 四、bolt
+## 四、Bolt
通过上小结我们已经了解了storm如何对spout接口进行设计的,bolt接口的设计也是一样的。
@@ -175,7 +189,7 @@ public interface IBolt extends Serializable {
同样的,在实现我们自己的bolt时,我们也通常是继承`BaseRichBolt`抽象类来实现。`BaseRichBolt`继承自`BaseComponent`抽象类,并实现了`IRichBolt`接口。
-
+
`IRichBolt`接口继承自`IBolt`和`IComponent`,自身并没有定义任何方法。
@@ -187,14 +201,176 @@ public interface IRichBolt extends IBolt, IComponent {
通过这样的设计,我们在继承`BaseRichBolt`实现自己的bolt时,就只需要实现三个必须的方法:
-- prepare: 来源于IBolt,可以通过此方法获取用来发送tuples的`SpoutOutputCollector`;
+- prepare: 来源于IBolt,可以通过此方法获取用来发送tuples的`OutputCollector`;
- execute:来源于IBolt,处理tuple和发送处理完成的tuple;
- declareOutputFields :来源于IComponent,通过此方法声明发送的tuple的名称,这样下一个组件才能知道如何接受数据。
-## 五、使用案例
+## 五、词频统计案例
+
+### 5.1 案例简介
+
+使用模拟数据进行词频统计。这里我们使用自定义的DataSourceSpout产生模拟数据。实际生产环境中通常是通过日志收集引擎(如Flume、logstash等)将收集到的数据发送到kafka指定的topic,通过storm内置的`KafkaSpout `来监听该topic,并获取数据。
+
+
+
+### 5.2 代码实现
+
+#### 1.DataSourceSpout
+
+```java
+public class DataSourceSpout extends BaseRichSpout {
+
+ private List list = Arrays.asList("Spark", "Hadoop", "HBase", "Storm", "Flink", "Hive");
+
+ private SpoutOutputCollector spoutOutputCollector;
+
+ @Override
+ public void open(Map map, TopologyContext topologyContext, SpoutOutputCollector spoutOutputCollector) {
+ this.spoutOutputCollector = spoutOutputCollector;
+ }
+
+ @Override
+ public void nextTuple() {
+ // 模拟产生数据
+ String lineData = productData();
+ spoutOutputCollector.emit(new Values(lineData));
+ Utils.sleep(1000);
+ }
+
+ @Override
+ public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
+ outputFieldsDeclarer.declare(new Fields("line"));
+ }
+
+
+ /**
+ * 模拟数据
+ */
+ private String productData() {
+ Collections.shuffle(list);
+ Random random = new Random();
+ int endIndex = random.nextInt(list.size()) % (list.size()) + 1;
+ return StringUtils.join(list.toArray(), "\t", 0, endIndex);
+ }
+
+}
+```
+
+上面类使用`productData`方法来产生模拟数据,产生数据的格式如下:
+
+```properties
+Spark HBase
+Hive Flink Storm Hadoop HBase Spark
+Flink
+HBase Storm
+HBase Hadoop Hive Flink
+HBase Flink Hive Storm
+Hive Flink Hadoop
+HBase Hive
+Hadoop Spark HBase Storm
+```
+
+#### 2. SplitBolt
+
+```java
+public class SplitBolt extends BaseRichBolt {
+
+ private OutputCollector collector;
+
+ @Override
+ public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
+ this.collector=collector;
+ }
+
+ @Override
+ public void execute(Tuple input) {
+ String line = input.getStringByField("line");
+ String[] words = line.split("\t");
+ for (String word : words) {
+ collector.emit(new Values(word));
+ }
+ }
+
+ @Override
+ public void declareOutputFields(OutputFieldsDeclarer declarer) {
+ declarer.declare(new Fields("word"));
+ }
+}
+```
+
+#### 3. CountBolt
+
+```java
+public class CountBolt extends BaseRichBolt {
+
+ private Map counts = new HashMap<>();
+
+ @Override
+ public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
+
+ }
+
+ @Override
+ public void execute(Tuple input) {
+ String word = input.getStringByField("word");
+ Integer count = counts.get(word);
+ if (count == null) {
+ count = 0;
+ }
+ count++;
+ counts.put(word, count);
+ // 输出
+ System.out.print("当前实时统计结果:");
+ counts.forEach((key, value) -> System.out.print(key + ":" + value + "; "));
+ System.out.println();
+ }
+
+ @Override
+ public void declareOutputFields(OutputFieldsDeclarer declarer) {
+
+ }
+}
+```
+
+#### 4. WordCountApp
+
+通过TopologyBuilder将上面定义好的组件进行串联形成 Topology,并提交到本地集群(LocalCluster)运行。在通常开发中,可用本地集群进行,测试完成后再提交到服务器集群运行。
+
+```java
+public class WordCountApp{
+
+ public static void main(String[] args) {
+
+ TopologyBuilder builder = new TopologyBuilder();
+
+ builder.setSpout("DataSourceSpout", new DataSourceSpout());
+
+ // 指明将 DataSourceSpout 的数据发送到 SplitBolt 中处理
+ builder.setBolt("SplitBolt", new SplitBolt()).shuffleGrouping("DataSourceSpout");
+
+ // 指明将 SplitBolt 的数据发送到 CountBolt 中 处理
+ builder.setBolt("CountBolt", new CountBolt()).shuffleGrouping("SplitBolt");
+
+ // 创建本地集群用于测试 这种模式不需要本机安装storm,直接运行该Main方法即可
+ LocalCluster cluster = new LocalCluster();
+ cluster.submitTopology("LocalWordCountTopology",
+ new Config(), builder.createTopology());
+ }
+
+}
+```
-## 六、提交到服务器运行
\ No newline at end of file
+#### 5. 运行结果
+
+启动`WordCountApp`的main方法即可运行,采用本地模式storm会自动在本地搭建一个集群,所以启动的过程会稍慢一点,启动成功后即可看到输出日志。
+
+
+
+
+
+## 六、提交到服务器运行
+
diff --git a/pictures/storm-word-count-console.png b/pictures/storm-word-count-console.png
new file mode 100644
index 0000000000000000000000000000000000000000..597110c0eaa17240ea86ffcfdfde660058c81992
GIT binary patch
literal 39558
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
I!kQlc3#R=Mg8%>k
literal 0
HcmV?d00001
diff --git a/pictures/storm-word-count-p.png b/pictures/storm-word-count-p.png
new file mode 100644
index 0000000000000000000000000000000000000000..8b55d17cd7ba7b59278594de9ef4c9da5ad0e82a
GIT binary patch
literal 39514
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