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.
Spark Structured Streamingで
Kafkaクラスタのデータをお手軽活用
2017/07/06
Apache Kafka Meetup Japan #3
Kimura, Sotaro(@kimutansk)
https:/...
自己紹介
• Kimura, Sotaro(@kimutansk)
– なんでもやデータエンジニア @ ドワンゴ
• データ分析基盤の管理
• データに関連する雑用係ことなら大体なんでも
– 好きな技術分野
• ストリーム処理(主にJVM上)
...
Spark Structured Streamingとは?
• Spark SQL上でストリーム処理アプリケーションを
簡単に組むためのコンポーネント
– Spark2.1系の時点でα版
– だが、databricksブログでシリーズ投稿等露出...
Spark Structured Streamingとは?
• モダンなストリーム処理の要素を広くカバー
– Out of orderなデータに対応
• Event Timeベースで処理を行うことが可能
• Watermarkにより、許容する遅...
簡単なアプリケーション例
// Sparkアプリケーション生成
val spark = SparkSession
.builder
.appName("StructuredNetworkWordCount")
.getOrCreate()
im...
簡単なアプリケーション例
// 入力データを単語毎に分割
val words = lines.as[String].flatMap(_.split(" "))
// 入力単語毎にカウント
val wordCounts = words.group...
簡単なアプリケーションイメージ
https://spark.apache.org/docs/latest/structured-streaming-programming-guide.html
どうKafkaと連携できるのか?
• spark-sql-kafkaを使用
– 以下の指定でKafkaのデータを取得可能
• Topic + Partition
• Topic
• Topicのパターン(正規表現で指定可能)
– データのメタ情...
どうKafkaと連携できるのか?
• 使用上の注意点
– offsetはSpark側でWALとして管理されるため、
他アプリケーションとConsumerGroupを用いた連携は不可
• 実際必要になることはほぼないとは思いますが
– 大量Top...
実際のアプリケーション例
• 実際に組んでみて、簡単にできたものは?
– ストリーミングETL
• KafkaのTopic名称をデータのスキーマに対応させておけば、
Topicのパターン指定で1アプリケーションで一括処理可能
– 例:以下のTo...
実際のアプリケーション例
// Sparkアプリケーション生成
val sparkSession = SparkSession
.builder
.appName("StreamingETLExample")
.getOrCreate()
//...
実際のアプリケーション例
// データを変換し、グループ分けに必要 or 出力カラムに絞る
import sparkSession.implicits._
val convertedDs =
kafkaDs.selectExpr("topic"...
実際のアプリケーション例
// データ変換結果をHDFSに出力
// 出力ディレクトリパス例は以下
// /data/converted/topic=example_general_action/date=20170706/hour=23
//...
まとめ
• Spark Streaming・Kafka連携は
Structured Streamingで比較的簡単にできる
• 複数のTopicをまとめて読み込めるため、
ストリーミングETLはユースケースとして有望
• ただしα版なので、
A...
Thank you for your attention!
https://www.flickr.com/photos/savannahcorps/7409364642
Upcoming SlideShare
Loading in …5
×

Spark Structured StreamingでKafkaクラスタのデータをお手軽活用

526 views

Published on

Apache Kafka Meetup Japan #3での発表資料です。

Published in: Data & Analytics
  • Be the first to comment

  • Be the first to like this

Spark Structured StreamingでKafkaクラスタのデータをお手軽活用

  1. 1. Spark Structured Streamingで Kafkaクラスタのデータをお手軽活用 2017/07/06 Apache Kafka Meetup Japan #3 Kimura, Sotaro(@kimutansk) https://www.flickr.com/photos/savannahcorps/9256762362
  2. 2. 自己紹介 • Kimura, Sotaro(@kimutansk) – なんでもやデータエンジニア @ ドワンゴ • データ分析基盤の管理 • データに関連する雑用係ことなら大体なんでも – 好きな技術分野 • ストリーム処理(主にJVM上) • 分散システム – 大切だと思うKafkaの設定項目 • advertised.listeners • cleanup.policy • unclean.leader.election.enable
  3. 3. Spark Structured Streamingとは? • Spark SQL上でストリーム処理アプリケーションを 簡単に組むためのコンポーネント – Spark2.1系の時点でα版 – だが、databricksブログでシリーズ投稿等露出は多い – バッチ処理と同様の方法でストリーム処理を記述可能 – Scala/Java/PythonのDataset/DataFrame APIで記述 – Dataset/DataFrameを用いることで 構造化データとして最適化された状態で動作 • メモリ使用量の節約 • ベクトル演算によるCPUリソースの有効活用
  4. 4. Spark Structured Streamingとは? • モダンなストリーム処理の要素を広くカバー – Out of orderなデータに対応 • Event Timeベースで処理を行うことが可能 • Watermarkにより、許容する遅延も設定可能 – Window関数で一定時間ごとにデータを区切って処理可能 • 1分間の区切りで5分間分のデータを処理などの Sliding Windowも利用可能 – Accumulation Mode(Output/Update Mode)も指定可能 • ただし、処理内容で適用可能なモードは限られる – ストリーム処理関連用語は以下の資料参照 • http://niconare.nicovideo.jp/watch/kn2358
  5. 5. 簡単なアプリケーション例 // Sparkアプリケーション生成 val spark = SparkSession .builder .appName("StructuredNetworkWordCount") .getOrCreate() import spark.implicits._ // ローカルポート上にソケットを生成してデータを待ち受け val lines = spark.readStream .format("socket") .option("host", "localhost") .option("port", 9999) .load()
  6. 6. 簡単なアプリケーション例 // 入力データを単語毎に分割 val words = lines.as[String].flatMap(_.split(" ")) // 入力単語毎にカウント val wordCounts = words.groupBy("value").count() // 集計結果を毎回すべてコンソールに出力 val query = wordCounts.writeStream .outputMode("complete") .format("console") .start() // アプリケーションが外部から停止されるまで実行 query.awaitTermination()
  7. 7. 簡単なアプリケーションイメージ https://spark.apache.org/docs/latest/structured-streaming-programming-guide.html
  8. 8. どうKafkaと連携できるのか? • spark-sql-kafkaを使用 – 以下の指定でKafkaのデータを取得可能 • Topic + Partition • Topic • Topicのパターン(正規表現で指定可能) – データのメタ情報も同時に取得するため利用可能 key: binary (nullable = true) value: binary (nullable = true) topic: string (nullable = true) partition: integer (nullable = true) offset: long (nullable = true) timestamp: timestamp (nullable = true) timestampType: integer (nullable = true)
  9. 9. どうKafkaと連携できるのか? • 使用上の注意点 – offsetはSpark側でWALとして管理されるため、 他アプリケーションとConsumerGroupを用いた連携は不可 • 実際必要になることはほぼないとは思いますが – 大量Topicを読むとマイクロバッチ実行時間は長くなる • KafkaのTopic-PartitionがSparkの1Partitionに対応するため • 当たり前ではありますが – まだα版なのでAPIやその他が変わる可能性あり • 個人的にはWALがSparkのバージョンアップで 読めなくならないか、が非常に怖い・・・
  10. 10. 実際のアプリケーション例 • 実際に組んでみて、簡単にできたものは? – ストリーミングETL • KafkaのTopic名称をデータのスキーマに対応させておけば、 Topicのパターン指定で1アプリケーションで一括処理可能 – 例:以下のTopicをリアルタイムで変換してHDFSに投入 – example_distributor_action – example_audience_action – example_general_action • Topic毎に出力ディレクトリを分けたい • 日、時間単位で出力ディレクトリを分けたい • 1分おきに実行したい
  11. 11. 実際のアプリケーション例 // Sparkアプリケーション生成 val sparkSession = SparkSession .builder .appName("StreamingETLExample") .getOrCreate() // example_で始まるKafka Topicを読み込む val kafkaDs = sparkSession.readStream.format("kafka"). option(kafka.bootstrap.servers", "host1:port1,host2:port2,host3:port3"). option("subscribePattern", "example_.*").load() // データの変換関数・時刻の抽出関数をUDFとして設定 val exampleConvertUdf = udf(funcExampleConvert) val extractTimestampUdf = udf(funcExtractTimestamp)
  12. 12. 実際のアプリケーション例 // データを変換し、グループ分けに必要 or 出力カラムに絞る import sparkSession.implicits._ val convertedDs = kafkaDs.selectExpr("topic", "CAST(value AS STRING) as value"). withColumn("converted_value", exampleConvertUdf('value)). withColumn("data_timestamp_str", extractTimestampUdf('value)). withColumn("data_timestamp", unix_timestamp($"data_timestamp_str", "yyyy-MM-dd'T'HH:mm:ssXXX")). withColumn("date", from_unixtime($"data_timestamp", "yyyyMMdd")). withColumn("hour", from_unixtime($"data_timestamp", "HH")). selectExpr("topic", "date", "hour", "converted_value")
  13. 13. 実際のアプリケーション例 // データ変換結果をHDFSに出力 // 出力ディレクトリパス例は以下 // /data/converted/topic=example_general_action/date=20170706/hour=23 // ※実際は出力間隔次第でファイル数が膨れ上がるので注意 convertedDs.toDF().writeStream. trigger(ProcessingTime("60 seconds")). partitionBy("topic", "date", "hour"). outputMode("append"). option("compression", "snappy"). option("checkpointLocation", "/data/checkpoint"). format("parquet"). start("/data/converted").awaitTermination()
  14. 14. まとめ • Spark Streaming・Kafka連携は Structured Streamingで比較的簡単にできる • 複数のTopicをまとめて読み込めるため、 ストリーミングETLはユースケースとして有望 • ただしα版なので、 APIや、WALの形式の変更には注意
  15. 15. Thank you for your attention! https://www.flickr.com/photos/savannahcorps/7409364642

×