一、storm基礎概念
1、什麼是storm
Storm是一個分散式的、高容錯的實時計算系統。
Storm對於實時計算的的意義相當於Hadoop對於批處理的意義。Hadoop為我們提供了Map和Reduce原語,使我們對資料進行批處理變的非常的簡單和優美。同樣,Storm也對資料的實時計算提供了簡單Spout和Bolt原語。
Storm適用的場景:
(1)、流資料處理:Storm可以用來用來處理源源不斷的訊息,並將處理之後的結果儲存到持久化介質中。
(2)、分散式RPC:由於Storm的處理元件都是分散式的,而且處理延遲都極低,所以可以Storm可以做為一個通用的分散式RPC框架使用。
2、入門級程式wordcount
topology:
SentenceSpout.java
public class SentenceSpout extends BaseRichSpout {
private SpoutOutputCollector collector;
private String[] sentences = {
"my dog has fleas",
"i like cold beverages",
"the dog ate my homework",
"don't have a cow man",
"i don't think i like fleas"
};
private int index = 0;
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("sentence"));
}
public void open(Map config, TopologyContext
context, SpoutOutputCollector collector) {
this.collector = collector;
}
public void nextTuple() {
this.collector.emit(new Values(sentences[index]));
index++;
if (index >= sentences.length) {
index = 0;
}
Utils.sleep(1);
}
}
SplitSentenceBolt.java
public class SplitSentenceBolt extends BaseRichBolt {
private OutputCollector collector;
public void prepare(Map config, TopologyContext
context, OutputCollector collector) {
this.collector = collector;
}
public void execute(Tuple tuple) {
String sentence = tuple.getStringByField("sentence");
String[] words = sentence.split(" ");
for(String word : words){
this.collector.emit(new Values(word));
}
}
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("word"));
}
}
WordCountBolt.java
public class WordCountBolt extends BaseRichBolt {
private OutputCollector collector;
private HashMap<String, Long> counts = null;
public void prepare(Map config, TopologyContext
context, OutputCollector collector) {
this.collector = collector;
this.counts = new HashMap<String, Long>();
}
public void execute(Tuple tuple) {
String word = tuple.getStringByField("word");
Long count = this.counts.get(word);
if(count == null){
count = 0L;
}
count++;
this.counts.put(word, count);
this.collector.emit(new Values(word, count));
}
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("word", "count"));
}
}
ReportBolt.java
public class ReportBolt extends BaseRichBolt {
private HashMap<String, Long> counts = null;
public void prepare(Map config, TopologyContext context, OutputCollector collector) {
this.counts = new HashMap<String, Long>();
}
public void execute(Tuple tuple) {
String word = tuple.getStringByField("word");
Long count = tuple.getLongByField("count");
this.counts.put(word, count);
}
public void declareOutputFields(OutputFieldsDeclarer declarer) {
// this bolt does not emit anything
}
public void cleanup() {
System.out.println("--- FINAL COUNTS ---");
List<String> keys = new ArrayList<String>();
keys.addAll(this.counts.keySet());
Collections.sort(keys);
for (String key : keys) {
System.out.println(key + " : " + this.counts.get(key));
}
System.out.println("--------------");
}
}
WordCountTopology.java
public class WordCountTopology {
private static final String SENTENCE_SPOUT_ID = "sentence-spout";
private static final String SPLIT_BOLT_ID = "split-bolt";
private static final String COUNT_BOLT_ID = "count-bolt";
private static final String REPORT_BOLT_ID = "report-bolt";
private static final String TOPOLOGY_NAME = "word-count-topology";
public static void main(String[] args) throws
Exception {
SentenceSpout spout = new SentenceSpout();
SplitSentenceBolt splitBolt = new
SplitSentenceBolt();
WordCountBolt countBolt = new WordCountBolt();
ReportBolt reportBolt = new ReportBolt();
TopologyBuilder builder = new TopologyBuilder();
builder.setSpout(SENTENCE_SPOUT_ID, spout);
// SentenceSpout --> SplitSentenceBolt
builder.setBolt(SPLIT_BOLT_ID, splitBolt).shuffleGrouping(SENTENCE_SPOUT_ID);
// SplitSentenceBolt --> WordCountBolt
builder.setBolt(COUNT_BOLT_ID, countBolt).fieldsGrouping(
SPLIT_BOLT_ID, new Fields("word"));
// WordCountBolt --> ReportBolt
builder.setBolt(REPORT_BOLT_ID, reportBolt).globalGrouping(COUNT_BOLT_ID);
Config config = new Config();
LocalCluster cluster = new LocalCluster();
cluster.submitTopology(TOPOLOGY_NAME, config,
builder.createTopology());
Utils.sleep(10000);
cluster.killTopology(TOPOLOGY_NAME);
cluster.shutdown();
}
}
3、storm叢集結構
4、Topology
一個實時計算應用程式的邏輯在storm裡面被封裝到topology物件裡面, 我把它叫做計算拓補. Storm裡面的topology相當於Hadoop裡面的一個MapReduce Job, 它們的關鍵區別是:一個MapReduce Job最終總是會結束的, 然而一個storm的topoloy會一直執行 — 除非你顯式的殺死它。 一個Topology是Spouts和Bolts組成的圖狀結構,
而連結Spouts和Bolts的則是Stream groupings。
5、spout
噴口(Spout)是拓撲的流的來源,是一個拓撲中產生源資料流的元件。通常情況下,Spout會從外部資料來源(例如Kestrel佇列或Twitter API)中讀取資料,然後轉換為拓撲內部的源資料。Spout可以是可靠的,也可以是不可靠的。如果Storm處理元組失敗,可靠的Spout能夠重新發射,而不可靠的Spout就儘快忘記發出的元組。Spout是一個主動的角色,其介面中有個nextTuple()函式,Storm框架會不停地呼叫此函式,使用者只要在其中生成源資料即可。
Spout的其他主要方法是ack()和fail()。當Storm檢測到一個元組從Spout發出時,ack()和fail()會被呼叫,要麼成功完成通過拓撲,要麼未能完成。ack()和fail()僅被可靠的Spout呼叫。
6、bolt所有的訊息處理邏輯被封裝在bolts裡面。 Bolts可以做很多事情: 過濾, 聚合, 查詢資料庫等等。
Bolts的主要方法是execute, 它以一個tuple作為輸入,Bolts使用OutputCollector來發射tuple, Bolts必須要為它處理的每一個tuple呼叫OutputCollector的ack方法,以通知storm這個tuple被處理完成了。– 從而我們通知這個tuple的發射者Spouts。 一般的流程是: Bolts處理一個輸入tuple, 發射0個或者多個tuple, 然後呼叫ack通知storm自己已經處理過這個tuple了。storm提供了一個IBasicBolt會自動呼叫ack
7、tuple和stream
一個Tuple代表資料流中的一個基本的處理單元,例如一條cookie日誌,它可以包含多個Field,每個Field表示一個屬性。
8、stream groupings
Shuffle Grouping:隨機分組,隨機派發stream裡面的tuple,保證每個bolt接收到的tuple數目相同。
Fields Grouping:按欄位分組,比如按userid來分組,具有同樣userid的tuple會被分到相同的Bolts,而不同的userid則會被分配到不同的Bolts。
All Grouping:廣播傳送,對於每一個tuple,所有的Bolts都會收到。
Global Grouping: 全域性分組,這個tuple被分配到storm中的一個bolt的其中一個task。再具體一點就是分配給id值最低的那個task。
Non Grouping:不分組,這個分組的意思是說stream不關心到底誰會收到它的tuple。目前這種分組和Shuffle grouping是一樣的效果,有一點不同的是storm會把這個bolt放到這個bolt的訂閱者同一個執行緒裡面去執行。
Direct Grouping:直接分組, 這是一種比較特別的分組方法,用這種分組意味著訊息的傳送者指定由訊息接收者的哪個task處理這個訊息。只有被宣告為Direct Stream的訊息流可以宣告這種分組方法。而且這種訊息tuple必須使用emitDirect方法來發射。訊息處理者可以通過TopologyContext來獲取處理它的訊息的taskid (OutputCollector.emit方法也會返回taskid)
Local or shuffle grouping:如果目標bolt有一個或者多個task在同一個工作程式中,tuple將會被隨機發生給這些tasks。否則,和普通的Shuffle Grouping行為一致。
相關文章
- 【Storm篇】--Storm基礎概念ORM
- MySQL(一)基礎概念MySql
- 圖論(一)--基礎概念圖論
- 【譯】Apache Storm系列 之一(核心概念)ApacheORM
- Vue 基礎概念Vue
- MySQL基礎概念MySql
- HTTP基礎概念HTTP
- JVM 基礎概念JVM
- Vue基礎概念Vue
- Elaticsearch基礎概念
- Oracle基礎概念Oracle
- Bamboo基礎概念
- Storm入門指南第一章 基礎知識ORM
- Rxjava2(一)、基礎概念及使用RxJava
- Nestjs入門教程【一】基礎概念JS
- Oracle RAC Cache Fusion 系列一:基礎概念Oracle
- 併發程式設計——基礎概念(一)程式設計
- 深入瞭解Oracle ASM(一):基礎概念OracleASM
- 1章 基礎概念
- java 基礎概念 (1)Java
- JavaScript WebGL 基礎概念JavaScriptWeb
- Elastic Stack基礎概念AST
- ZooKeeper 概念與基礎
- tensorflow基礎概念
- Hadoop 基礎概念Hadoop
- NestJS 基礎概念JS
- python基礎概念Python
- Storm基礎(四)保證訊息處理ORM
- CSS核心概念一把梭-基礎部分CSS
- 產品手記|一些基礎概念
- Java基礎概念知識Java
- RocketMQ基礎概念之BrokerMQ
- Spring 5 基礎概念Spring
- 音視訊基礎概念
- ApacheStorm官方文件——基礎概念ApacheORM
- Python 基礎概念篇Python
- Activiti 基礎概念 筆記筆記
- RAID基礎概念整理AI