Storm實戰之WordCount
在storm環境部署完畢,並正確啟動之後,現在就可以真正進入storm開發了,按照慣例,以wordcount作為開始。
這個例子很簡單,核心元件包括:一個spout,兩個bolt,一個Topology。
spout從一個路徑讀取檔案,然後readLine,向bolt發射,一個檔案處理完畢後,重新命名,以不再重複處理。
第一個bolt將從spout接收到的字串按空格split,產生word,發射給下一個bolt。
第二個bolt接收到word後,統計、計數,放到HashMap容器中。
1,定義一個spout,作用是源源不斷滴向bolt發射字串。
2,定義一個bolt,作用是接收spout發過來的字串,並分割成word,發射給下一個bolt。
3,定義一個bolt,接收word,並統計。
注意WordCounter類的prepare方法,裡面定義了一個Thread,持續監控容器的變化(word個數增加或者新增word)。
4,定義一個Topology,提交作業。
5,程式碼完成後,匯出jar(匯出時不要指定Main class),然後上傳至storm叢集,透過命令./storm jar com.x.x.WordCountTopo /data/tianzhen/input 2來提交作業。
Topo啟動,spout、bolt執行過程:
Thread監控的統計結果:
原始檔處理之後被重新命名為*.bak。
和Hadoop不同,在任務執行完之後,Topo不會停止,spout會一直監控資料來源,不停地往bolt發射資料。
所以現在如果源資料發生變化,應該能夠立馬體現出來。我往path下再放一個文字檔案,結果:
可見,結果立刻更新了,storm的實時性就體現在這裡。
這個例子很簡單,核心元件包括:一個spout,兩個bolt,一個Topology。
spout從一個路徑讀取檔案,然後readLine,向bolt發射,一個檔案處理完畢後,重新命名,以不再重複處理。
第一個bolt將從spout接收到的字串按空格split,產生word,發射給下一個bolt。
第二個bolt接收到word後,統計、計數,放到HashMap
1,定義一個spout,作用是源源不斷滴向bolt發射字串。
點選(此處)摺疊或開啟
-
import java.io.File;
-
import java.io.IOException;
-
import java.util.Collection;
-
import java.util.List;
-
import java.util.Map;
-
-
import org.apache.commons.io.FileUtils;
-
import org.apache.commons.io.filefilter.FileFilterUtils;
-
-
import backtype.storm.spout.SpoutOutputCollector;
-
import backtype.storm.task.TopologyContext;
-
import backtype.storm.topology.OutputFieldsDeclarer;
-
import backtype.storm.topology.base.BaseRichSpout;
-
import backtype.storm.tuple.Fields;
-
import backtype.storm.tuple.Values;
-
-
public class WordReader extends BaseRichSpout {
-
private static final long serialVersionUID = 2197521792014017918L;
-
private String inputPath;
-
private SpoutOutputCollector collector;
-
-
@Override
-
@SuppressWarnings(\"rawtypes\")
-
public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {
-
this.collector = collector;
-
inputPath = (String) conf.get(\"INPUT_PATH\");
-
}
-
-
@Override
-
public void nextTuple() {
-
Collection<File> files = FileUtils.listFiles(new File(inputPath),
-
FileFilterUtils.notFileFilter(FileFilterUtils.suffixFileFilter(\".bak\")), null);
-
for (File f : files) {
-
try {
-
List<String> lines = FileUtils.readLines(f, \"UTF-8\");
-
for (String line : lines) {
-
collector.emit(new Values(line));
-
}
-
FileUtils.moveFile(f, new File(f.getPath() + System.currentTimeMillis() + \".bak\"));
-
} catch (IOException e) {
-
e.printStackTrace();
-
}
-
}
-
}
-
-
@Override
-
public void declareOutputFields(OutputFieldsDeclarer declarer) {
-
declarer.declare(new Fields(\"line\"));
-
}
-
- }
2,定義一個bolt,作用是接收spout發過來的字串,並分割成word,發射給下一個bolt。
點選(此處)摺疊或開啟
-
import org.apache.commons.lang.StringUtils;
-
-
import backtype.storm.topology.BasicOutputCollector;
-
import backtype.storm.topology.OutputFieldsDeclarer;
-
import backtype.storm.topology.base.BaseBasicBolt;
-
import backtype.storm.tuple.Fields;
-
import backtype.storm.tuple.Tuple;
-
import backtype.storm.tuple.Values;
-
-
public class WordSpliter extends BaseBasicBolt {
-
-
private static final long serialVersionUID = -5653803832498574866L;
-
-
@Override
-
public void execute(Tuple input, BasicOutputCollector collector) {
-
String line = input.getString(0);
-
String[] words = line.split(\" \");
-
for (String word : words) {
-
word = word.trim();
-
if (StringUtils.isNotBlank(word)) {
-
word = word.toLowerCase();
-
collector.emit(new Values(word));
-
}
-
}
-
}
-
-
@Override
-
public void declareOutputFields(OutputFieldsDeclarer declarer) {
-
declarer.declare(new Fields(\"word\"));
-
-
}
-
- }
3,定義一個bolt,接收word,並統計。
點選(此處)摺疊或開啟
-
import java.util.HashMap;
-
import java.util.Map;
-
import java.util.Map.Entry;
-
-
import backtype.storm.task.TopologyContext;
-
import backtype.storm.topology.BasicOutputCollector;
-
import backtype.storm.topology.OutputFieldsDeclarer;
-
import backtype.storm.topology.base.BaseBasicBolt;
-
import backtype.storm.tuple.Tuple;
-
-
public class WordCounter extends BaseBasicBolt {
-
private static final long serialVersionUID = 5683648523524179434L;
-
private HashMap<String, Integer> counters = new HashMap<String, Integer>();
-
private volatile boolean edit = false;
-
-
@Override
-
@SuppressWarnings(\"rawtypes\")
-
public void prepare(Map stormConf, TopologyContext context) {
-
final long timeOffset = Long.parseLong(stormConf.get(\"TIME_OFFSET\").toString());
-
new Thread(new Runnable() {
-
@Override
-
public void run() {
-
while (true) {
-
if (edit) {
-
for (Entry<String, Integer> entry : counters.entrySet()) {
-
System.out.println(entry.getKey() + \" : \" + entry.getValue());
-
}
-
System.out.println(\"WordCounter---------------------------------------\");
-
edit = false;
-
}
-
try {
-
Thread.sleep(timeOffset * 1000);
-
} catch (InterruptedException e) {
-
e.printStackTrace();
-
}
-
}
-
}
-
}).start();
-
}
-
-
@Override
-
public void execute(Tuple input, BasicOutputCollector collector) {
-
String str = input.getString(0);
-
if (!counters.containsKey(str)) {
-
counters.put(str, 1);
-
} else {
-
Integer c = counters.get(str) + 1;
-
counters.put(str, c);
-
}
-
edit = true;
-
System.out.println(\"WordCounter+++++++++++++++++++++++++++++++++++++++++++\");
-
}
-
-
@Override
-
public void declareOutputFields(OutputFieldsDeclarer declarer) {
-
-
}
- }
4,定義一個Topology,提交作業。
點選(此處)摺疊或開啟
-
public class WordCountTopo {
-
public static void main(String[] args) {
-
if (args.length != 2) {
-
System.err.println(\"Usage: inputPaht timeOffset\");
-
System.err.println(\"such as : java -jar WordCount.jar D://input/ 2\");
-
System.exit(2);
-
}
-
TopologyBuilder builder = new TopologyBuilder();
-
builder.setSpout(\"word-reader\", new WordReader());
-
builder.setBolt(\"word-spilter\", new WordSpliter()).shuffleGrouping(\"word-reader\");
-
builder.setBolt(\"word-counter\", new WordCounter()).shuffleGrouping(\"word-spilter\");
-
String inputPaht = args[0];
-
String timeOffset = args[1];
-
Config conf = new Config();
-
conf.put(\"INPUT_PATH\", inputPaht);
-
conf.put(\"TIME_OFFSET\", timeOffset);
-
conf.setDebug(false);
-
LocalCluster cluster = new LocalCluster();
-
cluster.submitTopology(\"WordCount\", conf, builder.createTopology());
-
}
- }
5,程式碼完成後,匯出jar(匯出時不要指定Main class),然後上傳至storm叢集,透過命令./storm jar com.x.x.WordCountTopo /data/tianzhen/input 2來提交作業。
Topo啟動,spout、bolt執行過程:
Thread監控的統計結果:
原始檔處理之後被重新命名為*.bak。
和Hadoop不同,在任務執行完之後,Topo不會停止,spout會一直監控資料來源,不停地往bolt發射資料。
所以現在如果源資料發生變化,應該能夠立馬體現出來。我往path下再放一個文字檔案,結果:
可見,結果立刻更新了,storm的實時性就體現在這裡。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28912557/viewspace-1450885/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Storm實戰之TopNORM
- Storm的wordcount程式碼編寫與分析ORM
- Kafka實戰-Storm ClusterKafkaORM
- Kafka實戰-Kafka到StormKafkaORM
- 大資料Storm 之RCE實踐大資料ORM
- Storm 實戰:構建大資料實時計算ORM大資料
- HIVE實現wordcount過程Hive
- 《Storm企業級應用:實戰、運維和調優》——第2章開始使用StormORM運維
- Flink 入門篇之 寫個WordCount
- spark之 spark 2.2.0 Standalone安裝、wordCount演示Spark
- Hadoop MapReduce之wordcount(詞頻統計)Hadoop
- 兩個例子(來自Storm實戰 構建大資料實時計算)ORM大資料
- Storm入門之第6章一個實際的例子ORM
- Storm入門之附錄CORM
- hadoop wordcountHadoop
- 【Twitter Storm系列】flume-ng+Kafka+Storm+HDFS 實時系統搭建ORMKafka
- 探索c#之storm的TimeCacheMapC#ORM
- Storm應用系列之——Spout、Bolt APIORMAPI
- Storm應用系列之——Topology部署ORM
- Storm流計算之專案篇(Storm+Kafka+HBase+Highcharts+JQuery,含3個完整實際專案)ORMKafkajQuery
- 《Storm企業級應用:實戰、運維和調優》——2.5 本章小結ORM運維
- 《Storm企業級應用:實戰、運維和調優》——1.6 本章小結ORM運維
- Storm 系列(九)—— Storm 整合 KafkaORMKafka
- 【Storm篇】--Storm基礎概念ORM
- 【Storm篇】--Storm分組策略ORM
- 大資料storm學習之我觀大資料ORM
- 《Storm企業級應用:實戰、運維和調優》——2.1 環境準備ORM運維
- shiro實戰系列(二)之入門實戰續
- 使用IDEA+Maven實現MapReduce的WordCount功能IdeaMaven
- kubebuilder實戰之七:webhookUIWebHook
- Django之MTV實戰(2)Django
- golang實戰之flag包Golang
- 機器學習實戰之開篇機器學習
- Flutter實戰之動畫實現篇Flutter動畫
- Storm系列(六)storm和kafka整合ORMKafka
- 【Storm篇】--Storm併發機制ORM
- 【Storm篇】--Storm 容錯機制ORM
- 使用Hive處理WordCountHive