20. 8. これまでのStormの使い方
これまでStormは「1Tuple/1Boltずつ処理する」のが前提
ワードカウントも「1Tupleの処理」を各Boltに分散して記述
Word
1文を Count ["the”,2]
Tupleとして送出
単語に分割 ["the”] Bolt
Word
Sentence Split [“cow”]
Spout Bolt Count [“cow”,1]
Bolt
"the cow jumped ・
over the moon“ [“moon”] ・ 単語の発現回数を
・ カウント
・・・
Word
Count [“moon”,1]
Bolt
「複数のTupleに対してこうしてね」という
処理を記述することはできなかった
19
Advanced Tech Night
21. 9. Trident APIとは?
1. Storm0.8.0で追加された、Stormの抽象化API(≒構文糖衣)
① Tridentを用いることにより、
高スループットかつ状態を持つストリーム処理を構築可能
② コンセプトとしては、HadoopにおけるPigやCascadingと同一
2. Boltを意識することなく下記のような処理を作成可能。
① ネットワーク通信を行わないプロセス内で区切った処理の定義
② データの再配分(データの中身は変更しない)
③ データの集計
④ データのグルーピング
⑤ データのマージ/ジョイン
3. インクリメンタルな状態管理を提供
① 1回のバッチ毎に永続化層(DB等)にデータを保存し、
バッチ実行ごとに加算集計することが可能
20
Advanced Tech Night
24. 10. Trident APIで出来るようになったこと
• 【Before】これまでのStormを用いた場合(コンポーネント)
Word
1. 文章を1文ずつ Count ["the”,2]
読みこむ 2. 文章を単語ご
とに分割する ["the”] Bolt
Word
Sentence Split [“cow”]
Spout Bolt Count [“cow”,1]
Bolt
3. 各単語ごとに発
"the cow jumped ・
現回数をカウントす
over the moon“ [“moon”] ・
る
・
・・・
Word
Count [“moon”,1]
Bolt
1処理をSpout/Boltにマッピング
23
Advanced Tech Night
25. 10. Trident APIで出来るようになったこと
• 【After】Trident APIを用いた場合(コンポーネント)
1. 文章を1文ずつ 2. 文章を単語ご 3. 各単語ごとに発現回
読みこむ とに分割する 数をカウントする
["the”]
[“the”,1]
Sentence [“cow”]
Spout Split Count [“cow”,1]
[“moon”]
[“moon”,1]
"the cow jumped
over the moon“
・・・
Spoutは同じく作成
Boltではなく、「関数」をマッピング
24
Advanced Tech Night
26. 10. Trident APIで出来るようになったこと
• 【Before】これまでのStormを用いた場合(Topology定義部分)
// 新規のTopologyを生成
TopologyBuilder builder = new TopologyBuilder();
// Spout を設定
builder.setSpout(“Sentence", new SentenceSpout(), 1);
// Bolt を設定
builder.setBolt(“Split", new SplitBolt(), 1)
.shuffleGrouping(“Sentence");
builder.setBolt(“Word", new WordCountBolt(), 3)
.fieldsGrouping(“Split ",new Fields(“word"));
// Topologyの設定を指定
Config conf = new Config();
conf.setNumWorkers(2);
// TopologyをStormのクラスタへ登録
StormSubmitter.submitTopology(“WordCountTopology", conf, builder.createTopology());
25
Advanced Tech Night
27. 10. Trident APIで出来るようになったこと
• 【After】Trident APIを用いた場合(Topology定義部分)
TridentTopology topology = new TridentTopology();
TridentState wordCounts = topology
.newStream("spout1", spout)
.parallelismHint(1)
.each(new Fields(“sentence”), new Split(), new Fields(“word”)) ★文章を単位に分割★
.groupBy(new Fields(“word”)) ★単語でグルーピング★
.persistentAggregate(new MemoryMapState.Factory(), new Count(),
new Fields(“count”)).
parallelismHint(3); ★単語ごとにカウントし保存★
TopologyはDSLのように
簡易に記述可能!
26
Advanced Tech Night
28. 10. Trident APIで出来るようになったこと
• 【Before】これまでのStormを用いた場合(Spout)
■ SentenceSpout
Sentence
public class RandomSentenceSpout extends BaseRichSpout {
SpoutOutputCollector _collector; Spout
Random _rand;
@Override
public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {
_collector = collector;
_rand = new Random();
}
@Override
public void nextTuple() {
Utils.sleep(100);
String[] sentences = new String[] {
"the cow jumped over the moon“, "an apple a day keeps the doctor away“, "four score and seven years ago",
"snow white and the seven dwarfs“, "i am at two with nature"};
String sentence = sentences[_rand.nextInt(sentences.length)];
_collector.emit(new Values(sentence));
}
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("word"));
}
}
27
Advanced Tech Night
29. 10. Trident APIで出来るようになったこと
• 【After】Trident APIを用いた場合(Spout) Sentence
Spout
FixedBatchSpout spout = new FixedBatchSpout(new Fields("sentence"), 3,
new Values("the cow jumped over the moon"), new Values(
"the man went to the store and bought some candy"),
new Values("four score and seven years ago"), new Values(
"how many apples can you eat"), new Values(
"to be or not to be the person"));
spout.setCycle(true);
28
Advanced Tech Night
30. 10. Trident APIで出来るようになったこと
• 【Before】これまでのStormを用いた場合(Bolt)
Word
■ SplitBolt Split ■WordCountBolt Count
Bolt Bolt
public static class WordCount extends BaseBasicBolt {
Map<String, Integer> counts = new HashMap<String, Integer>();
public class SplitBolt extends BaseBasicBolt {
@Override
@Override
public void execute(Tuple tuple, BasicOutputCollector collector) {
public void execute(Tuple tuple, BasicOutputCollector collector) {
String word = tuple.getString(0);
String sentence = tuple.getString(0);
Integer count = counts.get(word);
for(String word: sentence.split(" ")) {
if(count==null) count = 0;
collector.emit(new Values(word));
count++;
}
counts.put(word, count);
}
collector.emit(new Values(word, count));
}
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
@Override
declarer.declare(new Fields("word"));
public void declareOutputFields(OutputFieldsDeclarer declarer) {
}
declarer.declare(new Fields("word", "count"));
}
}
}
29
Advanced Tech Night
31. 10. Trident APIで出来るようになったこと
• 【After】Trident APIを用いた場合(関数)
Split Count
■ Split ■ Count
public class Count implements CombinerAggregator<Long> {
public static class Split extends BaseFunction { @Override
public Long init(TridentTuple tuple) {
@Override return 1L;
public void execute(TridentTuple tuple, }
TridentCollector collector) {
String sentence = tuple.getString(0); @Override
for (String word : sentence.split(" ")) { public Long combine(Long val1, Long val2) {
collector.emit(new Values(word)); return val1 + val2;
}
}
} @Override
} public Long zero() {
return 0L;
}
}
Boltより小さい「関数」で処理を記述可能!
Boltを考える必要が無くなる!
30
Advanced Tech Night
32. 11. Trident APIサンプル実行デモ
• 下記の構成を持つTrident Topologyのデモを行います。
集計処理
“moon” “moon”
"the cow jumped “moon”
over the moon“ “cow” “cow”
・・・ “cow”
文章入力 単語分割 グルーピング カウント
“moon”, 10 “cow”, 8
結果保存
結果取得処理
“cat” “cat”,5 “cat”,5
DRPC
“dog” “dog”,10 “dog”,10
"cat dog jumped”
空データ 合計算出
単語分割 結果取得
フィルタリング
31
Advanced Tech Night