Date post: | 02-Jul-2015 |
Category: |
Documents |
Upload: | advancedtechnight |
View: | 5,570 times |
Download: | 1 times |
Advanced Tech Night No.05
リアルタイム分散処理フレームワーク Stormの注目の新機能
Trident API
2012/09/20
Acroquest Technology
木村 宗太郎
1
自己紹介
• 名前 : 木村宗太郎
• 所属 : Acroquest Technology
• Twitter : @kimutansk
• 主な仕事:
Androidサービス基盤開発、性能監視システム開発
• 趣味:
料理全般
(特にお菓子作り)
Advanced Tech Night
目次
(A)そもそもStormって何? 1. Stormとは?
2. Stormの6つの特長
3. 類似プロダクトの比較
(B)Stormの機能/構成 4. Stormの論理構成
5. Stormのプロセス構成
6. StreamGrouping
7. Storm実行イメージ
(C)注目の新機能 Trident API 8. これまでのStormの使い方
9. Trident APIとは?
10. Trident APIで
出来るようになったこと
11. Trident API
サンプル実行デモ
Advanced Tech Night
2
そもそもStormって何?
1. Stormとは?
1. 『フォールトトレラントなリアルタイム分散処理フレームワーク』 ※簡単に言うと、 ※「一部で障害が発生しても動き続ける早いフレームワーク」
2. Twitterではつぶやきのリアルタイム解析に利用
元々は、米BackType社が開発
Twitter社がBackType社を買収し、オープンソースとして公開(2011/09/19)
3. 用途は『連続的に発生するデータを、継続的に処理し続ける』
4. コア部分はClojure、コンポーネントはJavaで実装されている。
制御インタフェースはThriftで記述されているため、 他言語からでも操作することが可能。
※Thrift : Facebook社が開発したRPCライブラリ
4
昨日公開1周年!
Advanced Tech Night
2. Stormの6つの特長
1. 幅広いユースケース(Extremely broad set of use cases) • ストリーム処理:メッセージ処理やデータベースのリアルタイム更新
• 継続的な処理:発生し続けるデータを継続的に処理
• 例)Twitterのつぶやき、Web上の新規情報等
• 分散RPC:即座に処理する必要があるクエリを並列処理
2. スケーラブル(Scalable) • 膨大な処理に対してもマシンを追加するだけでスケール可能。
• アプリケーションの特性に依るが、マシンを追加した分線形にスケール。
5
Advanced Tech Night
2. Stormの6つの特長
3. メッセージの処理保証(Guarantees no data loss)
• Stormはメッセージが最後まで処理されるかトレースする
• 処理失敗した場合はメッセージを取得したスレッドに失敗通知が返る
• メッセージ処理保証機構をOFFにして
スピード重視の構成にすることも可能
4. 環境構築の容易性(Extremely robust) • Stormクラスタは「クラスタ」と呼ばれるが、環境構築は非常に容易
• Stormは全クラスタ共通の設定で動作する
• 共通設定を行ったノードを追加するだけでクラスタを拡張可能
6
Advanced Tech Night
2. Stormの6つの特長
5. 耐障害性(Fault-tolerant)
• Stormはメッセージの処理中に障害が発生した場合、
必要に応じて処理プロセスの再起動/再配分を行う。
• Stormはメッセージ処理を継続することを保証する。
6. プログラミング言語非依存(Programming language agnostic)
• StormのTopologyと処理コンポーネントは様々な言語で定義でき、
どんな開発者にとっても利用しやすくなっている。
• (例:Java、Clojure、Scala、Ruby、Python etc)
7
Advanced Tech Night
3. 類似プロダクトとの比較
8
Storm Dempsy S4
処理対象単位 Tuple(専用Entity)
(オブジェクト内包)
オブジェクト オブジェクト
ノードの役割分担 マスタ/スレーブ
(SPOFは無い)
対称 対称
接続関係の定義 プログラム 定義ファイル 定義ファイル
条件定義可能
コンポーネント
実装方法
継承 アノテーション 継承
メッセージ単位の
処理保証
失敗検知有り 失敗検知無し 処理負荷に従い
破棄
Advanced Tech Night
Stormの機能/構成
4. Stormの論理構成
Advanced Tech Night
10
Tuple Tuple Tuple
Spout
Bolt
Topology
Spout & Bolt からなるネットワーク構造
Bolt
4. Stormの論理構成
Tuple
Stream
Spout
Bolt
Topology
Stormで処理されるメッセージを保持するデータのこと。 シリアライズ登録をすることで独自エンティティも利用可能。
Tupleが連続的に流れる経路を意味する。
Streamのソースとなるもので、Tupleを送り出す。 Stormのストリーム処理の起点となる。
Streamの変換処理を行う。 単一、または、複数のStreamからTupleを受信し、
加工した上で、新たなStreamにメッセージを送信する。
Stream、Spout、Boltからなるネットワーク構造のこと。 Stormで処理を実行する場合は、このTopologyの単位でStormクラスタに渡す。
Topologyの構成要素
11
Advanced Tech Night
Stormクラスタ
5. Stormのプロセス構成
12
Nimbus
Zookeeper
Zookeeper
Zookeeper
Supervisor
Worker
Supervisor
Worker
Supervisor
Worker
Supervisor
Worker
1マシンにSupervisor1プロセスと複数のWorkerプロセスが存在
Advanced Tech Night
1ノード
5. Stormのプロセス構成
13
Nimbus
Zookeeper
Supervisor
StormクラスタにおけるMasterノードDaemon •Topologyの起動/終了リクエストの待受け •Workerプロセスへのタスクの割り振り
•Supervisor/Workerプロセスのモニタリング/再配分
NimbusとSupervisor間の協調 •各ノードで動作するDaemonの状態を管理 •Workerへのアサイン等は全てZookeeperを介して行われる
StormクラスタにおけるSlaveノードDaemon •Spout/Boltのアサイン待ち受け •Workerプロセスのモニタリング/起動/停止
Worker
Spout/Boltを実行するプロセス •Topologyのサブセットの実行
(≒Hadoop:JobTracker)
(≒Hadoop:TaskTracker)
(≒Hadoop:Task)
Advanced Tech Night
6. Stream Groupings
Advanced Tech Night
14
Stream
Groupings
Boltが、インプットとして
どのようなStreamを
読み込むかを
指定する定義
Stream
Stream
Stream Groupings
TupleがどのBoltに流れるかを指定
Stream Groupings
Spout → Bolt → Boltの流れと
流れるTupleのグルーピング定義が可能
6. Stream Groupings
15
7種類の Stream Groupings を知る Shuffle grouping
Fields grouping
All grouping
Global grouping
None grouping
Direct grouping
各Boltが等しい数のTupleを受けとるように、Tupleをサイクリックに配分する。
Streamは、グループで指定されたフィールドによって分割される。
同じ値を持つTupleは、必ず同じタスクへ送信される。 (コンシステント・ハッシュ法)
Streamは複製され、すべてのBoltタスクへ送信される。
Stream全体が、ただ一つのBoltタスクへ送信される。
具体的には、Streamは最も小さいIDのタスクへ送信される。
どのようにStreamがグループ化されるか気にしない。
現状このグループは Shuffle grouping と同じである。 だが、Stormは、このグループのBoltを(可能な場合)送信元のBolt
またはSpoutと同じスレッドで実行させる。
Tuple生成者がコンシューマのどのタスクに、Tupleを受けとらせるか決める。
Local or shuffle
grouping 同一Workerに送信先Boltが存在すればそのBoltに送信する。
存在しない場合はShuffle groupingと同じ。 ※同一Worker内の通信時、シリアライズとネットワーク通信が省略されるため、
処理負荷/時間を抑えることが可能。
Advanced Tech Night
7. Stormの実行イメージ
// 新規の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());
Topologyの構築は非常に簡単!(分散処理を、これだけで実現)
Spout、Bolt共に
スレッド数を指定
Worker数を“2”で指定
(Topologyにおいて起動するWorker数)
Spoutの名前 Spoutインスタンス
“Split”のOutputを”word”でGroupingして受信
Topologyの名前
Advanced Tech Night
16
7. Stormの実行イメージ
Advanced Tech Night
17
"the cow jumped
over the moon“
・・・
Sentence
Spout
Split
Bolt
Word
Count
Bolt
Word
Count
Bolt
Word
Count
Bolt
["the”]
[“cow”]
・ ・
・ [“moon”]
1文を Tupleとして
送出
ワードカウントの実行イメージ ["the”,2]
[“cow”,1]
[“moon”,1]
単語に 分割
単語の 発現回数を
カウント
Shuffle
grouping
Fields
grouping
(同じ単語は同じBoltへ送信)
注目の新機能
Trident API
8. これまでのStormの使い方
これまでStormは「1Tuple/1Boltずつ処理する」のが前提
ワードカウントも「1Tupleの処理」を各Boltに分散して記述
Advanced Tech Night
19
"the cow jumped
over the moon“
・・・
Sentence
Spout Split
Bolt
Word
Count
Bolt ["the”]
[“cow”]
・
・
・ [“moon”]
1文を
Tupleとして送出 ["the”,2]
[“cow”,1]
[“moon”,1]
単語に分割
単語の発現回数を
カウント
Word
Count
Bolt
Word
Count
Bolt
「複数のTupleに対してこうしてね」という
処理を記述することはできなかった
9. Trident APIとは?
1. Storm0.8.0で追加された、Stormの抽象化API(≒構文糖衣)
① Tridentを用いることにより、
高スループットかつ状態を持つストリーム処理を構築可能
② コンセプトとしては、HadoopにおけるPigやCascadingと同一
2. Boltを意識することなく下記のような処理を作成可能。
① ネットワーク通信を行わないプロセス内で区切った処理の定義
② データの再配分(データの中身は変更しない)
③ データの集計
④ データのグルーピング
⑤ データのマージ/ジョイン
3. インクリメンタルな状態管理を提供
① 1回のバッチ毎に永続化層(DB等)にデータを保存し、
バッチ実行ごとに加算集計することが可能
Advanced Tech Night
20
9. Trident APIとは?
• Trident Topologyでパーツとして利用できるAPI例
(自作機能を追加することも可能)
Advanced Tech Night
21
分割
(入力データを分割)
グルーピング
(データをグルーピング)
カウント
(発現回数をカウント)
フィルタ
(データをフィルタリング)
集計
(データを集計)
変換
(データを変換)
• これらのパーツを組み合わせたデータの整形/統計が
Stormの機構上で可能になる。
キャッシュ
(データを保持)
ジョイン
(キーベースでジョイン)
10. Trident APIで出来るようになったこと
実現したいことを例に考えてみると・・・
例:ある文書に対するワードカウント
→ ワードカウントは下記の3ステップに分割される。
1. 文章を1文ずつ読みこむ
2. 文章を単語ごとに分割する
3. 各単語ごとに発現回数をカウントする
Advanced Tech Night
22
これをStormで実現するとどうなるか?
10. Trident APIで出来るようになったこと
• 【Before】これまでのStormを用いた場合(コンポーネント)
Advanced Tech Night
23
"the cow jumped
over the moon“
・・・
Sentence
Spout Split
Bolt
Word
Count
Bolt ["the”]
[“cow”]
・
・
・ [“moon”]
1. 文章を1文ずつ
読みこむ ["the”,2]
[“cow”,1]
[“moon”,1]
2. 文章を単語ごとに分割する
3. 各単語ごとに発
現回数をカウントする
Word
Count
Bolt
Word
Count
Bolt
1処理をSpout/Boltにマッピング
10. Trident APIで出来るようになったこと
• 【After】Trident APIを用いた場合(コンポーネント)
Advanced Tech Night
24
"the cow jumped
over the moon“
・・・
Sentence
Spout
["the”]
[“cow”]
[“moon”]
1. 文章を1文ずつ
読みこむ
Split
2. 文章を単語ごとに分割する
3. 各単語ごとに発現回数をカウントする
Count
Spoutは同じく作成
Boltではなく、「関数」をマッピング
[“cow”,1]
[“moon”,1]
[“the”,1]
10. Trident APIで出来るようになったこと
• 【Before】これまでのStormを用いた場合(Topology定義部分)
Advanced Tech Night
25
// 新規の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());
10. Trident APIで出来るようになったこと
• 【After】Trident APIを用いた場合(Topology定義部分)
Advanced Tech Night
26
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のように
簡易に記述可能!
10. Trident APIで出来るようになったこと
• 【Before】これまでのStormを用いた場合(Spout)
Advanced Tech Night
27
public class RandomSentenceSpout extends BaseRichSpout { SpoutOutputCollector _collector;
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"));
}
}
■ SentenceSpout Sentence
Spout
10. Trident APIで出来るようになったこと
Advanced Tech Night
28
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);
• 【After】Trident APIを用いた場合(Spout) Sentence
Spout
10. Trident APIで出来るようになったこと
• 【Before】これまでのStormを用いた場合(Bolt)
Advanced Tech Night
29
public static class WordCount extends BaseBasicBolt { Map<String, Integer> counts = new HashMap<String, Integer>();
@Override
public void execute(Tuple tuple, BasicOutputCollector collector) {
String word = tuple.getString(0); Integer count = counts.get(word);
if(count==null) count = 0;
count++;
counts.put(word, count);
collector.emit(new Values(word, count)); }
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("word", "count")); }
}
■WordCountBolt
public class SplitBolt extends BaseBasicBolt {
@Override
public void execute(Tuple tuple, BasicOutputCollector collector) {
String sentence = tuple.getString(0);
for(String word: sentence.split(" ")) { collector.emit(new Values(word));
}
}
@Override public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("word"));
}
}
■ SplitBolt Split
Bolt
Word
Count
Bolt
10. Trident APIで出来るようになったこと
Advanced Tech Night
30
• 【After】Trident APIを用いた場合(関数)
public static class Split extends BaseFunction {
@Override public void execute(TridentTuple tuple, TridentCollector collector) {
String sentence = tuple.getString(0); for (String word : sentence.split(" ")) {
collector.emit(new Values(word)); } }
}
■ Split
public class Count implements CombinerAggregator<Long> {
@Override
public Long init(TridentTuple tuple) {
return 1L;
}
@Override
public Long combine(Long val1, Long val2) {
return val1 + val2;
}
@Override
public Long zero() {
return 0L;
}
}
■ Count
Boltより小さい「関数」で処理を記述可能!
Boltを考える必要が無くなる!
Split Count
11. Trident APIサンプル実行デモ
• 下記の構成を持つTrident Topologyのデモを行います。
Advanced Tech Night
31
文章入力 単語分割 グルーピング
集計処理
結果取得処理
DRPC
単語分割 結果取得
結果保存
空データ フィルタリング
カウント
"the cow jumped
over the moon“
・・・
合計算出 "cat dog jumped”
“cow”
“moon”
“moon” “moon”
“cow” “cow”
“dog”
“cat”
“dog”,10
“cat”,5
“dog”,10
“cat”,5
“moon”, 10 “cow”, 8
• Demo
まとめ
1. Stormは、
『分散し、フォールトトレラントなリアルタイム処理フレームワーク』
2. 6つの特長
①幅広いユースケース ②スケーラブル
③メッセージの処理保証 ④環境構築の容易性
⑤耐障害性 ⑥プログラミング言語非依存
3. Trident APIの特長
-これまでTuple単位だった処理をTopology全体で実施
-結果データの取得が容易になった
4. Trident APIのパーツ
分割、フィルタ、グルーピング、集計、カウント、変換etc
5. Trident APIを利用することで、統計処理が容易に実装可能
33
Advanced Tech Night
34
Thank you
Try Storm And
Trident!