Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

ストリームデータ分散処理基盤Storm

33,791 views

Published on

2012年12月10日
NTTデータ オープンソースDAY 2012 講演資料
『ストリームデータ分散処理基盤 Storm』

NTTデータ 基盤システム事業本部
OSSプロフェッショナルサービス
岩崎 正剛

http://oss.nttdata.co.jp/hadoop/

  • Be the first to comment

ストリームデータ分散処理基盤Storm

  1. 1. Copyright © 2013 NTT DATA CorporationNTT DATA CorporationMasatake Iwasakiストリームデータ分散処理基盤 「Storm」2012年12月10日NTTデータ オープンソースDAY 2012 講演資料
  2. 2. 2Copyright © 2012NTT DATA CorporationIndex1 はじめに2 Stormとは3 ストリームデータ処理4 並列分散フレームワーク5 サーバ構成と耐障害性6 プロセス構成と並行性7 アプリケーション開発8 まとめ
  3. 3. Copyright © 2013 NTT DATA Corporation 3はじめに
  4. 4. 4Copyright © 2013 NTT DATA Corporation自己紹介岩崎 正剛(いわさき まさたけ)株式会社NTTデータ 基盤システム事業本部OSSプロフェッショナルサービスHadoopをはじめとするOSS(オープンソースソフトウエア)製品の技術開発、調査検証、コンサルテーション、サポート、構築支援などに従事。PostgreSQLの全文検索ツール「Ludia」の開発をはじめとして、Hadoop以外のOSSも幅広く扱う。http://oss.nttdata.co.jp/hadoop/
  5. 5. 5Copyright © 2013 NTT DATA Corporation今日の内容Stormの紹介技術的な話が中心Hadoopをある程度知っていることを期待
  6. 6. 6Copyright © 2013 NTT DATA CorporationStormの特徴スケールアウトする分散処理基盤ストリーミングデータ処理に特化リアルタイムでインクリメンタルなデータ処理Hadoopに似ているHadoopよりシンプルSPOFがないMapReduceより柔軟な計算トポロジ
  7. 7. Copyright © 2013 NTT DATA Corporation 7Stormとは
  8. 8. 8Copyright © 2013 NTT DATA CorporationStormストリームデータ分散処理基盤並列分散処理のためのフレームワーク「リアルタイム処理のHadoop」?Similar to how Hadoop provides a set of generalprimitives for doing batch processing, Storm provides aset of general primitives for doing realtime computation.https://github.com/nathanmarz/storm/
  9. 9. 9Copyright © 2013 NTT DATA CorporationHadoopとの併用補完する関係にある。Hadoopvery easy to sort/join/pivot large sets of dataand requires very little work to do so. Does notaddress any real-time needs.Stormsimilar paradigm, but very easy to do real-timehttps://groups.google.com/forum/?fromgroups=#!topic/storm-user/4it768NTvwA
  10. 10. 10Copyright © 2013 NTT DATA CorporationStormの開発者Nathan Marz氏Twitter社(に買収されたBackType社)のエンジニアTwitterデータを分析するサービスを提供していた(=> 2013年3月に会社を設立)https://github.com/nathanmarzhttp://manning.com/marz/
  11. 11. 11Copyright © 2013 NTT DATA CorporationStormの利用事例http://storm-project.net/
  12. 12. 12Copyright © 2013 NTT DATA CorporationStormの利用事例https://github.com/nathanmarz/storm/wiki/Powered-ByGroupon データ結合、クレンジング、正規化The Weather Channel 気象データサービス: データ整形、DB格納FullContactソーシャルデータサービス:外部サービスとのアドレスデータ同期グラフ解析Twitterパートナー向け解析データ提供:Tweetデータ処理、クリックデータ集計Infochimps データ収集/配信サービス: ETLOoyala動画サービス:視聴データ解析、レコメンデーションspider.io インターネットトラフィック解析: 不正検出GumGum 広告プラットフォーム: イベント処理
  13. 13. Copyright © 2013 NTT DATA Corporation 13ストリームデータ処理
  14. 14. 14Copyright © 2013 NTT DATA Corporationストリームデータとはなにか?ストリーム的なデータ連続的に入力されるデータ量が時間的に一定しない保存しきれないほどの量がある例: Tweetデータ、センサデータストリーム的に処理データを溜めずインクリメンタルに集計/抽出/加工
  15. 15. 15Copyright © 2013 NTT DATA CorporationHadoopのストリームデータ処理入力データを分散ファイルシステムに溜めて処理溜めるためのプロダクトが存在Flume, Scribe, Fluentd...バッチ処理短いバッチジョブの繰り返し
  16. 16. 16Copyright © 2013 NTT DATA CorporationStormのストリームデータ処理入力データを溜めずに処理MQを利用する場合が多いKafka, Kestrel, RabbitMQ...イベントドリブン処理常駐ジョブが入力データをインクリメンタルに処理
  17. 17. Copyright © 2013 NTT DATA Corporation 17並列分散処理フレームワーク
  18. 18. 18Copyright © 2013 NTT DATA Corporationフレームワークとはなにか?「枠組み」特定のロジックに従うプログラムの開発/実行基盤ライブラリ: ユーザがライブラリを呼ぶフレームワーク: フレームワークがユーザロジックを呼ぶ型にはめることで共通のパーツが使える型にはめることで変なことをさせない
  19. 19. 19Copyright © 2013 NTT DATA Corporationなぜ並列分散処理のフレームワークが必要なのか並列分散処理のプログラムは書くのが難しいノード間でのデータ交換と同期スケーリングエラー処理並列分散処理のプログラムは動かすのが面倒プログラムとデータの配布、起動と結果の回収エラー時にゴミとして残ったプロセスとデータの消去並列分散処理のプログラムは網羅的なテストができない状況を分散環境で再現すること事態が困難な場合も
  20. 20. 20Copyright © 2013 NTT DATA CorporationHadoopのMapReduceの処理の流れ入力データをタスクに分割入出力はKeyValueの形式で扱うMapは出力をKeyで仕分けてReduceに渡すデータをすべて処理したらジョブは完了MapperMapperMapperin outReducerReducerReducer行番号: テキスト"foo": 3単語: 1(単語に分解)単語: カウント(単語ごとに集計)"foo": 1"bar": 4"baz": 2"foo";: 3"bar": 4"baz": 21000: “foo bar bar”...2000: “bar bar baz”...3000: “foo foo baz”..."bar": 1"bar": 1"baz": 1"foo": 1"baz": 1"bar": 1"bar": 1"foo": 1
  21. 21. 21Copyright © 2013 NTT DATA CorporationMapReduceのフレームワークユーザはMapperとReducerを実装するMapperとReducerはフレームワークが呼び出すそこ以外はフレームワークが世話してくれるプログラムとデータの受け渡し状態の監視エラー時のリトライpublic class Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT> {protected void map(KEYIN key, VALUEIN value,Context context) throws IOException, InterruptedException {public class Reducer<KEYIN,VALUEIN,KEYOUT,VALUEOUT> {protected void reduce(KEYIN key, Iterable<VALUEIN> values, Context context) throws IOException, InterruptedException {
  22. 22. 22Copyright © 2013 NTT DATA Corporation枠組みとしてのMapReduce縛ることでスケーラビリティと開発容易性を保つユーザはロジックとデータの流れの枠組みを変えられない一見厳しい制限にみえる各タスクは他の部分と独立に処理Map -> Reduceの一方通行でも意外といろいろなことができるMapReduceの組みあわせと繰り返し
  23. 23. 23Copyright © 2013 NTT DATA Corporation低レイテンシな並列分散処理の背景MapReduceの繰り返しは効率が悪い何もせず終了するジョブでも1つ数十秒MapReduceジョブ間のデータ受け渡しがHDFSを経由MapReduceとは異なるフレームワークがでてきたグラフ処理: Giraph分散クエリ: ImpalaHadoopプロジェクトもYARNを開発ノード管理部分とアプリケーション管理部分を分離MapReduce以外へも汎用化
  24. 24. 24Copyright © 2013 NTT DATA CorporationStormの処理の流れSpoutは入力データを後続のBoltに流すBoltは入力がきたら随時イベントドリブンで処理HadoopのJob: 与えられたデータセットを処理するバッチ処理StormのTopology: 常駐してイベントドリブン的にデータを処理Bolt ABolt ABolt ABolt BBolt BBolt B行単位に入力foo: 3単語に分割 単語ごとの集計"foo"bar: 4baz: 2{foo: 3,bar: 4,baz: 2}集約“foo bar bar”“bar bar baz”“foo foo baz”"bar""bar""baz""foo""baz"Spout Bolt C"bar""foo""bar"
  25. 25. 25Copyright © 2013 NTT DATA CorporationStormの計算トポロジMapReduceよりも自由度が高いBoltとSpoutの組み合わせの定義はTopologyと呼ばれる入出力はアプリケーション次第Bolt ABolt ABolt CBolt CBolt BSpout ABolt DSpout BSpout BBolt C
  26. 26. 26Copyright © 2013 NTT DATA Corporationデータ入出力データ入力MQからデータを取り込むのが定番スケールアウト可能な製品が好ましいKestrel, Apache Kafka, RabbitMQ...データ出力ストリームとして下流に流す集計結果を永続化KVS, RDBMS, ...
  27. 27. 27Copyright © 2013 NTT DATA CorporationStormのフレームワークユーザはSpoutとBoltを実装するSpoutは無限ループで呼ばれ続け、Tupleを流すBoltはTupleを受け取ったらexecuteを呼び出すpublic interface ISpout extends Serializable {void nextTuple();public interface IBolt extends Serializable {void execute(Tuple input);
  28. 28. 28Copyright © 2013 NTT DATA CorporationStormノード間のデータ受け渡しTupleと呼ばれるデータ構造であつかうフィールド名の付いた値の組public interface Tuple {public int size();public int fieldIndex(String field);public boolean contains(String field);public Object getValue(int i);public String getString(int i);public Integer getInteger(int i);public Long getLong(int i);public Boolean getBoolean(int i);...public Object getValueByField(String field);public String getStringByField(String field);public Integer getIntegerByField(String field);public Long getLongByField(String field);public Boolean getBooleanByField(String field);...public List<Object> getValues();public List<Object> select(Fields selector);...
  29. 29. 29Copyright © 2013 NTT DATA CorporationStormノード間のデータ受け渡し後続のBoltにTupleを渡すpublic class Values extends ArrayList<Object>{public Values() {}public Values(Object... vals) {super(vals.length);for(Object o: vals) {add(o);}}}collector.emit(new Values("foobar", 3, 0.2));Tupleの実体は単に値の組
  30. 30. 30Copyright © 2013 NTT DATA CorporationグルーピングTupleをどの後続Boltに渡すかを決めるロジック同じデータを複数のBoltに渡すこともできるFIELDS: 指定されたフィールドのハッシュ値で振り分けSHUFFLE: ランダムに振り分けALL: すべてのBolt同じTupleを送信DIRECT: 振り分け先のタスクIDを明示的に指定CUSTOM: 振り分けロジックをユーザが実装Bolt ABolt BBolt B
  31. 31. Copyright © 2013 NTT DATA Corporation 31サーバ構成と耐障害性
  32. 32. 32Copyright © 2013 NTT DATA CorporationMasterSlaveTaskTrackerDataNodeMasterNameNodeSlaveTaskTrackerDataNodeJobTrackerSlaveTaskTrackerDataNodeマスタースレーブMapReduceとHDFSの同居がポイントデータ保持ノードにタスクを渡すことで効率的にI/Oを分散Hadoopのサーバ構成
  33. 33. 33Copyright © 2013 NTT DATA CorporationSlaveMasterStormのサーバ構成SlaveSupervisorSlaveSupervisorNimbusSupervisorZooKeeperZooKeeperZooKeeperマスタースレーブ状態管理にZooKeeperクラスタを利用
  34. 34. 34Copyright © 2013 NTT DATA CorporationZooKeeper分散システム開発のためのパーツ小さな分散ファイルシステムディレクトリとファイルの区別がないopen/closeもread/writeもない設定や状態情報を冗長化して保存ロック、キュー、カウンタとしてもノード間のコーディネーションファイルの読み書きの際にWatcherを登録ファイルに変化があるとコールバック
  35. 35. 35Copyright © 2013 NTT DATA CorporationHadoopの対障害性データブロックのレプリカを複数ノードが持つスレーブノードがダウンしたら別ノードでタスクをリトライSlaveDataNodeTaskTrackerdata blockTaskSlaveDataNodeTaskTrackerdata blockTaskSlaveDataNodeTaskTrackerMasterNameNodeMasterJobTracker
  36. 36. 36Copyright © 2013 NTT DATA CorporationMasterSlaveTaskTrackerDataNodeMasterNameNodeSlaveTaskTrackerDataNodeJobTrackerSlaveTaskTrackerDataNodeマスターがSPOF(だった)巨大で重要な管理情報をマスターが(メモリ上に)保持HadoopのSPOFファイルシステムメタデータ登録ジョブと実行状態
  37. 37. 37Copyright © 2013 NTT DATA CorporationSlaveMasterStormのSPOFSlaveSupervisorSlaveSupervisorNimbusSupervisorZooKeeperZooKeeperZooKeeperSPOFなし情報は冗長性のあるZooKeeperクラスタ上に保存Hadoopと違い管理情報が小さくてすむためトポロジと割り当て状態
  38. 38. 38Copyright © 2013 NTT DATA CorporationSlaveMasterStormのマスター障害SlaveSupervisorSlaveSupervisorNimbusSupervisorZooKeeperZooKeeperZooKeeperマスターがいなくてもTopologyは動きつづける単に再起動すればよいマスターダウン中はタスクの(再)割り当てはできない
  39. 39. 39Copyright © 2013 NTT DATA CorporationSlaveMasterStormのスレーブ障害SlaveSupervisorSlaveSupervisorNimbusSupervisorスレーブマシンまたはSupervisorプロセスのクラッシュマスターがスレーブを監視し、タスクを別のノードに移動TaskTaskZooKeeperZooKeeperZooKeeper
  40. 40. 40Copyright © 2013 NTT DATA CorporationSlaveMasterStormのアプリケーションプロセス障害SlaveSupervisorSlaveSupervisorNimbusSupervisorSupervisorがWorkerプロセスを監視して再起動ZooKeeperZooKeeperZooKeeperWorkerWorker
  41. 41. 41Copyright © 2013 NTT DATA CorporationAckを利用したエラー処理SpoutからTupleを流す際にIDを与えておくpublic interface ISpoutOutputCollector {List<Integer> emit(String streamId,List<Object> tuple,Object messageId);public interface ISpout extends Serializable {void ack(Object msgId);void fail(Object msgId);下流のBoltがack/failを呼ぶと、Spoutに伝わるSpout BoltMQ1: キューからデータ取り出し 2: Tupleを流して処理3: 処理が完了したらack失敗したらfail4: ackならキューからの消去をcommitfailならキャンセルしてデータを戻す
  42. 42. 42Copyright © 2013 NTT DATA Corporationノード間通信とZeroMQスレーブ間の通信はWorker単位で管理通信レイヤでの再送や再接続の管理にZeroMQを利用Disrupter(後述)導入後はバッファリングなしの設定に将来的には使わなくなる?https://github.com/nathanmarz/storm/issues/372
  43. 43. 43Copyright © 2013 NTT DATA Corporation並列分散処理における対障害性の考えかた並列分散処理ではエラーは例外的な状況ではない落ちないプログラムではなく、落ちても平気なプログラムフレームワークがかなり面倒をみてくれるでも、アプリケーション側でも意識が必要無限リトライに陥らない一部のエラーで全体を無駄にしない
  44. 44. Copyright © 2013 NTT DATA Corporation 44プロセス構成と並行性
  45. 45. 45Copyright © 2013 NTT DATA CorporationHadoopアプリケーションのプロセス構成TaskTrackerがスロット数までChildプロセスを起動スロット数はCPUコア数を目安に設定適切な並列度はディスクI/OにもよるChildプロセスがタスク(Map/Reduce)を処理SlaveTaskTracker(プロセス)Child(プロセス)TaskChild(プロセス)Task
  46. 46. 46Copyright © 2013 NTT DATA CorporationStormアプリケーションのプロセス構成Supervisorがスロット数までWorkerプロセスを起動WorkerはExecutorスレッドを起動Executorスレッドがタスク(BoltやSpout)を処理Task数 > Executor数にすることも可能SlaveSupervisor(プロセス)Worker(プロセス) Worker(プロセス)Executor(スレッド)TaskTaskExecutor(スレッド)Executor(スレッド)TaskTask
  47. 47. 47Copyright © 2013 NTT DATA Corporation非同期処理とDisruptor処理スレッドと通信スレッドの間をキューで非同期化同じWorker内で動くタスク同士のやり取りにもキューとしてLMAX Disruptorを利用http://lmax-exchange.github.com/disruptor/以前はプロセス内のやりとりにもZeroMQを利用していた性能上重要な部分WorkerExecutorReceiveThreadTransferThreadDisruptorQueueDisruptorQueueExecutorDisruptorQueue
  48. 48. 48Copyright © 2013 NTT DATA Corporationサーバの実装StormはJavaとClojureで実装されているプリミティブなデータ型やインタフェースはJavaで定義Clojureでサーバプロセスを組み上げるClojureLISP系の言語JVM言語マルチスレッドプログラミング向きのパーツを提供
  49. 49. Copyright © 2013 NTT DATA Corporation 49アプリケーション開発
  50. 50. 50Copyright © 2013 NTT DATA CorporationJavaで記述したHadoopアプリケーションMapperの定義Job job = new Job(new Configuration(), "word count");job.setJarByClass(WordCount.class);job.setMapperClass(TokenizerMapper.class);job.setCombinerClass(IntSumReducer.class);job.setReducerClass(IntSumReducer.class);job.setOutputKeyClass(Text.class);job.setOutputValueClass(IntWritable.class);FileInputFormat.addInputPath(job, new Path(otherArgs[0]));FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));job.submit();public static class TokenizerMapperextends Mapper<Object, Text, Text, IntWritable>{private final static IntWritable one = new IntWritable(1);private Text word = new Text();public void map(Object key, Text value, Context context) throws IOException, InterruptedException {StringTokenizer itr = new StringTokenizer(value.toString());while (itr.hasMoreTokens()) {word.set(itr.nextToken());context.write(word, one);}}Jobの定義と起動
  51. 51. 51Copyright © 2013 NTT DATA CorporationJavaで記述したStormアプリケーションBoltの定義TopologyBuilder builder = new TopologyBuilder();builder.setSpout("spout", new RandomSentenceSpout(), 5);builder.setBolt("split", new SplitSentence(), 8).shuffleGrouping("spout");builder.setBolt("count", new WordCount(), 12).fieldsGrouping("split", new Fields("word"));Config conf = new Config();conf.setNumWorkers(3);StormSubmitter.submitTopology(args[0], conf, builder.createTopology());public static class WordCount extends BaseBasicBolt {Map<String, Integer> counts = new HashMap<String, Integer>();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));}Topologyの定義と起動
  52. 52. 52Copyright © 2013 NTT DATA Corporation並列分散処理フレームワークにおけるDSLMapとReduceを書くだけだから開発は簡単だといったな=>あれは嘘だ現実には数多くのMapperやReducerを作って組み合わせそれなりにめんどうくさいDSL(Domain Specific Language)がよく利用されるHadoopではHiveやPigが代表例特定の問題に特化した抽象度の高いプログラミング言語C、Java、Rubyといった汎用言語で実装されるアプリケーション開発の生産性向上のためのツール
  53. 53. 53Copyright © 2013 NTT DATA CorporationTrident典型的なパターンのTopologyを実装するためのAPI射影、結合、集約、分岐、フィルタ、トランザクションSpout/Operation/Partitionの3種のノードでグラフ構造を定義FluentスタイルのAPI呼び出しでアプリケーションを記述(内部DSLに分類される)TridentTopology topology = new TridentTopology();TridentState wordCounts =topology.newStream("spout1", spout).parallelismHint(16).each(new Fields("sentence"), new Split(), new Fields("word")).groupBy(new Fields("word")).persistentAggregate(new MemoryMapState.Factory(),new Count(),new Fields("count")).parallelismHint(16);
  54. 54. 54Copyright © 2013 NTT DATA CorporationClojure DSLコードをClojureで簡潔に記述できる内部DSLClojureのマクロで実装Clojureで書く利点Clojureの機能が使えるパターンマッチング、リスト内包表記、遅延評価、マクロ…並行処理用のパーツはSpoutやBoltでは出番が少なそうDSL的な何かを作ることに定評のあるLISP系言語=>恩恵を受けるのはエンドユーザよりも周辺ツール開発者?
  55. 55. 55Copyright © 2013 NTT DATA CorporationClojure DSLで記述したStormアプリケーションBoltの定義(defn -main([name](StormSubmitter/submitTopologyname{TOPOLOGY-WORKERS 3}(topology{"spout" (spout-spec sentence-spout :p 5)}{"split" (bolt-spec {"spout" :shuffle } split-sentence :p 8)"count" (bolt-spec {"split" ["word"]} word-count:p 12)})))))(defbolt word-count ["word" "count"] {:prepare true}[conf context collector](let [counts (atom {})](bolt(execute [tuple](let [word (.getString tuple 0)](swap! counts (partial merge-with +) {word 1})(emit-bolt! collector [word (@counts word)] :anchor tuple)(ack! collector tuple))))))Topologyの定義と起動
  56. 56. 56Copyright © 2013 NTT DATA CorporationDSLの特徴内部DSL: (Clojure DSL、Tridentはこちら)母体の言語の枠組み上で動く構文上の工夫などで独自言語風にみせる呼び出し方に独自ルールにあるライブラリ?外部DSL: (Hive、Pigはこちら)独自の言語処理系を実装構文解析して構文木をつくり実行自由な構文が定義できる反面:エディタ、デバッガといった開発ツールがない任意のロジックを記述できない(または煩雑)
  57. 57. 57Copyright © 2013 NTT DATA CorporationShellBoltBoltを外部コマンドとして起動標準入出力経由のデータ受け渡しで制御Hadoop Streamingと同じ任意のプログラミング言語でアプリケーションが書ける{"command": "next"}{"command": "emit","id": "12345","stream": "1","task": 3,"tuple": ["foobar", 3, 0.2]}子プロセスに渡すコマンドの例:子プロセスからの返却値の例:
  58. 58. 58Copyright © 2013 NTT DATA Corporationローカル環境でのTopologyの実行分散環境StormSubmitter.submitTopology("word-count",conf,builder.createTopology());LocalCluster cluster = new LocalCluster();cluster.submitTopology("word-count",conf,builder.createTopology());ローカル実行
  59. 59. Copyright © 2013 NTT DATA Corporation 59まとめ
  60. 60. 60Copyright © 2013 NTT DATA CorporationStormのよいところスケール可能な並列分散処理フレームワークHadoopができないストリームデータの逐次処理をカバー対障害性が高いコードベースがコンパクトでシンプル特に巨大なHadoopのコードベースと比較してClojureによる実装読んで楽しい(人による)
  61. 61. 61Copyright © 2013 NTT DATA Corporation大規模データ処理の広がり大規模データ処理にHadoopは広く普及した並列分散処理の開発と運用が実用的に並列分散処理におけるフレームワークの重要性汎用のパーツを再利用複雑さを抑えて(普通の)人間に把握可能にHadoop(MapReduce)以外の選択肢も増えてきた解決すべき問題に応じて使い分け
  62. 62. Copyright © 2011 NTT DATA CorporationCopyright © 2012 NTT DATA Corporation

×