Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kubernetesで並列分散処理 ~ Apache Spark 入門から Spark K8s Operator まで

Kubernetesで並列分散処理 ~ Apache Spark 入門から Spark K8s Operator まで

Oracle Cloud Hangout Cafe Season 5 #2

2022.02.17 「Kubernetes 上でのジョブ・スケジューリング」スライドを追加
2022.03.02 OCI Object Storage S3互換API についての説明スライドを追加

https://www.youtube.com/watch?v=InKR2ILOdTY

oracle4engineer

February 16, 2022
Tweet

More Decks by oracle4engineer

Other Decks in Technology

Transcript

  1. Kubernetesで並列分散処理 ~ Apache Spark 入門から Spark K8s Operator まで Oracle

    Cloud Hangout Cafe - Season 5 #2 v1.2 Feb 16th, 2022 Tadahisa Kotegawa Senior Director, Solutions Architect Oracle Corporation Japan
  2. 自己紹介 Copyright © 2022 Oracle and/or its affiliates. 3 古手川

    忠久 日本オラクル株式会社 ソリューションアーキテクト本部 @tkotegaw tkote oracle-japan @tkote
  3. 1. Apache Spark の概要 2. ローカル環境で Apache Spark アプリケーションを動かす 3.

    Apache Spark のクラスタ構成 4. Kubernetes 環境で Apache Spark アプリケーションを動かす 5. Spark Operator を使って Apache Spark アプリケーションを動かす 6. 応用:データベースと連携する with Structured Streaming on K8s 7. まとめ Agenda Copyright © 2022 Oracle and/or its affiliates. 4
  4. Oracle Distribution for Hadoop (ODH) の例 「Hadoop エコシステム」 Copyright ©

    2022 Oracle and/or its affiliates. 5 分散処理フレームワークの基盤 • 分散処理フレームワークのMapReduce、 • 分散ファイルシステムのHDFS、 • リソース制御のYARN インメモリ データ処理エンジン SQL、R、Streaming、ML、 Graphなど幅広いライブラリ を擁するデータ処理エンジ ン。SQLとしてはバッチ、アド ホッククエリを両方カバー。 SQLエンジン Hadoop互換ファイルシス テム上のデータに対する SQL操作を提供。高ス ループットを目指すバッチ処 理向き。低レイテンシ指向 の問い合わせはアンチパ ターン。 SQLエンジン MapReduceを使わず、 Hiveではアンチパターン となるアドホックなクエリの レスポンス重視に特化し たSQLエンジン。 RDB連携 HDFSとRDB間でデータのコピー を行うツール。 ジョブ・ワークフロー管理ツール ジョブ設定、実行のワークフロー 制御(実行順序、依存関係)を 行うワークフローエンジン。 クラスタ管理ツール クラスタ内のソフトウェア群のプロビ ジョニング、設定、管理、監視の ツール。Web UIによる管理。 SQLエンジン Oracle DB19c 互換のSQ クエリエンジン。HDFS、 Hive、Oracle NoSQL DB などのデータに対して OracleのSQLでクエリを実 行。 Cloud SQL MapReduce HDFS YARN
  5. Spark処理系をクラウド・ネイティブな環境で実行・管理する方法を探る Apache Spark による分散処理 Copyright © 2022 Oracle and/or its

    affiliates. 6 分散処理フレームワークの基盤 • 分散処理フレームワークのMapReduce • 分散ファイルシステムのHDFS • リソース制御のYARN インメモリ データ処理エンジン SQL、R、Streaming、ML、 Graphなど幅広いライブラリ を擁するデータ処理エンジ ン。SQLとしてはバッチ、アド ホッククエリを両方カバー。 SQLエンジン Hadoop互換ファイルシス テム上のデータに対する SQL操作を提供。高ス ループットを目指すバッチ処 理向き。低レイテンシ指向 の問い合わせはアンチパ ターン。 SQLエンジン MapReduceを使わず、 Hiveではアンチパターン となるアドホックなクエリの レスポンス重視に特化し たSQLエンジン。 RDB連携 HDFSとRDB間でデータのコピー を行うツール。 ジョブ・ワークフロー管理ツール ジョブ設定、実行のワークフロー 制御(実行順序、依存関係)を 行うワークフローエンジン。 クラスタ管理ツール クラスタ内のソフトウェア群のプロビ ジョニング、設定、管理、監視の ツール。Web UIによる管理。 SQLエンジン Oracle DB19c 互換のSQ クエリエンジン。HDFS、 Hive、Oracle NoSQL DB などのデータに対して OracleのSQLでクエリを実 行。 Cloud SQL MapReduce HDFS YARN クラウドで使うなら クラウド・ネイティブな構成にした方が効率的でないか? ファイルシステム → Object Storage を直接使う リソース制御 → Kubernetes の機能を活用する 本日の テーマ
  6. 本日のセッションの最終段階における Apache Spark 稼働環境 Copyright © 2022 Oracle and/or its

    affiliates. 7 Node #1 Node #2 Node #3 Object Storage Bucket Bucket Bucket プログラム / ライブラリ 入力ファイル 出力ファイル Bucket イベント spark-operator spark-history-server default Container Registry driver executor executor Spark Cluster Spark Operator Spark History Server $ spark-submit $ sparkctl OKE Virtual Machine
  7. https://spark.apache.org/ • 巨大なデータに対して高速に分散処理を行うオープンソースのフレームワーク • Scalaで書かれ、クラスタ化されたJVM上で稼働する • Scala と Java のアプリケーションはネイティブに対応

    • Python の実行をサポート (PySpark) → データサイエンス系のソリューションと親和性が高い (注: R にも対応しています) • Spark SQL → 非構造化データをSQLライクに処理できる • Spark Streaming → ストリーミング・データをSQLライクに処理できる (永遠に増え続ける行を持つテーブルを処理) • 機械学習、グラフ Apache Spark Copyright © 2022 Oracle and/or its affiliates. 10 Apache Spark™ is a unified analytics engine for large-scale data processing. 実は多くの Oracle Cloud サービスのベースとなっている! • Big Data Service (Spark のクラスタ環境を提供) • Data Flow (Spark ジョブ実行サービス) • Data Integration (Spark SQL をベースにした ETL) • Stream Analytics (Spark Streaming ベースの GUI リアルタイム分析) • Data Science (PySpark 実行環境を Notebook で提供)
  8. Apache Spark の応用分野 Copyright © 2022 Oracle and/or its affiliates.

    11 IT全般 コマース • 大量データ一括処理、High Performance Computing • ETL処理の代替 • バッチ方式 → ストリーム処理方式によるリアルタイム化 製造業 金融 ヘルスケア • 工場内センサーからのストリーミングデータ収集・分析 • 車載機と連携した各種テレマティクス・サービスの提供 • 設計フェーズにおける各種シミュレーション • アクセスログ、視聴ログ、通信ログの集計・分析 • 機械学習と組み合わせた需要予測 • リアルタイム・リコメンデーション • 顧客リテンション • ゲノム・データの分析 • 医療画像データの分析 • 医療機器、ウェアラブル端末からのデータ処理・解析 • 金融シミュレーション、リスク計算 • 不正検知、アンチ・マネー・ロンダリング などなど…
  9. 2015年米国国内線飛行履歴データ 2015 Flight Delays and Cancellations (https://www.kaggle.com/usdot/flight-delays) • U.S. Department

    of Transportation 提供の public domain データ デモで使うデータセット Copyright © 2022 Oracle and/or its affiliates. 13 flights.csv airlines.csv airports.csv レコード数 5,819,079 14 322 scala> sc.textFile("oci://spark@ochacafe/data/flights.csv").take(5).foreach(println) YEAR,MONTH,DAY,DAY_OF_WEEK,AIRLINE,FLIGHT_NUMBER,TAIL_NUMBER,ORIGIN_AIRPORT,DESTINATION_AIRPORT,SCHEDULED_DEPARTURE,DEPARTURE_TIME,DEPARTURE_DELAY,TAXI_OUT ,WHEELS_OFF,SCHEDULED_TIME,ELAPSED_TIME,AIR_TIME,DISTANCE,WHEELS_ON,TAXI_IN,SCHEDULED_ARRIVAL,ARRIVAL_TIME,ARRIVAL_DELAY,DIVERTED,CANCELLED,CANCELLATION_RE ASON,AIR_SYSTEM_DELAY,SECURITY_DELAY,AIRLINE_DELAY,LATE_AIRCRAFT_DELAY,WEATHER_DELAY 2015,1,1,4,AS,98,N407AS,ANC,SEA,0005,2354,-11,21,0015,205,194,169,1448,0404,4,0430,0408,-22,0,0,,,,,, 2015,1,1,4,AA,2336,N3KUAA,LAX,PBI,0010,0002,-8,12,0014,280,279,263,2330,0737,4,0750,0741,-9,0,0,,,,,, 2015,1,1,4,US,840,N171US,SFO,CLT,0020,0018,-2,16,0034,286,293,266,2296,0800,11,0806,0811,5,0,0,,,,,, 2015,1,1,4,AA,258,N3HYAA,LAX,MIA,0020,0015,-5,15,0030,285,281,258,2342,0748,8,0805,0756,-9,0,0,,,,,, scala> sc.textFile("oci://spark@ochacafe/data/airlines.csv").take(5).foreach(println) IATA_CODE,AIRLINE UA,United Air Lines Inc. AA,American Airlines Inc. US,US Airways Inc. F9,Frontier Airlines Inc. scala> sc.textFile("oci://spark@ochacafe/data/airports.csv").take(5)foreach(println) IATA_CODE,AIRPORT,CITY,STATE,COUNTRY,LATITUDE,LONGITUDE ABE,Lehigh Valley International Airport,Allentown,PA,USA,40.65236,-75.44040 ABI,Abilene Regional Airport,Abilene,TX,USA,32.41132,-99.68190 ABQ,Albuquerque International Sunport,Albuquerque,NM,USA,35.04022,-106.60919 ABR,Aberdeen Regional Airport,Aberdeen,SD,USA,45.44906,-98.42183
  10. Scala で書いた SparkSQL (航空会社別平均到着遅延時間を集計する) Spark アプリケーションのフレーバー… Copyright © 2022 Oracle

    and/or its affiliates. 14 val airlines = spark.read.format("csv").option("header", "true").option("inferSchema", "true") .load(s"oci://${params("input_bucket")}@${params("namespace")}/airlines.csv") .select(col("IATA_CODE"), col("AIRLINE").alias("AIRLINE_NAME")) val flights = spark.read.format("csv").option("header", "true").option("inferSchema", "true") .load(s"oci://${params("input_bucket")}@${params("namespace")}/flights.csv") val avg_arrival_delay = flights.groupBy("AIRLINE") .agg(count(col("AIRLINE")).alias("FLIGHTS_COUNT"), avg(col("ARRIVAL_DELAY")).alias("AVG_ARRIVAL_DELAY")) .withColumn("AVG_ARRIVAL_DELAY_BY_MINUTES", format_number(col("AVG_ARRIVAL_DELAY"), 2)) .join(airlines, flights.col("AIRLINE") === airlines.col("IATA_CODE"), "left") .coalesce(1) .sortWithinPartitions("AVG_ARRIVAL_DELAY") .select(col("AIRLINE_NAME"), col("FLIGHTS_COUNT"), col("AVG_ARRIVAL_DELAY_BY_MINUTES")) avg_arrival_delay.write.format(params("output_format")).mode("overwrite") .save(s"oci://${params("output_bucket")}@${params("namespace")}/avg_arrival_delay_by_airline") CSVファイルに対して SQL処理をかけるように プログラムが書ける airlines.csv 読み込み flights.csv 読み込み 集計 left join ソート json 書き込み avg join sort avg.json プログラム flights.csv airlines.csv
  11. 同じ処理を SQL 文でも記述できる +--------------------+-------------+-------------------+ | AIRLINE_NAME|FLIGHTS_COUNT| AVG_ARRIVAL_DELAY| +--------------------+-------------+-------------------+ |Alaska Airlines

    Inc.| 172521|-0.9765630924118783| |Delta Air Lines Inc.| 875881|0.18675361236390797| |Hawaiian Airlines...| 76272| 2.023092805197196| ... 途中略 ... | JetBlue Airways| 267048| 6.677860800940307| |Frontier Airlines...| 90836| 12.504706404706404| | Spirit Air Lines| 117379| 14.471799501705833| +--------------------+-------------+-------------------+ Spark アプリケーションのフレーバー… 続き Copyright © 2022 Oracle and/or its affiliates. 15 airlines.createOrReplaceTempView("AIRLINES") flights.createOrReplaceTempView("FLIGHTS") val avg_arrival_delay = spark.sql(""" SELECT first(a.AIRLINE_NAME) AS AIRLINE_NAME, count(f.AIRLINE) as FLIGHTS_COUNT, avg(f.ARRIVAL_DELAY) as AVG_ARRIVAL_DELAY FROM FLIGHTS as f LEFT JOIN AIRLINES as a ON f.AIRLINE = a.IATA_CODE GROUP BY f.AIRLINE ORDER BY AVG_ARRIVAL_DELAY """) avg_arrival_delay.show()
  12. 予め準備しておくもの:Java の実行環境 (8 or 11 - Sparkバージョン依存) 手順 • https://spark.apache.org/downloads.html

    からダウンロード & 展開 • ./bin/spark-shell を動かして動作確認 Apache Spark のローカル環境へのインストール Copyright © 2022 Oracle and/or its affiliates. 16 $ wget --no-check-certificate https://.../spark-3.2.1-bin-hadoop2.7.tgz $ tar xvf spark2.1-bin-hadoop2.7.tgz $ ./spark-3.2.1-bin-hadoop2.7/bin/spark-shell -3. Setting default log level to "WARN". To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel). 22/01/06 12:18:52 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable Spark context Web UI available at http://instance.regionalsubnet.vcn.oraclevcn.com:4040 Spark context available as 'sc' (master = local[*], app id = local-1641439134355). Spark session available as 'spark'. Welcome to ____ __ / __/__ ___ _____/ /__ _¥ ¥/ _ ¥/ _ `/ __/ '_/ /___/ .__/¥_,_/_/ /_/¥_¥ version 3.2.1 /_/ Using Scala version 2.12.15 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_241) Type in expressions to have them evaluated. Type :help for more information. scala> $ tree -d -L 1 . . ├── bin ├── conf ├── data ├── examples ├── jars ├── kubernetes ├── licenses ├── logs ├── metastore_db ├── python ├── R ├── sbin └── yarn
  13. アプリケーションとしてパッケージされたものを実行するためのシェルスクリプト 基本形 Spark アプリケーションの実行 – spark-submit Copyright © 2022 Oracle

    and/or its affiliates. 17 ./bin/spark-submit ¥ --class <main-class> ¥ --master <master-url> ¥ --deploy-mode <deploy-mode> ¥ --conf <key>=<value> ¥ ... # other options <application-jar> ¥ [application-arguments] $SPARK_HOME/bin/spark-submit ¥ --master local[*] ¥ --deploy-mode client ¥ --class org.apache.spark.examples.SparkPi ¥ --name spark-pi ¥ $SPARK_HOME/examples/jars/spark-examples_2.12-3.2.1.jar サンプル・アプリケーション(モンテカルロ法でだいたいの円周率を求める)をローカルで実行 --master と –deploy-mode は クラスタ構成の章で解説します
  14. Apache Hadoop/Spark から OCI Object Storage のデータの読取りと書込みを可能にする オープン・ソースで提供 • github.com/oracle/oci-hdfs-connector

    URIフォーマットのスキーム = “oci” • バケット (ルート) → oci://bucket@namespace/ • オブジェクト → oci://bucket@namespace/some/directory/object.json APIキー認証の他に、インスタンス・プリンシパル&リソース・プリンシパルに対応 • APIキーの管理が不要、動的グループに対して権限付与することが可能 Oracle Cloud Infrastructure HDFS Connector for Object Storage Copyright © 2022 Oracle and/or its affiliates. 18 HDFS(Hadoop Distributed File System) • 仮想的な分散ファイル・システム • Hadoopエコシステムの基本となる入出力インターフェース • Spark では "hdfs://~" で読み書きする HDFS コネクタ • URIスキームを拡張してHDFS以外のファイルシステムをHDFSと同一のAPIで利用できるようにしたもの • クラウド各社の Object Storage 用のコネクタが提供されている "oci://~", "s3a://~" file system node file system node file system node HDFS
  15. Object Storage がファイルシステムのように扱える! (参考) Hadoop に HDFS Connector を入れて HDFS

    シェルコマンドを使う Copyright © 2022 Oracle and/or its affiliates. 19 $ $HADOOP_HOME/bin/hadoop fs -ls oci://spark@ochacafe/ Found 4 items drwxrwxrwx - 0 1970-01-01 09:00 oci://spark@ochacafe/data drwxrwxrwx - 0 1970-01-01 09:00 oci://spark@ochacafe/history drwxrwxrwx - 0 1970-01-01 09:00 oci://spark@ochacafe/lib drwxrwxrwx - 0 1970-01-01 09:00 oci://spark@ochacafe/out $ $HADOOP_HOME/bin/hadoop fs -ls oci://spark@ochacafe/data Found 3 items -rw-rw-rw- 1 359 2021-12-08 17:41 oci://spark@ochacafe/data/airlines.csv -rw-rw-rw- 1 23867 2021-12-08 17:41 oci://spark@ochacafe/data/airports.csv -rw-rw-rw- 1 592406591 2021-12-08 17:41 oci://spark@ochacafe/data/flights.csv $ $HADOOP_HOME/bin/hadoop fs -cp oci://spark@ochacafe/data oci://spark@ochacafe/backup $ $HADOOP_HOME/bin/hadoop fs -ls oci://spark@ochacafe/ Found 5 items drwxrwxrwx - 0 1970-01-01 09:00 oci://spark@ochacafe/backup drwxrwxrwx - 0 1970-01-01 09:00 oci://spark@ochacafe/data drwxrwxrwx - 0 1970-01-01 09:00 oci://spark@ochacafe/history drwxrwxrwx - 0 1970-01-01 09:00 oci://spark@ochacafe/lib drwxrwxrwx - 0 1970-01-01 09:00 oci://spark@ochacafe/out $ $HADOOP_HOME/bin/hadoop fs -rm -r -f oci://spark@ochacafe/backup Deleted oci://spark@ochacafe/backup ディレクトリ コピーが簡単にできる!
  16. Spark へのインストール ドキュメンテーション 「Sparkでの HDFS コネクタの使用」 のやり方でもいいのですが… • HDFS Connector

    のライブラリ (jar) を準備 (spark-submit 時の引数で指定) • $SPARK_HOME/conf/core-site.xml を作成 & OCI 接続情報を追加 • $SPARK_HOME/conf/spark-defaults.conf に設定を追加 spark-defaults.conf には HADOOP の設定も入れられるので、 core-site.xml は不要 • spark.hadoop.~=xxx でOK ⇒ core-site.xml の設定もここに集約可能 オレ流インストール手順 • HDFS Connector のライブラリ (jar) を $SPARK_HOME/jars にコピー (この方が色々と好都合) • $SPARK_HOME/conf/spark-defaults.conf に設定を追加 Oracle Cloud Infrastructure HDFS Connector for Object Storage Copyright © 2022 Oracle and/or its affiliates. 20 spark.sql.hive.metastore.sharedPrefixes=shaded.oracle,com.oracle.bmc spark.hadoop.fs.oci.client.hostname=https://objectstorage.us-ashburn-1.oraclecloud.com spark.hadoop.fs.oci.client.custom.authenticator=com.oracle.bmc.hdfs.auth.InstancePrincipalsCustomAuthenticator “oci:”を使う Object Storage のエンドポイント インスタンス・プリンシパルで認証
  17. OCI の Object Storage は S3 互換 API を提供しているけど… Sparkでも

    s3a://<バケット名>/~ で Object Storageへのアクセスは可能 • 必要な jar → hadoop-aws-x.x.x.jar, aws-java-sdk-bundle-x.xx.xxx.jar • spark-defaults.conf の設定 S3 互換 API の制限 • 認証方式が限られる → アクセス・キー & シークレット・キー • OCI HDFS Connector であれば、ユーザ・プリンシパル、インスタンス・プリンシパル、リソース・プリンシパル が利用できる • アクセス範囲が限られる → テナンシーで指定した単一のコンパートメントのみ • OCI HDFS Connector なら、OCIのポリシーを使ってテナンシー内のバケットに自由にアクセス/制御できる 21 Copyright © 2022 Oracle and/or its affiliates. spark.hadoop.fs.s3a.access.key= spark.hadoop.fs.s3a.secret.key= spark.hadoop.fs.s3a.aws.credentials.provider=org.apache.hadoop.fs.s3a.SimpleAWSCredentialsProvider spark.hadoop.fs.s3a.endpoint=https://<namespace>.compat.objectstorage.<region>.oraclecloud.com spark.hadoop.fs.s3a.path.style.access=true spark-defaults.conf の設定
  18. Copyright © 2022 Oracle and/or its affiliates. 22 デモ ローカル環境で

    Spark アプリケーションを実行する Object Storage Bucket Bucket Bucket プログラム / ライブラリ 入力ファイル 出力ファイル Local VM $ spark-submit
  19. airports.csv を読み込んで、州別の飛行場数を集計する ローカルのJVMでSparkを起動 データファイルはObject Storage 上に存在 ローカル環境で Spark アプリケーションを実行する Copyright

    © 2022 Oracle and/or its affiliates. 23 $ $SPARK_HOME/bin/spark-submit ¥ --master local[*] ¥ --deploy-mode client ¥ --name num_airports_by_state ¥ --class com.example.demo.NumAirportsByState ¥ target/scala-2.12/us-flights-app_2.12-0.1.jar ¥ --input_file oci://spark@ochacafe/data/airports.csv ¥ --output_file oci://spark@ochacafe/out/num_airports_by_state ¥ --show_summary true input_file=oci://spark@ochacafe/data/airports.csv, output_file=oci://spark@ochacafe/out/num_airports_by_state, output_format=json, show_summary=true +-----+-----+ |STATE|COUNT| +-----+-----+ | TX| 24| | CA| 22| | AK| 19| ... 途中略 ... | WY| 6| | AL| 5| +-----+-----+ only showing top 20 rows Elapsed time(sec): 20.676
  20. Spark のアプリケーションはこんなお作法 アプリケーションのソース (NumAirportsByState.scala) Copyright © 2022 Oracle and/or its

    affiliates. 24 package com.example.demo import org.apache.spark.sql.SparkSession import org.apache.spark.sql.functions._ object NumAirportsByState { def main(args: Array[String]): Unit = { val params = parseArgs(args) // 引数を解析 val spark = SparkSession.builder().appName("num_airports_by_state").getOrCreate() // Spark セッションを開始 spark .read.format("csv").option("header", "true").option("inferSchema", "true").load(params("input_file")) // ファイルを読み込み .groupBy("STATE").agg(count(col("STATE")).alias("COUNT")) // 集計 .coalesce(1).sortWithinPartitions(col("COUNT").desc, col("STATE")) // ソート .write.format(params("output_format")).mode("overwrite").save(params("output_file")) // ファイルに書き込み spark.close() // Spark セッションを終了 } def parseArgs(args: Array[String]): scala.collection.mutable.Map[String, String] = { ... 省略 ... } }
  21. spark-shell / pyspark / Notebook (Zeppelin, Jupyter) Spark 標準装備の REPL

    環境 Notebook ⇒ 作成したプログラムを実行し、実行結果を記録しながら、データの分析作業を進めるためのツール Spark アプリケーションの実行 – インタラクティブ (試行錯誤) な開発スタイルもOK Copyright © 2022 Oracle and/or its affiliates. 25 コマンド 機能 spark-shell ($SPARK_HOME/bin/spark-shell) Scala インタープリタ pyspark ($SPARK_HOME/bin/pyspark) Python インタープリタ コマンド 機能 対応言語 Apache Zeppelin 汎用 Notebook 環境 Scala, PySpark, SparkR, SparkSql Jupyter Notebook Python に特化した高機能 Notebook PySpark
  22. Apache Zeppelin 設定 Tips • zeppelin-env.sh 内で HDFS Connector が設定済みの

    SPARK_HOME をエクスポートすればOK! OCI Data Science (Jupyter Notebook) 設定 Tips • HDFS Connector と Oracle JDBC Driver のライブラリは あらかじめ設定済み (~/spark_conf_dir に設定ファイルあり) • リソース・プリンシパルで認証可能 (core-site.xmlで指定) Notebook 環境から Object Storage を使う Copyright © 2022 Oracle and/or its affiliates. 26
  23. ドライバ • Spark の処理命令 (RDDの生成、変換など) を制御 するプロセス • データローカリティを考慮し、エグゼキュータ上のタスク 生成、タスクスケジューリングを行う

    エグゼキュータ • ワーカーノードで起動され、実際の処理を実行するプ ロセス • タスクに分割され各パーティションに対する処理を行い、 結果をドライバ返す クラスタ・マネージャ • クラスタ内のリソース管理 • Standalone、YARN、MESOS、Kubernetes などが利用可 Spark の処理アーキテクチャ Copyright © 2022 Oracle and/or its affiliates. 28 クラスタ マネージャ Executor Task Partition Partition Task Partition Partition Filter/Map/Reduce Executor Task Partition Partition Task Partition Partition Filter/Map/Reduce エグゼキュータ Task Partition Partition Task Partition Partition Filter/Map/Reduce ドライバ Executor Task Partition Partition Task Partition Partition Filter/Map/Reduce Executor Task Partition Partition Task Partition Partition Filter/Map/Reduce エグゼキュータ Task Partition Partition Task Partition Partition Filter/Map/Reduce
  24. 利用可能なクラスタ・マネージャ spark-submit の --master オプションでアプリケーションの実行先を切り替えることができる クラスタ・マネージャ Copyright © 2022 Oracle

    and/or its affiliates. 29 クラスタ・マネージャ 概要 スタンドアロン Spark に同梱されているシンプルなクラスタ・マネージャ Apache Mesos (非推奨) Hadoop YARN Hadoop2 のリソース・マネージャ Kubernetes コンテナ化されたアプリケーションの運用管理自動化を行うオープンソースシステム --master 概要 local ([*],[K],[K,F],[*,F]) ローカル実行, K=ワーカースレッド数(*=実行マシンの論理コア数), F=実行中止に達するタスク失敗数 local-cluster[N,C,M] 単体テスト用途で、単一JVM上で N ワーカー、C コア、M MiBメモリーのクラスタ環境をエミュレート spark://HOST:PORT スタンドアロン クラスタのマネージャに接続 spark://HOST1:PORT1,HOST2:PORT2 ZooKeeper を使ったマルチ・マスタースタンドアロン クラスタに接続 yarn YARN クラスタに接続 k8s://HOST:PORT Kubernetes クラスタ (API Server) に接続
  25. ドライバーをワーカーノードにデプロイするか、または外部クライアントとしてローカルにデプロイするか --deploy-mode client (デフォルト) --deploy-mode cluster デプロイ・モード ( --deploy-mode )

    Copyright © 2022 Oracle and/or its affiliates. 30 ドライバ エグゼキュータ エグゼキュータ local machine Spark クラスタ ドライバ エグゼキュータ エグゼキュータ local machine Spark クラスタ アプリ 計算処理 計算処理 計算処理 計算処理 アプリ $ spark-submit $ spark-submit
  26. Spark クラスタ・マネージャとして Kubernetes を使用する Copyright © 2022 Oracle and/or its

    affiliates. 32 OKE Node #1 Node #2 Node #3 Object Storage Bucket Bucket Bucket プログラム / ライブラリ 入力ファイル 出力ファイル default Container Registry driver executor executor Spark Cluster $ spark-submit Virtual Machine
  27. 1. spark-submit を使って Kubernetes クラスタに Sparkアプリケーションをサブミット 2. Spark は、Kubernetes Pod

    内で実行されるドライバを作成 3. ドライバは、エグゼキュータ Pod を作成してそれらに接続し、アプリケーションコードを実行 4. アプリケーションが完了すると、エグゼキュータ Pod は終了してクリーンアップされる 5. ドライバ Pod はログを保持し、最終的にガベージコレクションされるか手動でクリーンアップ されるまで “Completed” の状態のままになる spark-submit の --conf オプションで Kubernetes の諸々の機能を活用できる • Secret のマウント • Volume のマウント (hostPath, emptyDir, nfs, persistentVolumeClaim) • Node selector を使ったワーカーノードの指定 • ドライバ、エグゼキュータに割り当てる CPU, メモリーの指定 • etc. Kubernetes クラスタ上で Spark アプリケーションが動作する仕組み Copyright © 2022 Oracle and/or its affiliates. 33 driver executor executor Spark Cluster
  28. 1. コンテナ・イメージの作成 • Pod にデプロイするイメージは $SPARK_HOME からユーザが作成する ( ./conf はイメージに含まれない

    : 重要) • Spark は Dockerfile (カスタマイズ可) と 作成ツール (docker-image-tool.sh) を提供している 2. サービスアカウントの作成 • ドライバ Pod はサービスアカウントで Kubernetes API サーバーにアクセスし、エグゼキュータ Pod を作成・監視する • 少なくとも、サービスアカウントには Role もしくは ClusterRole が付与されている必要がある Kubernetes クラスタ上で Spark アプリケーションを動かすための事前準備 Copyright © 2022 Oracle and/or its affiliates. 34 $ ./bin/docker-image-tool.sh -r <repository> -t <tag> build $ ./bin/docker-image-tool.sh -r <repository> -t <tag> push # to build additional PySpark docker image $ ./bin/docker-image-tool.sh -r <repository> -t <tag> ¥ -p ./kubernetes/dockerfiles/spark/bindings/python/Dockerfile build ローカルの Spark インストール ディレクトリのファイルを使ってイ メージを作る仕組みになっている $ kubectl create serviceaccount spark $ kubectl create clusterrolebinding spark-role ¥ --clusterrole=edit --serviceaccount=default:spark <repository>/spark:<tag> というイメージができる <repository>/spark-py:<tag> というイメージができる
  29. spark-submit を行うと何が起きるか? Copyright © 2022 Oracle and/or its affiliates. 35

    local machine $ spark-submit ./conf/log4j.properties ./conf/spark-defaults.conf ConfigMap driver executor executor log4j.properties spark.properties ConfigMap log4j.properties /opt/spark/conf/log4j.properties /opt/spark/conf/spark.properties /opt/spark/conf/log4j.properties /opt/spark/conf/log4j.properties コンテナ イメージ 存在しない 場合もあり spark-drv-xxxxxxx-conf-map spark-exec-xxxxxxx-conf-map ownerReference • エグゼキュータ Pod • ヘッドレス・サービス for Driver • ConfigMap はドライバ Pod に対する ownerReference を持っている ので、ドライバ Pod が削除される とカスケードして削除される xxxxx-driver-svc ヘッドレス・サービス ※ ヘッドレス・サービス = clusterIP: Noneのサービス • ローカルの ./conf ディレクトリを ConfigMap にする • ドライバ/エグゼキュータがConfigMapをマウントする 7078 driver-rpc-port 7079 blockmanager 4040 spark-ui
  30. Kubernetes 上での ジョブ・スケジューリング ドライバ、エグゼキュータのスケジューリングは Pod として Kubernetes によって制御される • ノード・セレクタは利用可能

    • Affinity は未サポート → 後述する Spark Operator では Admission Webhook を使って実現している リソースの制御 • Pod のリソース要求 (requests) と制限 (limits) で実現 • Kubernetes のネームスペースに対するリソース・クオータの設定でリソースの予約や制限が可能 ダイナミック・リソース・アロケーション • スケジューリング待ちになったタスクがある時に追加のエグゼキュータを要求することができる • spark.dynamicAllocation.enabled=true • spark.dynamicAllocation.shuffleTracking.enabled=true • spark.dynamicAllocation.schedulerBacklogTimeout (バックログの経過時間) • spark.dynamicAllocation.sustainedSchedulerBacklogTimeout (後続リクエスト発出の待機時間) • spark.dynamicAllocation.executorIdleTimeout second (削除するまでのアイドル時間) 36 Copyright © 2022 Oracle and/or its affiliates.
  31. Spark Config は Container spec にどう反映されるのか spec 設定項目 反映される Spark

    Config CPUの要求 spark.kubernetes.{driver|executor}.request.cores (K8sのCPU単位) spark.{driver|executor}.cores (コア数) 注: spark.kubernetes.{driver|executor}.request.cores が優先される CPUの制限 spark.kubernetes.{driver|executor}.limit.cores (K8sのCPU単位) メモリの要求&制限 spark.{driver|executor}.memory (Sparkのメモリー単位) と spark.{driver|executor}.memoryOverhead (Sparkのメモリー単位) の合計値 その他 spark.{driver|executor}.resources.{resourceName}.* ドライバ/エグゼキュータ Pod のリソース要求 (requests) と制限 (limits) Copyright © 2022 Oracle and/or its affiliates. 37 resources: requests: cpu: 200m memory: 512Mi limits: cpu: 2 memory: 4Gi マニフェストで言うとこの部分…
  32. Kubernetes クラスタに spark-submit する Copyright © 2022 Oracle and/or its

    affiliates. 38 $SPARK_HOME/bin/spark-submit ¥ --master k8s://$K8S_API_SERVER ¥ --deploy-mode cluster ¥ --conf spark.driver.cores=2 ¥ --conf spark.Kubernetes.driver.limit.cores=3000m ¥ --conf spark.driver.memory=2g ¥ --conf spark.executor.instances=3 ¥ --conf spark.executor.cores=2 ¥ --conf spark.executor.memory=4g ¥ --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark ¥ --conf spark.kubernetes.container.image=iad.ocir.io/namespace/prefix/spark:3.2.1 ¥ --conf spark.kubernetes.container.image.pullSecrets=docker-registry-secret ¥ --conf spark.kubernetes.container.image.pullPolicy=Always ¥ --conf spark.kubernetes.node.selector.name=pool2 ¥ --conf spark.kubernetes.report.interval=10s ¥ --conf spark.eventLog.enabled=true ¥ --conf spark.eventLog.dir=oci://spark@ochacafe/history ¥ --name num_airports_by_state ¥ --class com.example.demo.NumAirportsByState ¥ oci://spark@ochacafe/lib/us-flights-app_2.12-0.1.jar ¥ --input_file oci://spark@ochacafe/data/airports.csv ¥ --output_file oci://spark@ochacafe/out/num_airports_by_state ドライバ、エグゼキュータの設定 イベント・ログの出力先 (ヒストリー・サーバが読み込む) Kubernetes ノード・セレクタ ステータス出力インターバル コンテナイメージ の設定
  33. Spark アプリケーションの実行ステータスの確認 $ spark-submit --master k8s://<api-server-url> --status <submission-id> Spark アプリケーションの実行ジョブの中止

    $ spark-submit --master k8s://<api-server-url> --kill <submission-id> ログの確認 $ kubectl logs <driver-pod-name> デバッグ (詳細情報の確認) $ kubectl describe pod <driver-pod-name> Driver UIへのアクセス $ kubectl port-forward <driver-pod-name> 4040:4040 Spark アプリケーションの管理 Copyright © 2022 Oracle and/or its affiliates. 39 $ spark-submit --master k8s://<api-server-url> --status <submission-id> $ kubectl logs <driver-pod-name> $ spark-submit --master k8s://<api-server-url> --kill <submission-id> $ kubectl describe pod <driver-pod-name> $ kubectl port-forward <driver-pod-name> 4040:4040 * submission-id = <namespace>:<pod-name>
  34. 実行終了後 Driver Pod は残る (終了後でもログを確認できる) 40 Copyright © 2022 Oracle

    and/or its affiliates. $ spark-submit --master k8s://xxx.xxx.xxx.xxx:6443 --status default:num-airports-by-state-c37f607ef174f91a-driver Application status (driver): pod name: num-airports-by-state-c37f607ef174f91a-driver namespace: default labels: spark-app-selector -> spark-ec0dccc6a3524159a8083573b19d3167, spark-role -> driver pod uid: afd39bd9-d2f5-45fb-aa37-e6322923a2d2 creation time: 2022-02-13T05:01:25Z service account name: spark volumes: spark-local-dir-1, spark-conf-volume-driver, kube-api-access-hbghs node name: 10.0.10.186 start time: 2022-02-13T05:04:06Z phase: Succeeded container status: container name: spark-kubernetes-driver container image: iad.ocir.io/orasejapan/ochacafe/spark:3.2.1 container state: terminated container started at: 2022-02-13T05:04:08Z container finished at: 2022-02-13T05:04:37Z exit code: 0 termination reason: Completed $ kubectl get pod NAME READY STATUS RESTARTS AGE num-airports-by-state-c37f607ef174f91a-driver 0/1 Completed 0 5m27s
  35. Spark のモニタリング 実行ログ – conf/log4j.properties で制御 Web インターフェース • Web

    UI: リアルタイムにアプリケーションの実行状況を確認する • History Server: アプリケーション終了後にアプリケーションの実行状況を確認する • REST API: アプリケーションの実行状況を JSON 形式で取得する メトリクス - conf/metrics.properties で制御 • ConsoleSink: コンソールに出力する • CSVSink: CSV ファイルを定間隔で出力する • JmxSink: JMX 情報として出力する (JMX コンソール等で確認する) • MetricsServlet: JSON 形式のエンドポイントを公開する • PrometheusServlet: Prometheus 形式のエンドポイントを公開する (Experimental) • GraphiteSink: Graphite (モニタリング OSS) ノードに送信する • Slf4jSink: slf4j ログを出力する • StatsdSink: StatsD ノードに送信する • GangliaSink: Ganglia ノードに送信する 42 Copyright © 2022 Oracle and/or its affiliates. OKE上のドライバ/エグゼキュータのログは カスタム・ログの設定で OCI Logging に集約できる
  36. Spark WebUI • Spark アプリケーションの実行に関する様々な情報を提供 • アプリケーションが実行中の間でないと利用できない Spark History Server

    • イベントログを使って事後的に Spark アプリケーションの実行状況を確認できる • ローカル環境では ./sbin/start-history-server.sh で起動 Spark History Server Copyright © 2022 Oracle and/or its affiliates. 43 Bucket イベント spark-history-server default driver executor executor Spark Cluster Spark History Server • History Server のイメージを作成するツールは 提供されていない • 通常の手順でコンテナ化してデプロイすればOK (HDFS Connectorを忘れずに!) • 認証機能は含まれていない → Servlet Filterを作成して適用可能
  37. Spark Operator で制御される Apache Spark 稼働環境 Copyright © 2022 Oracle

    and/or its affiliates. 45 Node #1 Node #2 Node #3 Object Storage Bucket Bucket Bucket プログラム / ライブラリ 入力ファイル 出力ファイル Bucket イベント spark-operator spark-history-server default Container Registry driver executor executor Spark Cluster Spark Operator Spark History Server $ spark-submit $ sparkctl OKE Virtual Machine
  38. https://github.com/GoogleCloudPlatform/spark-on-k8s-operator Googleが開発したオープンソース (Apache License 2.0) のカスタムオペレータ • 利用している人たち → GitHub

    の docs/who-is-using.md カスタムリソース: SparkApplication, ScheduledSparkApplication の2種類 主要機能 • Spark2.3以降をサポート • spark-submit をユーザに代わって実行 • アプリケーションのスケジュール (cron) 実行 • Mutating Admission Webhook を介した Spark Pod のカスタマイズ • e.g. ConfigMap と Volume のマウント、Pod の affinity/anti-affinity、etc. • (失敗時の)再試行の制御 – Never, Always, OnFailure • アプリケーション&ドライバー/エグゼキューター・メトリックの収集と Prometheus へのエクスポート • コマンドライン・ツール sparkctl を提供 Kubernetes Operator for Apache Spark Copyright © 2022 Oracle and/or its affiliates. 47
  39. README.md の通りにやれば大丈夫 Helm chart を使ったインストール • Helm = Kubernetes 上にアプリケーションをデプロイするための標準的なツール

    • Chart = デプロイメントに必要となる様々な設定ファイルの集まり Spark Kubernetes Operator のインストール Copyright © 2022 Oracle and/or its affiliates. 48 # chart リポジトリを追加 $ helm repo add spark-operator https://googlecloudplatform.github.io/spark-on-k8s-operator # リポジトリの内容を確認 $ helm search repo spark-operator NAME CHART VERSION APP VERSION DESCRIPTION spark-operator/spark-operator 1.1.15 v1beta2-1.3.1-3.1.1 A Helm chart ... # chart のインストール $ helm install my-release spark-operator/spark-operator ¥ --namespace spark-operator --create-namespace # ステータスの確認 $ helm status --namespace spark-operator my-release
  40. バージョン Mutating Admission Webhook ( --set webhook.enable=true ) • インストール試みるもエラー

    → エラーログから察するに v1beta1 にしか対応していないように見受けられる Spark Kubernetes Operator のインストール : 注意点 Copyright © 2022 Oracle and/or its affiliates. 49 Operator Version API Version Kubernetes Version Base Spark Version Operator Image Tag latest (master HEAD) v1beta2 1.13+ 3.0.0 latest v1beta2-1.3.3-3.1.1 v1beta2 1.16+ 3.1.1 v1beta2-1.3.3-3.1.1 v1beta2-1.3.2-3.1.1 v1beta2 1.16+ 3.1.1 v1beta2-1.3.2-3.1.1 v1beta2-1.3.0-3.1.1 v1beta2 1.16+ 3.1.1 v1beta2-1.3.0-3.1.1 v1beta2-1.2.3-3.1.1 v1beta2 1.13+ 3.1.1 v1beta2-1.2.3-3.1.1 v1beta2-1.2.0-3.0.0 v1beta2 1.13+ 3.0.0 v1beta2-1.2.0-3.0.0 v1beta2-1.1.2-2.4.5 v1beta2 1.13+ 2.4.5 v1beta2-1.1.2-2.4.5 v1beta2-1.0.1-2.4.4 v1beta2 1.13+ 2.4.4 v1beta2-1.0.1-2.4.4 v1beta2-1.0.0-2.4.4 v1beta2 1.13+ 2.4.4 v1beta2-1.0.0-2.4.4 v1beta1-0.9.0 v1beta1 1.13+ 2.4.0 v2.4.0-v1beta1-0.9.0 OperatorHubにあるのはこれ # 特定のバージョンをインストールしたい場合 $ helm install my-release spark-operator/spark-operator ¥ --namespace spark-operator --create-namespace --set image.tag=v1beta2-1.3.0-3.1.1
  41. kubectl を使って カスタムリソース・マニフェストを apply する Spark Operator を使った Sparkアプリケーションの実行 Copyright

    © 2022 Oracle and/or its affiliates. 50 apiVersion: "sparkoperator.k8s.io/v1beta2" kind: SparkApplication metadata: name: spark-pi namespace: default spec: type: Scala mode: cluster image: "gcr.io/spark-operator/spark:v3.1.1" imagePullPolicy: Always mainClass: org.apache.spark.examples.SparkPi mainApplicationFile: "local:///opt/spark/examples/jars/spark-examples_2.12-3.1.1.jar" sparkVersion: "3.1.1“ ... 以下省略 $ kubectl apply -f examples/spark-pi.yaml sparkapplication.sparkoperator.k8s.io/spark-pi created spark-pi.yaml GitHubの docs/api-docs.md に詳細があります
  42. fasfas “SparkApplication” カスタムリソースの確認 Copyright © 2022 Oracle and/or its affiliates.

    51 $ kubectl apply -f examples/spark-pi.yaml sparkapplication.sparkoperator.k8s.io/spark-pi created $ kubectl get SparkApplication -w NAME STATUS ATTEMPTS START FINISH AGE spark-pi 0s spark-pi SUBMITTED 1 2021-12-14T09:20:50Z <no value> 4s spark-pi SUBMITTED 1 2021-12-14T09:20:50Z <no value> 4s spark-pi RUNNING 1 2021-12-14T09:20:50Z <no value> 6s spark-pi RUNNING 1 2021-12-14T09:20:50Z <no value> 13s spark-pi RUNNING 1 2021-12-14T09:20:50Z <no value> 15s spark-pi RUNNING 1 2021-12-14T09:20:50Z <no value> 19s spark-pi SUCCEEDING 1 2021-12-14T09:20:50Z 2021-12-14T09:21:06Z 20s spark-pi COMPLETED 1 2021-12-14T09:20:50Z 2021-12-14T09:21:06Z 20s 出力を見やすいように整形しています
  43. fasfas “SparkApplication”カスタムリソースの詳細情報確認 (Status, Events) Copyright © 2022 Oracle and/or its

    affiliates. 52 $ kubectl describe SparkApplication spark-pi Name: spark-pi Namespace: default API Version: sparkoperator.k8s.io/v1beta2 Kind: SparkApplication ... 途中省略 ... Status: Application State: State: COMPLETED Driver Info: Pod Name: spark-pi-driver Execution Attempts: 1 Executor State: spark-pi-3406127db81fa08e-exec-1: FAILED Last Submission Attempt Time: 2021-12-14T08:46:40Z Spark Application Id: spark-f81b750db35e4a278070d02e95a301d0 Submission Attempts: 1 Submission ID: d7233c66-a356-4ca8-932c-d3d40bc182a6 Termination Time: 2021-12-14T08:47:23Z Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SparkApplicationAdded 20m spark-operator SparkApplication spark-pi was added, enqueuing it for submission Normal SparkApplicationSubmitted 20m spark-operator SparkApplication spark-pi was submitted successfully Normal SparkDriverRunning 20m spark-operator Driver spark-pi-driver is running Normal SparkExecutorPending 20m spark-operator Executor [spark-pi-3406127db81fa08e-exec-1] is pending Normal SparkExecutorRunning 20m spark-operator Executor [spark-pi-3406127db81fa08e-exec-1] is running Normal SparkDriverCompleted 19m spark-operator Driver spark-pi-driver completed Normal SparkApplicationCompleted 19m spark-operator SparkApplication spark-pi completed Warning SparkExecutorFailed 19m spark-operator Executor [spark-pi-3406127db81fa08e-exec-1 %!s(int=-1) Unknown ...
  44. SparkApplication の作成、リスト、ステータス確認、ログの取得、削除、Web UIのポートフォーワード • ScheduledSparkApplication には対応していない sparkctl のインストール • Goコンパイラでビルド…

    (ドキュメント通りやればバイナリが出来上がる) 使い方 sparkctl コマンドライン・ツール Copyright © 2022 Oracle and/or its affiliates. 53 $ sparkctl --help Usage: sparkctl [command] Available Commands: create Create a SparkApplication object delete Delete a SparkApplication object event Shows SparkApplication events forward Start to forward a local port to the remote port of the driver UI help Help about any command list List SparkApplication objects log log is a sub-command of sparkctl that fetches logs of a Spark application. status Check status of a SparkApplication
  45. ScheduledSparkApplication カスタムリソース Cron 形式 (拡張形式もOK) のスケジューリングが行える ScheduledSparkApplication = スケジューリングの設定 +

    SparkApplication テンプレート Spark アプリケーションのスケジュール実行 Copyright © 2022 Oracle and/or its affiliates. 54 apiVersion: "sparkoperator.k8s.io/v1beta2" kind: ScheduledSparkApplication metadata: name: spark-pi-scheduled namespace: default spec: schedule: "@every 5m" concurrencyPolicy: Allow suspend: false successfulRunHistoryLimit: 2 failedRunHistoryLimit: 3 template: ... 以下 SparkApplication と同様の設定内容 concurrencyPolicy: 同時実行性 Allow, Forbid, Replace のいずれか Suspend: スケジュール実行の一時中断 true, false のいずれか (kubectl apply で反映される)
  46. ScheduledSparkApplication の作成 ~ ステータス確認 Copyright © 2022 Oracle and/or its

    affiliates. 55 $ kubectl apply -f spark-pi_cron.yaml scheduledsparkapplication.sparkoperator.k8s.io/spark-pi-cron created $ kubectl get ScheduledSparkApplication NAME SCHEDULE SUSPEND LAST RUN LAST RUN NAME AGE spark-pi-cron @every 2m false 53s spark-pi-cron-1639542480449468151 5m11s $ kubectl describe ScheduledSparkApplication spark-pi-cron Name: spark-pi-cron ... 途中略 Kind: ScheduledSparkApplication ... 途中略 Status: Last Run: 2021-12-15T04:28:00Z Last Run Name: spark-pi-cron-1639542480449468151 Next Run: 2021-12-15T04:30:00Z Past Successful Run Names: spark-pi-cron-1639542480449468151 spark-pi-cron-1639542360448610236 Schedule State: Scheduled Events: <none> 過去の成功/失敗した SparkApplication は .status.pastSuccessfulRunNames .status.pastFailedRunNames で確認できる 保持する最大数は spec.successfulRunHistoryLimit spec.failedRunHistoryLimit で設定される
  47. Copyright © 2022 Oracle and/or its affiliates. 56 デモ Spark

    Operatorを使って Spark アプリケーションを実行する
  48. デモのマニフェスト (num_airports_by_state.yaml) – 1/2 Copyright © 2022 Oracle and/or its

    affiliates. 57 apiVersion: "sparkoperator.k8s.io/v1beta2" kind: SparkApplication metadata: name: op-num-airports-by-state namespace: default spec: type: Scala mode: cluster image: "iad.ocir.io/ochacafe/spark:3.2.1-oci" imagePullPolicy: Always imagePullSecrets: - docker-registry-secret mainClass: com.example.demo.NumAirportsByState mainApplicationFile: "oci://spark@ochacafe/lib/us-flights-app_2.12-0.1.jar" arguments: - "--input_file" - "oci://spark@ochacafe/data/airports.csv" - "--output_file" - "oci://spark@ochacafe/out/num_airports_by_state" sparkVersion: "3.2.1" restartPolicy: type: Never sparkConf: spark.sql.hive.metastore.sharedPrefixes: shaded.oracle,com.oracle.bmc spark.hadoop.fs.oci.client.hostname: "https://objectstorage.us-ashburn-1.oraclecloud.com" spark.hadoop.fs.oci.client.custom.authenticator: "com.oracle.bmc.hdfs.auth.InstancePrincipalsCustomAuthenticator" spark.eventLog.enabled: "true" spark.eventLog.dir: "oci://spark@ochacafe/history“ ...次ページに続く コンテナイメージ の設定 ヒストリー・サーバが読み込むイベント・ログの出力先 Hadoop の設定 (HDFSコネクタ) Never, Always, OnFailure
  49. #1 SparkApplication の実行 $ kubectl apply –f num_airports_by_state.yaml $ sparkctl

    create num_airports_by_state.yaml デモのマニフェスト (num_airports_by_state.yaml) – 2/2 Copyright © 2022 Oracle and/or its affiliates. 58 ...前ページより続く timeToLiveSeconds: 3600 nodeSelector: name: "pool2" driver: cores: 1 coreLimit: “2500m" memory: "512m" labels: version: 3.2.1 serviceAccount: spark executor: #instances: 3 cores: 1 memory: "512m" labels: version: 3.2.1 dynamicAllocation: enabled: true initialExecutors: 2 minExecutors: 1 maxExecutors: 10 ドライバ、エグゼキュータの設定 Kubernetes ノード・セレクタ SparkApplication オブジェクトを終了後ガベージコレクトするまでの時間 エグゼキュータ のダイナミック・アロケーションの設定 #2 ScheduledSparkApplication の実行 $ kubectl apply –f num_airports_by_state_cron.yaml ( sparkctl は未対応)
  50. Spark の “Dynamic Resource Allocation” 機能を限定的に実現 エグゼキュータのダイナミック・リソース・アロケーション Copyright © 2022

    Oracle and/or its affiliates. 59 spec: dynamicAllocation: enabled: true initialExecutors: 2 minExecutors: 1 maxExecutors: 10 initialExecutors: 2 初期状態として 2 個のエグゼキュータが起動 3 個のエグゼキュータが 動的に起動 合計 5個のエグゼキュータ
  51. (ちょっとしたETLツールとして使えます!) 出力先をデータベースにする Copyright © 2022 Oracle and/or its affiliates. 61

    Node #1 Node #2 Node #3 Object Storage Bucket Bucket プログラム / ライブラリ 入力ファイル Bucket イベント spark-operator spark-history-server default Container Registry driver executor executor Spark Cluster Spark Operator Spark History Server $ spark-submit $ sparkctl OKE Autonomous Database Secret (DB接続情報) Virtual Machine
  52. Spark は JDBC 経由でデータベースの入出力をネイティブにサポート → アプリケーションの修正は僅少で済む 実行には必然的に JDBC ドライバが必要 1.

    JDBC ドライバのライブラリの入ったイメージを作成して使用する → DB決め打ちでいいのであればこれが簡単 2. マニフェストで、JDBC ドライバのライブラリを指定する (下記参照) 出力先をデータベースにする & Spark Operator で実行する Copyright © 2022 Oracle and/or its affiliates. 62 val db_prop = new Properties() db_prop.put("user", "user") db_prop.put("password", "password") db_prop.put("driver", “<jdbc driver class name>") num_airports.write.mode("overwrite").option("truncate", true).jdbc("<jdbc url>", "<table name>"), db_prop) spec: deps: jars: - https://repo.maven.apache.org/maven2/com/oracle/database/jdbc/ojdbc8/21.3.0.0/ojdbc8-21.3.0.0.jar mainClass: com.example.demo.NumAirportsToDb mainApplicationFile: "oci://spark@ochacafe/lib/us-flights-app_2.12-0.1.jar" Maven リポジトリの jar を指定している - Operator だと packages: 指定がエグゼキュータに効かなったため…
  53. Spark Operator でも Secret を環境変数として利用することが可能 Database のユーザ/パスワードを Secret に保存して使用する Copyright

    © 2022 Oracle and/or its affiliates. 63 apiVersion: v1 kind: Secret metadata: name: db-config-secret type: Opaque stringData: user: "demo" password: "Z5i*ug3i" jdbcUrl: "jdbc:oracle:thin:@..." Spec: driver: envSecretKeyRefs: DB_USER: name: db-config-secret key: user DB_PASSWORD: name: db-config-secret key: password DB_JDBCURL: name: db-config-secret key: jdbcUrl db-config-secret.yaml (Secret定義) num_airports_to_db.yaml (SparkApplication 定義) val db_prop = new Properties() db_prop.put("user", sys.env("DB_USER")) db_prop.put("password", sys.env("DB_PASSWORD")) ... NumAirportsToDb.scala (アプリケーション・ソース)
  54. Copyright © 2022 Oracle and/or its affiliates. 64 デモ 1.

    Kafka Operator を使って K8s (OKE) 上に Kafka クラスタを構築し、Twitter の Filtered Stream で取得した Tweet を Kafka に流す Pod をデプロイする 2. Spark Structured Streaming を使って Kafka から取得したデータから 30 秒毎のキーワード出現数を集計し、データベース (ADW) に書き込む 3. ADW に出力されたデータをクエリして、リアルタイムなワードクラウドを作成する Twitter stream 集計アプリ Twitter stream 収集アプリ console database Tweet 本文 30秒毎 キーワード出現数 Autonomous Data Warehouse 1 2 3
  55. Kafka クラスタ環境も Operator を使ってシンプル&スピーディに構築! Spark Streaming 実行環境 Copyright © 2022

    Oracle and/or its affiliates. 65 Node #1 Node #2 Node #3 Object Storage Bucket プログラム / ライブラリ spark-operator default Container Registry Spark Cluster Spark Operator driver executor executor OKE Kafka Cluster Operator kafka my-kafka-project zookeeper Entity Operator kafka pub sub filtered stream Autonomous Database write Twitter stream 収集アプリ Twitter stream 集計アプリ Spark cluster Node #4 Node #5 Node #6 UI for Apache Kafka prometheus Virtual Machine spark-role=driver
  56. Structured Streaming: 集計アプリで行っていること 66 Copyright © 2022 Oracle and/or its

    affiliates. ts text (2022/02/16 14:05:15) “本日は晴天です、明日も晴天でしょう。" .select($"ts", tokenizeUDF($"text").as("tokens")) ts tokens (2022/02/16 14:05:15) [“本日", "晴天", "明日", "晴天“] ts token (2022/02/16 14:05:15) “本日" (2022/02/16 14:05:15) "晴天" (2022/02/16 14:05:15) "明日" (2022/02/16 14:05:15) "晴天“ window token count “本日" 1 "晴天" 2 "明日" 1 Start end (2022/02/16 14:05:00) (2022/02/16 14:05:30) Start end (2022/02/16 14:05:00) (2022/02/16 14:05:30) Start end (2022/02/16 14:05:00) (2022/02/16 14:05:30) .select($"ts", explode($"tokens").as("token")) .groupBy(window($"ts", “30 seconds"), $"token") .agg(count("token").as("count")) ユーザ定義関数を使って文字列を分割&フィルタして配列にする (形態素解析ライブラリを使用) explode() 関数は配列を分解して要素数分の行を作成する 30秒の time window と token 列でグルーピングして行数をカウント データベース書き込み処理に続く
  57. Structured Streaming で データベースに出力するには? Input Source → Structured Streaming →

    Output Sink Sparkが標準で提供している Output Sink • File sink • Kafka sink • Foreach sink → 任意の処理を実装する場合 • Console sink (for debugging) • Memory sink (for debugging) Data Writer が提供されているもの (= jdbc) は foreachBatch() を用いることが可能 67 Copyright © 2022 Oracle and/or its affiliates. .writeStream .foreachBatch { (batchDF: DataFrame, batchId: Long) => batchDF.write.mode("append") .option("isolationLevel", "READ_COMMITTED") .jdbc(sys.env("DB_JDBCURL"), "TWEET_KEYWORDS", db_prop) } .option("checkpointLocation", "oci://spark@ochacafe/checkpoint") .queryName("keywords to database") .start() foreachBatch() • 各マイクロバッチ毎に呼び出される • DataFrameとバッチIDが渡される: ラムダ式で記述できる foreach() • 各行毎に呼び出される • 抽象クラス ForeachWriterの実装クラスを作成する "checkpointing" を忘れずに! 処理失敗時 (意図的な shutdown を含む) に 再実行するポイントと状態を保持するログ → HDFS互換ファイルシステムのパスを指定する
  58. Mutating Admission Webhook • ConfigMap のマウント • ボリューム関連の設定 • Pod

    affinity/anti-affinity Monitoring • Prometheus JMX exporter → Spark 3.0 から Prometheus 向けの Metrics を出力できるようになっているので、使わなくても export 可能 試していない Spark Operator の機能 Copyright © 2022 Oracle and/or its affiliates. 69
  59. クラウドを活用した効率的な Apache Spark 実行環境の構築と運用の実現 • クラスタ管理、リソース制御 → Managed Kubernetes Service

    を活用 • HDFSファイルシステム → Object Storage を活用 大規模はもちろん、さらに小回りの利くアプリケーション領域への活用が広がることが期待できる • ETL、Data Preparation、機械学習 (MLlib) & グラフ • ストリーミング系アプリケーション (Kafka と連携したソリューション) まとめ Copyright © 2022 Oracle and/or its affiliates. 70
  60. Big Data Service Data Flow Copyright © 2022, Oracle and/or

    its affiliates 71 Autonomous Database Exadata VM/BM Database MySQL Data Integration OCI – Block Storage, File Storage, Object Storage Data Catalog Data Science Oracle SQL Oracle Analytics Analyze Metadata Process and Manage Data Store Oracle Cloud Data Platform Services Streaming Database Migration Stream Analytics Spark 実行環境 Spark 実行環境 Spark 実行環境 Spark 実行環境
  61. フルマネージド Apache Sparkサービス サービス概要/特徴 • OCI Data Flow は フルマネージドのApache

    Spark サービ スです • Sparkアプリケーションの実行を簡単にし、運用上のオーバー ヘッドを発生させずに、優れたビッグデータアプリケーションの 作成に集中できます こんな課題に役立ちます • Big Data アプリケーション(Spark アプリケーション)を迅速に提 供できる環境が欲しい • オンプレミスの既存Big Data アプリケーション(Spark アプリ ケーション)の実行環境コストを削減したい • 3rd Party クラウド上の既存Big Data アプリケーション(Spark アプリケーション)の実行環境コストを削減したい サービス価格 • 実行時にプロビジョニングされたOCIリソースに対する課金のみ Oracle Cloud Infrastructure - Data Flow Copyright © 2022 Oracle and/or its affiliates. 72 • 実行時にダイナミックに ”コンピュート” をプロビジョン - シェイプとインスタンス数を指定 - 実行完了後コンピュートを削除 • spark-shell 相当の操作を CLI で操作可能 • Spark Streaming は未対応 ←1/26リリース
  62. こちらも参考に Copyright © 2022 Oracle and/or its affiliates. 73 Qiita

    Hadoop と Oracle Cloud Infrastructure HDFS Connector を使って Object Storage をファイルシステムのように扱う https://qiita.com/tkote/items/04eef4ac723b2a140cdb Speaker Deck https://speakerdeck.com/oracle4engineer/cloud-native-streaming 「Cloud Native x Streaming はじめの一歩」 Spark Streaming の仕組みからプログラミングまで解説しています
  63. Apache Spark ドキュメント https://spark.apache.org/docs/latest/ Kubernetes Operator for Apache Spark https://github.com/GoogleCloudPlatform/spark-on-k8s-operator

    HDFS Connector for OCI Object Storage https://docs.oracle.com/ja-jp/iaas/Content/API/SDKDocs/hdfsconnector.htm https://github.com/oracle/oci-hdfs-connector デモのコード&スクリプト(Scala バージョン / pyspark バージョン) https://github.com/oracle-japan/ochacafe-spark-on-k8s リファレンス Copyright © 2022 Oracle and/or its affiliates. 74
  64. Our mission is to help people see data in new

    ways, discover insights, unlock endless possibilities.