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 SQL - The internal -

2018年10月31日に開催されたNTTデータ テクノロジーカンファレンス2018での講演資料です。

  • Login to see the comments

Spark SQL - The internal -

  1. 1. NTTデータ テクノロジーカンファレンス 2018 © 2018 NTT DATA Corporation Spark SQL - The internal - 2018/10/31 NTT ソフトウェアイノベーションセンタ 山室 健 NTTデータシステム技術本部 土橋 昌
  2. 2. © 2018 NTT DATA Corporation 2 本日のアジェンダ  自己紹介  Apache Sparkの注目したい最近の動向  Spark SQL Deep Dive  Data Source API  Code generation
  3. 3. © 2018 NTT DATA Corporation 3 Who am I? • 所属 – NTTデータ 技術革新統括本部 システム技術本部 方式技術部 • 業務経歴 – 入社以来OSSを用いたシステム開発、研究開発に従事 – 近年は大規模データ処理のための技術を主担当とし、企業の 研究者と連携しながら新しい技術をエンタープライズで用い られるようにする取り組みに多数携わってきた • 登壇・執筆 – Spark Summit、Kafka Summit、 Strata Data Conference、 DataWorks Summit、 Developer Summitなど。 土橋 昌
  4. 4. © 2018 NTT DATA Corporation 4 Who am I? • 2008年4月にNTT研究所入所、今年で 11年目 – 当時はDBMS内部のデータ圧縮・データ 並列化に関する研究に着手 • 現在はOSS開発とそれらの適用支援で 活動中 – Apache Sparkのクエリ処理最適化部を 中心に活動 – Apache HivemallのSpark対応の部分で 協力
  5. 5. © 2018 NTT DATA Corporation 6 本セッションでの共同登壇に関して
  6. 6. © 2018 NTT DATA Corporation 7 (準備)Apache Sparkとは?
  7. 7. © 2018 NTT DATA Corporation 8 Apache Spark(以降Spark)概要 • Apache Spark is a unified analytics engine for large-scale data processing(https://spark.apache.org/) • 2014年にtop-level Apacheプロジェクトになった。2018/10/31 時点の最新バージョンは2.3.2である。 昨年のMatei Zaharia (Sparkの生みの親) の講演より https://www.slideshare.net/databricks/deep- learning-and-streaming-in-apache-spark-2x- with-matei-zaharia- 81232855?from_action=save
  8. 8. © 2018 NTT DATA Corporation 9 Sparkのコンポーネント Spark Summit Europe 2018にて紹介された2015年当時の定義 https://www.slideshare.net/databricks/unifying-stateoftheart-ai-and-big-data-in-apache-spark-with-reynold-xin
  9. 9. © 2018 NTT DATA Corporation 10 Sparkとは?に関する参考情報 • Unifying State-of-the-Art AI and Big Data in Apache Spark with Reynold Xin – https://www.slideshare.net/databricks/unifying-stateoftheart-ai-and- big-data-in-apache-spark-with-reynold-xin – 前半に簡単な歴史も記載されているので、誰かに紹介するときに 便利
  10. 10. © 2018 NTT DATA Corporation 11 Sparkの注目したい最近の動向
  11. 11. © 2018 NTT DATA Corporation 12 本枠の内容について • Spark2.3.0以降の議論の中で注目すべきトピックを(主観的 に…)抽出し、簡単に紹介します。 1. Project Hydrogen ★ 2. Kubernetes対応 ★ 3. Python周りの改善 ★ 4. Data Source周りの対応改善 →主に山室氏の講演参照 5. Structured Streaming関連 →主に昨年度テクノロジカンファレンス猿田氏の講演参照 • https://www.slideshare.net/hadoopxnttdata/structured-streaming- the-internal
  12. 12. © 2018 NTT DATA Corporation 13 Project Hydrogen:背景と現場視点からの考察 大規模データ処理向けの基盤とニューラルネットワーク・機械学習向けの基盤 がそれぞれ存在する世界を打破する https://www.slideshare.net/databricks/project-hydrogen-stateoftheart-deep-learning-on-apache-spark (Xiangrui Meng) 1
  13. 13. © 2018 NTT DATA Corporation 14 Project Hydrogen: 例)Barrier Execution Mode 例えば…Barrier APIを設け、Spark上でギャングスケジューリングを実現する。 タスク間のインタラクションを前提とした分散での学習を実現しやすくする。 https://www.slideshare.net/databricks/project-hydrogen-stateoftheart-deep-learning-on-apache-spark (Xiangrui Meng) 1
  14. 14. © 2018 NTT DATA Corporation 15 Project Hydrogen: 例)Barrier Execution Mode https://jira.apache.org/jira/browse/SPARK-24374 1
  15. 15. © 2018 NTT DATA Corporation 16 Project Hydrogen:参考情報 • Xiangrui Meng による概要説明 – https://www.slideshare.net/databricks/project-hydrogen-stateoftheart- deep-learning-on-apache-spark • SPIP: Barrier Execution Mode – https://jira.apache.org/jira/browse/SPARK-24374 • Barrier Executionのデザインドキュメント – https://jira.apache.org/jira/browse/SPARK-24582 • BarrierTaskContextのデザインドキュメント – https://issues.apache.org/jira/browse/SPARK-24581 1
  16. 16. © 2018 NTT DATA Corporation 17 Kubernetes対応:背景と現場視点からの考察 KubernetesのエコシステムやKubernetes上の異なるワークロードと共存させ る。開発の分断を減らす、オペレーションコストを減らす。 https://issues.apache.org/jira/secure/attachment/12881586/SPARK- 18278%20Spark%20on%20Kubernetes%20Design%20Proposal%20Revisi on%202%20%281%29.pdf https://www.slideshare.net/databricks/apache-spark-on-kubernetes- anirudh-ramanathan-and-tim-chen (Anirudh Ramananathan et al.) https://www.slideshare.net/databricks/apache-spark-on-kubernetes- anirudh-ramanathan-and-tim-chen (Anirudh Ramananathan et al.) 2
  17. 17. © 2018 NTT DATA Corporation 18 Kubernetes対応:スケジューラバックエンドの拡張に関する議論 https://issues.apache.org/jira/browse/SPARK-18278 by Seon Owen by Matt Cheah https://issues.apache.org/jira/browse/SPARK-18278 private[spark] class KubernetesClusterSchedulerBackend( scheduler: TaskSchedulerImpl, rpcEnv: RpcEnv, kubernetesClient: KubernetesClient, requestExecutorsService: ExecutorService, snapshotsStore: ExecutorPodsSnapshotsStore, podAllocator: ExecutorPodsAllocator, lifecycleEventHandler: ExecutorPodsLifecycleManager, watchEvents: ExecutorPodsWatchSnapshotSource, pollEvents: ExecutorPodsPollingSnapshotSource) extends CoarseGrainedSchedulerBackend(scheduler, rpcEnv) { (snip) private[spark] // Yarn only OptionAssigner(args.queue, YARN, ALL_DEPLOY_MODES, confKey = "spark.yarn.queue"), OptionAssigner(args.numExecutors, YARN, ALL_DEPLOY_MODES, confKey = "spark.executor.instances"), OptionAssigner(args.pyFiles, YARN, ALL_DEPLOY_MODES, confKey = "spark.yarn.dist.pyFiles"), OptionAssigner(args.jars, YARN, ALL_DEPLOY_MODES, confKey = "spark.yarn.dist.jars"), OptionAssigner(args.files, YARN, ALL_DEPLOY_MODES, confKey = "spark.yarn.dist.files"), OptionAssigner(args.archives, YARN, ALL_DEPLOY_MODES, confKey = "spark.yarn.dist.archives"), 2
  18. 18. © 2018 NTT DATA Corporation 19 Kubernetes対応:参考情報 • SPIP: Support native submission of spark jobs to a kubernetes cluster – https://issues.apache.org/jira/browse/SPARK-18278 • Apache Spark on Kubernetes, Anirudh Ramanathan and Tim Chen – https://www.slideshare.net/databricks/apache-spark-on-kubernetes- anirudh-ramanathan-and-tim-chen 2
  19. 19. © 2018 NTT DATA Corporation 20 Python周りの改善:背景と現場視点からの考察 1 0 5 10 15 20 25 30 (参考)タイトルレベルでの大まかな分類 arrow udf pandas 性能改善とアプリケーション開発におけるボイラープレート低減 https://www.slideshare.net/SparkSummit/trends-for-big-data-and-apache- spark-in-2017-by-matei-zaharia (Spark Summit East 2017) https://issues.apache.org/jira/browse/SPARK-22216 3
  20. 20. © 2018 NTT DATA Corporation 21 Python周りの改善:例)Pandas UDF https://www.slideshare.net/databricks/vectorized-udf-scalable-analysis-with-python-and-pyspark-with-li-jin 累積分布関数の例 3
  21. 21. © 2018 NTT DATA Corporation 22 Python周りの改善:参考情報 • Improving PySpark/Pandas interoperability – https://issues.apache.org/jira/browse/SPARK-22216 • Complete support for remaining Spark data types in Arrow Converters – https://issues.apache.org/jira/browse/SPARK-21187 • Vectorized UDF: Scalable Analysis with Python and PySpark with Li Jin – https://www.slideshare.net/databricks/vectorized-udf-scalable- analysis-with-python-and-pyspark-with-li-jin 3
  22. 22. © 2018 NTT DATA Corporation 23 Data Source周りの改善:背景と現場視点からの考察 https://issues.apache.org/jira/browse/SPARK-15689 ⇒小さなサーフェースの実現 ⇒カラム型対応の改善 ⇒既存のプッシュダウンは存続 ⇒さらに新しいオペレーションにも対応 4
  23. 23. © 2018 NTT DATA Corporation 24 Data Source周りの改善:例)各種プッシュダウンの定義 https://www.slideshare.net/databricks/apache-spark-data-source-v2-with- wenchen-fan-and-gengliang-wang (Wenchen Fan and Gengliang Wang) @InterfaceStability.Evolving public interface SupportsPushDownFilters extends ScanConfigBuilder { (snip) @InterfaceStability.Evolving public interface ScanConfigBuilder { ScanConfig build(); } ミックスイン 2018/10/27時点のmasterブランチより 4
  24. 24. © 2018 NTT DATA Corporation 25 Data Source周りの改善:参考情報 • SPIP: Standardize SQL logical plans with DataSourceV2 – https://issues.apache.org/jira/browse/SPARK-23521 • Data source API v2 – https://issues.apache.org/jira/browse/SPARK-15689 • Data Source V2 improvements – https://issues.apache.org/jira/browse/SPARK-22386 • Apache Spark Data Source V2 with Wenchen Fan and Gengliang Wang – https://www.slideshare.net/databricks/apache-spark-data-source-v2- with-wenchen-fan-and-gengliang-wang 4
  25. 25. © 2018 NTT DATA Corporation 26 Structured Streaming関連(今回は省略) • SPIP: Continuous Processing Mode for Structured Streaming – https://issues.apache.org/jira/browse/SPARK-20928 • Introducing Low-latency Continuous Processing Mode in Structured Streaming in Apache Spark 2.3 – https://databricks.com/blog/2018/03/20/low-latency-continuous- processing-mode-in-structured-streaming-in-apache-spark-2-3- 0.html 5
  26. 26. © 2018 NTT DATA Corporation 27 続いて山室氏講演
  27. 27. Copyright©2018 NTT corp. All Rights Reserved. SQL - The Internal Takeshi Yamamuro NTT Software Innovation Center Copyright(c)2018 NTT Corp. All Rights Reserved.
  28. 28. 2Copyright©2018 NTT corp. All Rights Reserved. What’s Spark Apache Spark 2015 Year In Review, https://databricks.com/blog/2016/01/05/apache-spark-2015-year-in-review.html • AMPLab/UC Berkeleyの成果を2012年にOSSとし て公開した汎用的な分散処理フレームワーク • 最新はv2.4.0(2018.11.9 released) • 主な特徴はユーザが使いやすいAPI,外部データとの連 携,内部での高度な実行最適化
  29. 29. 3Copyright©2018 NTT corp. All Rights Reserved. • 外部データとの連携 • Sparkが外部データ(CSV/Parquetなどのストレージフォーマ ットやPostgreSQLなどのRDBMS)に対して読み書き・最適化 (e.g., 不要なIOの除去) を実施 • これらを効率的に行うために外部データに対する操作をData Source APIとして抽象化 • 内部での高度な実行最適化 • ユーザやライブラリからの入力(SQL/DataFrame/Dataset) に関係代数的な最適化を行った後,コード生成・実行 • Catalystが一連の実行最適化を担当 What’s Spark
  30. 30. 4Copyright©2018 NTT corp. All Rights Reserved. What’s Spark SQL • RDD(障害を考慮した分散並列計算モデル)による実 行直前までの,入力クエリの分析・最適化とコード生成 を司る構成要素 • RDDはSparkのにおける唯一のデータ操作のためのAPI,現在 はこのAPIを直接ユーザが使用することは非推奨 Sparkの構成要素の概要
  31. 31. 5Copyright©2018 NTT corp. All Rights Reserved. • 前半: Data Source APIに関して • 読み込み処理の具体例を示しながら,Data Sourceの各実装で どのような最適化が内部で実施されているかを俯瞰 • 後半: Catalystでの実行最適化に関して • Catalystの特徴と最適化の具体的な方法,またコード生成によ る高速化に関して俯瞰 Today’s Agenda
  32. 32. 6Copyright©2018 NTT corp. All Rights Reserved. Data Sources API
  33. 33. 7Copyright©2018 NTT corp. All Rights Reserved. • 外部データへの読み書きを抽象化したAPI • 本発表では特に読み込みのみに焦点を当てて紹介 • Spark Built-in Data Source • CSV, JSON, JDBC, Parquet, ORC, and Hive Tables • AVROはv2.4.0からサポート • 3rd Party Data Source • 比較的容易に新規に追加可能 • 実装例: https://github.com/databricks/spark-xml Data Source API
  34. 34. 8Copyright©2018 NTT corp. All Rights Reserved. • シンプル&大半のケースでうまく動くように設計 • Data Source実装に最適化情報(条件句と参照カラム列)を提供 • 結果は行の集合(RDD[Row])として返却 A Design of the API 条件句のCatalyst内部表現参照カラム列 Data Source APIの一部 結果の行集合
  35. 35. 9Copyright©2018 NTT corp. All Rights Reserved. An Example - CSV scala> val df = spark.read.option("inferSchema", true).csv(”/tmp/test.csv”) scala> df.show +---+----+-----+ |_c0| _c1|_c2| +---+----+-----+ | 1| abc| 3.8| +---+----+-----+ scala> df.explain == Physical Plan == *(1) FileScan csv [_c0#39,_c1#40,_c2#41] Batched: false, DataFilters: [], Format: CSV, Location: InMemoryFileIndex[file:/tmp/test.csv], PartitionFilters: [], PushedFilters: [], ReadSchema: struct<_c0:int,_c1:string,_c2:double> scala> df.selectExpr("_c0", "_c1").where("_c0 = 1").explain == Physical Plan == *(1) Project [_c0#39, _c1#40] +- *(1) Filter (isnotnull(_c0#39) && (_c0#39 = 1)) +- *(1) FileScan csv [_c0#39,_c1#40] Batched: false, DataFilters: [isnotnull(_c0#39), (_c0#39 = 1)], Format: CSV, Location: InMemoryFileIndex[file:/tmp/test.csv], PartitionFilters: [], PushedFilters: [IsNotNull(_c0), EqualTo(_c0,1)], ReadSchema: struct<_c0:int,_c1:string> 1, abc, 3.8
  36. 36. 10Copyright©2018 NTT corp. All Rights Reserved. An Example - Parquet scala> val df = spark.read.parquet("/tmp/test.parquet") scala> df.show +---+----+-----+ |_c0| _c1|_c2| +---+----+-----+ | 1| abc| 3.8| +---+----+-----+ scala> df.explain == Physical Plan == *(1) FileScan parquet [_c0#103,_c1#104,_c2#105] Batched: true, DataFilters: [], Format: Parquet, Location: InMemoryFileIndex[file:/tmp/test.parquet], PartitionFilters: [], PushedFilters: [], ReadSchema: struct<_c0:int,_c1:string,_c2:double> scala> df.selectExpr("_c0", "_c1").where("_c0 = 1").explain == Physical Plan == *(1) Project [_c0#103, _c1#104] +- *(1) Filter (isnotnull(_c0#103) && (_c0#103 = 1)) +- *(1) FileScan parquet [_c0#103,_c1#104] Batched: true, DataFilters: [isnotnull(_c0#103), (_c0#103 = 1)], Format: Parquet, Location: InMemoryFileIndex[file:/tmp/test.parquet], PartitionFilters: [], PushedFilters: [IsNotNull(_c0), EqualTo(_c0,1)], ReadSchema: struct<_c0:int,_c1:string>
  37. 37. 11Copyright©2018 NTT corp. All Rights Reserved. An Example - JDBC scala> val df = spark.read.jdbc("jdbc:postgresql:postgres", "test", options) scala> df.show +---+----+-----+ |_c0| _c1|_c2| +---+----+-----+ | 1| abc| 3.8| +---+----+-----+ scala> df.explain == Physical Plan == *(1) Scan JDBCRelation(test) [numPartitions=1] [_c0#22,_c1#23,_c2#24] PushedFilters: [], ReadSchema: struct<_c0:int,_c1:string,_c2:double> scala> df.selectExpr("_c0", "_c1").where("_c0 = 1").explain == Physical Plan == *(1) Scan JDBCRelation(test) [numPartitions=1] [_c0#22,_c1#23] PushedFilters: [*IsNotNull(_c0), *EqualTo(_c0,1)], ReadSchema: struct<_c0:int,_c1:string>
  38. 38. 12Copyright©2018 NTT corp. All Rights Reserved. • 1. Pushed Filters • 2. Read Schema • 3. Filter/Project Plan Pruning • 4. Partition Listing & Filters To Understand Data Source scala> df.selectExpr("_c0", "_c1").where("_c0 = 1").explain == Physical Plan == *(1) Project [_c0#103, _c1#104] +- *(1) Filter (isnotnull(_c0#103) && (_c0#103 = 1)) +- *(1) FileScan parquet [_c0#103,_c1#104] Batched: true, DataFilters: [isnotnull(_c0#103), (_c0#103 = 1)], Format: Parquet, Location: InMemoryFileIndex[file:/tmp/test.parquet], PartitionFilters: [], PushedFilters: [IsNotNull(_c0), EqualTo(_c0,1)], ReadSchema: struct<_c0:int,_c1:string>
  39. 39. 13Copyright©2018 NTT corp. All Rights Reserved. • Data SourceへPush Downされた条件句 • この条件句自体はCatalystの内部表現 • このCatalystの内部表現で表された条件句を活用して 最適化を行うかは実装依存 • CSVは未使用 • ParquetはParquetの内部表現に変換して活用 • JDBCは内部でSQL文のWHERE句にコンパイルして活用 1. Pushed Filters scala> df.selectExpr("_c0", "_c1").where("_c0 = 1").explain == Physical Plan == *(1) Project [_c0#103, _c1#104] +- *(1) Filter (isnotnull(_c0#103) && (_c0#103 = 1)) +- *(1) FileScan parquet [_c0#103,_c1#104] Batched: true, DataFilters: [isnotnull(_c0#103), (_c0#103 = 1)], Format: Parquet, Location: InMemoryFileIndex[file:/tmp/test.parquet], PartitionFilters: [], PushedFilters: [IsNotNull(_c0), EqualTo(_c0,1)], ReadSchema: struct<_c0:int,_c1:string>
  40. 40. 14Copyright©2018 NTT corp. All Rights Reserved. • JDBCRDD#compileFilterがWHERE句に変換 • WHERE ("_c0" IS NOT NULL) AND ("_c0" = 1) 1. Pushed Filters - JDBC scala> df.selectExpr("_c0", "_c1").where("_c0 = 1").explain == Physical Plan == *(1) Scan JDBCRelation(test) [numPartitions=1] [_c0#22,_c1#23] PushedFilters: [*IsNotNull(_c0), *EqualTo(_c0,1)], ReadSchema: struct<_c0:int,_c1:string>
  41. 41. 15Copyright©2018 NTT corp. All Rights Reserved. • 上位の物理プランで参照されるカラム列 • PushedFiltersと同様でこの情報を活用した最適化を 行うかは実装依存 • CSVは内部のパーサ(Univocity)が不要なカラムの処理をバ イパスしてCPU時間を節約するために活用 • Parquetはカラムナ構造であるため不要なIOを除去 • JDBCはSELECT文に参照するカラムを指定 2. Read Schema scala> df.selectExpr("_c0", "_c1").where("_c0 = 1").explain == Physical Plan == *(1) Project [_c0#103, _c1#104] +- *(1) Filter (isnotnull(_c0#103) && (_c0#103 = 1)) +- *(1) FileScan parquet [_c0#103,_c1#104] Batched: true, DataFilters: [isnotnull(_c0#103), (_c0#103 = 1)], Format: Parquet, Location: InMemoryFileIndex[file:/tmp/test.parquet], PartitionFilters: [], PushedFilters: [IsNotNull(_c0), EqualTo(_c0,1)], ReadSchema: struct<_c0:int,_c1:string>
  42. 42. 16Copyright©2018 NTT corp. All Rights Reserved. • 有名なカラムナフォーマット実装の1つ • Sparkでは初期の頃から標準でサポート • カラム方向にデータがストレージ上で連続配置されてい るため,参照しないカラムの読み込みを除去可能 2. Read Schema - Parquet File format, https://github.com/apache/parquet-format Column a Column b R(Column a, Column b)
  43. 43. 17Copyright©2018 NTT corp. All Rights Reserved. • 現状ではJDBCのみが不要な物理ノードを除去 • この最適化がCSV/Parquetで適用されていないのはFileFormat API(Data Source APIの一部)の制約 3. Filter/Project Plan Pruning scala> df.selectExpr("_c0", "_c1").where("_c0 = 1").explain == Physical Plan == // Parquet *(1) Project [_c0#103, _c1#104] +- *(1) Filter (isnotnull(_c0#103) && (_c0#103 = 1)) +- *(1) FileScan parquet [_c0#103,_c1#104] Batched: true, DataFilters: [isnotnull(_c0#103), (_c0#103 = 1)], Format: Parquet, Location: InMemoryFileIndex[file:/tmp/test.parquet], PartitionFilters: [], PushedFilters: [IsNotNull(_c0), EqualTo(_c0,1)], ReadSchema: struct<_c0:int,_c1:string> == Physical Plan ==. // JDBC *(1) Scan JDBCRelation(test) [numPartitions=1] [_c0#22,_c1#23] PushedFilters: [*IsNotNull(_c0), *EqualTo(_c0,1)], ReadSchema: struct<_c0:int,_c1:string> ProjectとFilterが除去
  44. 44. 18Copyright©2018 NTT corp. All Rights Reserved. • CSVやParquetはパーティション分割が可能で,読み 込み時に対象ファイルの列挙が必要 • また読み込みに不要なファイルの除去も可能 4. Partition Listing & Filters scala> val df = spark.range(100).selectExpr("id % 3 AS p", "id”) scala> df.write.partitionBy("p").parquet("/tmp/test.parquet”) scala> df.show(5) +---+---+ | p| id| +---+---+ | 0| 0| | 1| 1| | 2| 2| | 0| 3| | 1| 4| +---+---+ Data Source Table Format
  45. 45. 19Copyright©2018 NTT corp. All Rights Reserved. • CSVやParquetはパーティション分割が可能で,読み 込み時に対象ファイルの列挙が必要 • また読み込みに不要なディレクトリのスキップが可能 4. Partition Listing & Filters scala> spark.read.parquet("/tmp/test.parquet").where("p = 0").explain == Physical Plan == *(1) FileScan parquet [id#45L,p#46] Batched: true, DataFilters: [], Format: Parquet, Location: InMemoryFileIndex[file:/tmp/test.parquet], PartitionCount: 1, PartitionFilters: [isnotnull(p#46), (p#46 = 0)], PushedFilters: [], ReadSchema: struct<id:bigint> このフォルダ以下のファイルのみ読み込み Data Source Table Format
  46. 46. 20Copyright©2018 NTT corp. All Rights Reserved. • Scalable File Listing (v2.1+) • ファイルの列挙処理をSparkクラスタで分散並列化 • v2.0まではドライバで逐次列挙していたため,パーティション が数万以上になるとオーバヘッドが顕在化 • パーティション数が異常に多い場合は,Sparkクラスタ のリソースを食いつぶさないように並列数を制御 4. Partition Listing & Filters Scalable Partition Handling for Cloud-Native Architecture in Apache Spark 2.1, https://databricks.com/blog/2016/12/15/scalable-partition-handling-for- cloud-native-architecture-in-apache-spark-2-1.html
  47. 47. 21Copyright©2018 NTT corp. All Rights Reserved. • 現在コミュニティで開発中のData Source向けの新し いAPI,現状(V1)のAPIの問題点を解決 • org.apache.spark.sql.execution.datasources.v2 • 開発の過程で一貫性がなくなってきたAPIの整理 • FilterだけではなくLimitやAggregateなどの他のプランの Push Downを可能に • 行以外の(e.g., 列)読み込みパタンを考慮した設計 • ... • Iceberg: A fast table format for S3 • https://github.com/Netflix/iceberg • Data Source V2を活用した高速なテーブル表現 • HiveテーブルのO(n)のパーティション列挙を,Icebergテーブ ルではO(1)のメタデータ読み込みに • ここでのnはクエリの処理に必要なパーティション数 WIP: Data Source V2
  48. 48. 22Copyright©2018 NTT corp. All Rights Reserved. Catalyst Optimization
  49. 49. 23Copyright©2018 NTT corp. All Rights Reserved. • Sparkに入力されたクエリを分析,最適な物理プランを 決定してRDDに変換する機構 • 関係代数的な最適化ルール • 新規のプラン書き換えルールの追加が容易 • 物理プランからのコード生成 Catalyst: Extensible Optimizer Framework Spark Catalystの処理フロー概要 最適な物理プランの決定 コード生成
  50. 50. 24Copyright©2018 NTT corp. All Rights Reserved. • 実行順序と実行アルゴリズムの選択 Relational Query Optimization scala> val a = spark.read.parquet(“/tmp/a”) scala> val b = spark.read.parquet(“/tmp/b”) // SELECT * FROM a, b WHERE a.id = b.id AND a.value = 3 scala>a.join(b, “id”, “INNER”).where(“value = 3”) Join Filter 論理プランの候補①: Scan a Scan b Join a.id = b Filter a.value = 3 Scan a Scan b Filter a.value = 3 Join a.id = b 論理プランの候補②:
  51. 51. 25Copyright©2018 NTT corp. All Rights Reserved. • 実行順序と実行アルゴリズムの選択 Relational Query Optimization Scan a Scan b Filter a.value = 3 Join a.id = b 選択された論理プラン: scala> val a = spark.read.parquet(“/tmp/a”) scala> val b = spark.read.parquet(“/tmp/b”) // SELECT * FROM a, b WHERE a.id = b.id AND a.value = 3 scala>a.join(b, “id”, “INNER”).where(“value = 3”) Join Filter
  52. 52. 26Copyright©2018 NTT corp. All Rights Reserved. • 実行順序と実行アルゴリズムの選択 Relational Query Optimization In-Memory Scan b Filtered Scan a w/ a.value = 3 Shuffled Hash Join a.id = b 選択された物理プラン: scala> val a = spark.read.parquet(“/tmp/a”) scala> val b = spark.read.parquet(“/tmp/b”) // SELECT * FROM a, b WHERE a.id = b.id AND a.value = 3 scala>a.join(b, “id”, “INNER”).where(“value = 3”) Join Filter
  53. 53. 27Copyright©2018 NTT corp. All Rights Reserved. • Sparkは内部で関係代数的な評価を行うため,Pandas のDataFrameとNULLの扱いが異なる • Sparkは3値理論におけるNULL NULL Behavior Difference in DataFrame scala> val df = spark.read.option("inferSchema", true).csv("/tmp/test.csv") scala> df.where("_c0 != 1").explain == Physical Plan == *(1) Project [_c0#76, _c1#77, _c2#78] +- *(1) Filter (isnotnull(_c0#76) && NOT (_c0#76 = 1)) +- *(1) FileScan csv [_c0#76,_c1#77,_c2#78] … Isnotnullが自動で挿入
  54. 54. 28Copyright©2018 NTT corp. All Rights Reserved. • Sparkは内部で関係代数的な評価を行うため,Pandas のDataFrameとNULLの扱いが異なる • Sparkは3値理論におけるNULL NULL Behavior Difference in DataFrame scala> sdf.show +----+----+ | _c0| _c1| +----+----+ | 1| a| | 2| b| | | c| +----+----+ scala> sdf.where("_c0 != 1").show +----+----+ | _c0| _c1| +----+----+ | 2| b| +----+----+ null >>> pdf _c0 _c1 0 1.0 a 1 2.0 b 2 NaN c >>> pdf[pdf['_c0'] != 1] 1 2.0 b 2 NaN c Spark DataFrame Pandas DataFrame NULLを含む行は除去
  55. 55. 29Copyright©2018 NTT corp. All Rights Reserved. • コード生成の目的: CPU内の処理の効率化*1 • 仮想関数呼び出しの除去 • 中間データがレジスタに残りやすい処理 • コンパイラによる最適化の享受 • データ並列化,デッドコード削除,共通部分式除去,... Code Generation *1 Everything You Always Wanted to Know About Compiled and Vectorized Queries But Were Afraid to Ask, PVLDB (Vol.11, No.13, 2018) コード生成 レジスタに残りやすく,データ並列化しやすそう
  56. 56. 30Copyright©2018 NTT corp. All Rights Reserved. • 従来のVolcano(Iterator) Styleの実行方式は現代の CPU上で非効率 • 物理プラン間の繰り返しの仮想関数呼び出し • コンパイラによる最適化の余地が限りなく少ない Code Generation 物理プランのFilterノードの実装例 next next next
  57. 57. 31Copyright©2018 NTT corp. All Rights Reserved. • 性能改善の例: Broadcast Hash Join Code Generation
  58. 58. 32Copyright©2018 NTT corp. All Rights Reserved. Future Work & Wrap Up
  59. 59. 33Copyright©2018 NTT corp. All Rights Reserved. • 現状のコード生成機構の課題 • OpenJDKでは単一メソッドのバイトコードのサイズが8KBを超 えると性能劣化が発生するが,現状のSparkでは生成後のバイ トコードのサイズを制御できない • 性能劣化の原因: 生成コードをJITコンパイルできないため • 物理プランの各ノード(Hash JoinやHash Aggregate等)が 直接コードを生成し,文字列の連結でプランに対応したコード を生成するためコード生成中のデバッグが困難 Advanced Topic & Future Work Hash Aggregate Scan Project 現状のSparkのコード生成 (イメージ) Project Java Code コード生成 Hash Agg Java Code コード生成 Scan Java Code コード生成 Generated Plan Code Java Virtual Machine 文字列の連結 Large Java Bytecode 変換 インタプリタモード で実行
  60. 60. 34Copyright©2018 NTT corp. All Rights Reserved. • 現在デザインを議論中: Tungsten IR(仮名) • 物理プランの各ノードがIR(中間表現)を生成・結合した後に プランに対応したコードを生成 • 結合したIRで生成後のバイトコードのサイズを制御 • コード生成を構造化することでデバッグを容易に Advanced Topic & Future Work Hash Aggregate Scan Project IRを活用したコード生成 (イメージ) IR生成 IR生成 IR生成 Generated Plan Code Java Virtual Machine Smaller Java Bytecode 変換 IR結合 コード生成 JIT コンパイル して実行 生成後のバイトコードのサイズを IRの段階で制御
  61. 61. 35Copyright©2018 NTT corp. All Rights Reserved. • Spark SQLは入力されたクエリの実行最適化を行う Sparkにおいて非常に重要な構成要素 • Data Source API • 外部データに対して読み書きと必要な最適化情報を提供するた めのAPI,実際の最適化内容は実装依存 • Catalyst • 関係代数的な最適化,拡張が容易な構造,コード生成などを特 徴とするSpark SQLの心臓部 Wrap Up
  62. 62. © 2018 NTT DATA Corporation 28 本講演のまとめ • Apache Sparkの注目したい最近の動向 – Project Hydrogen、Kubernetes対応、Python周りの改善、Data Source周りの対応改善 – エントリポイントとなる情報の紹介 • Spark SQL Deep Dive – Data Source API – Code generation
  63. 63. © 2018 NTT DATA Corporation

×