Apache Arrow Flight

: subtitle

ビッグデータ用高速データ転送フレームワーク

: author

須藤功平

: institution

株式会社クリアコード

: content-source

db tech showcase 2021

: date

2021-11-17

: allotted-time

45m

: theme

.

モチベーション

ビッグデータをn 処理したい!

ビッグデータ処理に必要なもの

* 大量データ:データがないと始まらない!
* 速度:速くないと処理しきれない!

大量データの収集に必要なもの

  * データ収集ツール
    * 例:ログ:Fluentd/Fluent Bit
  * ストレージ
    * 例:Amazon S3
  * 効率的なデータフォーマット
    * トレードオフ:空間効率と時間効率
    * 例:CSVよりApache Parquet

# image
# src = images/fluentd-maintenance.png
# relative-width = 20
# relative-margin-right = -10
# align = right
# vertical-align = top

高速処理に必要なもの

* 高速な分散システム
  * 1台では処理しきれない
* 高速なアルゴリズムとその実装
  * 個々の処理が速くなると全体も速くなる

今日注目すること

高速な分散システム

高速な分散システムに必要なもの

* 効率のよいタスク管理
  * より速く処理が終わるようなリソース配分
* 効率のよいデータ転送
  * ノード間でのデータ交換コストは無視できない

大量データの交換コスト

    # image
    # src = https://hannes.muehleisen.org/p852-muehleisen.pdf
    # page = 1
    # relative-width = 50
    # relative-clip-y = 8
    # relative-clip-height = 17
    # align = center
    # vertical-align = top

  # image
  # src = https://hannes.muehleisen.org/p852-muehleisen.pdf
  # page = 1
  # relative-width = 90
  # relative-clip-x = 50
  # relative-clip-y = 25
  # relative-clip-height = 25
  # align = left
  # vertical-align = bottom
  # relative-margin-top = 1.5
  # relative-margin-left = -20

# image
# src = https://hannes.muehleisen.org/p852-muehleisen.pdf
# page = 2
# relative-width = 100
# relative-clip-x = 50
# relative-clip-height = 29
# align = right
# vertical-align = bottom
# relative-margin-top = 8
# relative-margin-right = -10

((‘tag:right’)) ((‘tag:margin-top * 22.5’)) ((‘note:((<URL:hannes.muehleisen.org/p852-muehleisen.pdf>))’))

大量データの交換コスト

  * ボトルネックになりやすい
    (1) シリアライズ・デシリアライズ
    (2) ネットワーク帯域
  * 目指すところ
    * メイン処理がボトルネック\n
      (メイン処理以外が十分速い)

# image
# src = https://hannes.muehleisen.org/p852-muehleisen.pdf
# page = 2
# relative-width = 60
# relative-clip-x = 50
# relative-clip-height = 24
# align = right
# vertical-align = top
# relative-margin-top = -10
# relative-margin-right = -17

解決策

Apache Arrow Flight

Apache Arrow Flightと私

  * Apache ArrowプロジェクトのPMCメンバー
    * (('note:Apache Arrow Flightも開発しているプロジェクト'))
    * (('note:PMC:プロジェクト管理委員会'))
  * コミット数2位

# image
# src = images/contributor.png
# relative-width = 45
# align = right
# vertical-align = bottom
# relative-margin-top = 10
# relative-margin-right = -10

Apache Arrow Flight

* gRPCベースのデータ転送フレームワーク
* ポイント
  * 並列転送対応
    * 「効率のよいタスク管理」に有用
  * ストリーム処理対応
    * 「効率のよいタスク管理」に有用
  * シリアライズ・デシリアライズがほぼ不要
    * 「効率のよいデータ転送」に有用

簡単な使い方

# image
# src = https://arrow.apache.org/img/20191014_flight_simple.png
# relative-height = 80

((‘tag:right’)) ((‘note:((<URL:GetFlightInfo

  * クライアント→サーバー
  * データの取得方法を教えてもらう
    * サーバーはFlightInfoを返す
  * FlightInfoの中身
    * メタデータ:スキーマ・総レコード数…
    * 複数エンドポイント:\n
      データは複数ヶ所に分散しているかもしれない!

# image
# src = https://arrow.apache.org/img/20191014_flight_simple.png
# relative-width = 20
# align = right
# vertical-align = top
# relative-margin-right = -10

DoGet

  * クライアント→サーバー
  * データを取得する
    * サーバーはレコードバッチをストリームで返す
    * プロトコルレベルではFlightDataと呼んでいる
  * レコードバッチ
    * データ全体のうちの一部のレコードの集まり

# image
# src = https://arrow.apache.org/img/20191014_flight_simple.png
# relative-width = 20
# align = right
# vertical-align = top
# relative-margin-right = -10

Apache Arrow Flightが扱うデータ

  * 型付きのテーブルデータ
    * RDBMSで扱うようなデータ
    * カラムごとに型がある
    * すべてのレコードは同じカラム構成
  * レコードバッチ
    * テーブルデータ内の連続したレコードの集まり

# image
# src = images/record-batch.svg
# relative-width = 30
# align = right
# vertical-align = top
# relative-margin-right = -10

レコードバッチストリーム

# image
# src = images/record-batch-stream.svg
# relative-width = 90

スライドプロパティー

: enable-title-on-image

false

なぜストリームが重要か

* 大量データを準備ができた順に処理できる
  * 全部準備ができるまで待たなくてよい
  * リソースを有効活用できる
* レコードバッチのストリームでいいの?
  * レコードのストリーム方がいいんじゃない?

ストリームの単位

  * レコード
    * レコード単位で処理できる
    * データはレコード単位でまとめる
  * レコードバッチ
    * 複数レコードをまとめて処理できる
    * データをカラム単位でまとめられる

# image
# src = images/columnar.svg
# relative-width = 30
# align = right
# vertical-align = top
# relative-margin-right = -10

レコードバッチと処理

  * 複数レコードをまとめて処理
    * SIMDを活用すればレコード単位の処理より高速
  * カラム単位でまとまったデータ
    * 分析処理が高速
    * ビッグデータ処理の多くは分析処理なはず

# image
# src = images/columnar.svg
# relative-width = 30
# align = right
# vertical-align = top
# relative-margin-right = -10

詳細

# image
# src = https://slide.rabbit-shocker.org/authors/kou/db-tech-showcase-online-2020/why-apache-arrow-format-is-fast.pdf
# relative-width = 80

((‘tag:right’)) ((‘note:((<URL:slide.rabbit-shocker.org/authors/kou/db-tech-showcase-online-2020/>))’))

高速な分散システムの実現方法

* レコードバッチのストリーム\n
  (('note:ここまでで説明したこと'))
  * 待ち時間を減らせる
  * 受け取ったデータを高速処理できる
* スケールアウト\n
  (('note:これから説明すること'))
  * データを複数ノードで分散処理
  * それを効率的に扱う

スケールアウト構成例

# image
# src = https://arrow.apache.org/img/20191014_flight_complex.png
# relative-height = 80

((‘tag:right’)) ((‘note:((<URL:ポイント1:ムダな転送を回避可能

  * 多くの分散システム
    * 「コーディネーター」経由で通信
    * ノード→コーディネーター→クライアント
  * Apache Arrow Flight
    * 直接クライアントがデータ取得可能
    * ノード→クライアント

# image
# src = https://arrow.apache.org/img/20191014_flight_complex.png
# relative-width = 20
# align = right
# vertical-align = top
# relative-margin-right = -10

ポイント2:並列転送可能

  * 同時に複数ノードからデータ取得可能
    * データごとに異なるエンドポイントだから可能
  * ストリームなので各データを随時処理可能

# image
# src = https://arrow.apache.org/img/20191014_flight_complex.png
# relative-width = 20
# align = right
# vertical-align = top
# relative-margin-right = -10

個々のデータ転送も速い

  * 個々のデータ転送のボトルネック
    * シリアライズ・デシリアライズ
  * どうすれば速くできる?
    * なにもしなきゃいいじゃん!

# image
# src = https://hannes.muehleisen.org/p852-muehleisen.pdf
# page = 2
# relative-width = 60
# relative-clip-x = 50
# relative-clip-height = 24
# align = right
# vertical-align = top
# relative-margin-top = -10
# relative-margin-right = -17

なにもしない?

  * そもそもなぜシリアライズが必要?
    * メモリー上のデータの配置と\n
      通信時のデータの配置が違うから
  * シリアライズしなくて済むには?
    * メモリー上のデータの配置と\n
      通信時のデータの配置を同じにすればいい!

# image
# src = https://hannes.muehleisen.org/p852-muehleisen.pdf
# page = 2
# relative-width = 60
# relative-clip-x = 50
# relative-clip-height = 24
# align = right
# vertical-align = top
# relative-margin-top = -10
# relative-margin-right = -17

Apache Arrowフォーマット

  * シリアライズ不要フォーマット
    * メモリー上で効率よくデータを扱える配置
    * データ交換時も↑と同じ配置を使う
  * Apache Arrow Flightが扱うデータは\n
    Apache Arrowフォーマット
    * 個々のデータ転送も速い!

# image
# src = https://hannes.muehleisen.org/p852-muehleisen.pdf
# page = 2
# relative-width = 60
# relative-clip-x = 50
# relative-clip-height = 24
# align = right
# vertical-align = top
# relative-margin-top = -10
# relative-margin-right = -17

Apache Arrow Flightのまとめ

* 高速データ転送フレームワーク
  * 並列転送対応
  * ストリーム処理対応
  * シリアライズ・デシリアライズがほぼ不要
* gRPCベース
  * 既存のgRPCライブラリーでも接続可能
  * 専用ライブラリーあり:C, C++, C#, Go, Java, Python, R, Ruby, Rust

Apache Arrow Flightの利用事例

((‘tag:xx-large’)) Apache Arrow Ballista

# image
# src = https://raw.githubusercontent.com/apache/arrow-datafusion/master/ballista/ui/scheduler/public/logo512.png
# relative-width = 20
# relative-margin-right = -10
# align = right

((‘tag:right’)) ((‘note:Apache License 2.0 - © 2016-2021 The Apache Software Foundation’))

Apache Arrow Ballista

 * Rust実装の分散計算プラットフォーム
 * データはApache Arrowフォーマット
 * 通信はgRPCとApache Arrow Flight

# image
# src = https://raw.githubusercontent.com/apache/arrow-datafusion/master/ballista/ui/scheduler/public/logo512.png
# relative-width = 20
# relative-margin-right = -10
# align = right
# vertical-align = top

アーキテクチャー

# image
# src = https://raw.githubusercontent.com/apache/arrow-datafusion/master/ballista/docs/images/query-execution.png
# relative-width = 80
# draw[0] = [rectangle, false, 0.3, 0.5, 0.15, 0.1, "#0041ab", {line_width: 3}]
# draw[1] = [rectangle, true, 0.05, 0.52, 0.15, 0.07, white]
# draw[2] = [text, Apache Arrow Flight, 0.05, 0.52, "#0041ab", {size: 25}]
# draw[3] = [rectangle, false, 0.295, 0.75, 0.15, 0.1, "#0041ab", {line_width: 3}]
# draw[4] = [rectangle, true, 0.05, 0.76, 0.15, 0.07, white]
# draw[5] = [text, Apache Arrow Flight, 0.05, 0.76, "#0041ab", {size: 25}]

((‘tag:right’)) ((‘note:Apache License 2.0 - © 2016-2021 The Apache Software Foundation’))

Apache Arrow Ballistaでの使い方

  * DoGetだけ使っている
    * 処理済みのパーティションを受け取る
    * 大量データになりうる
  * その他の通信は素のgRPC
    * 各Executorへの処理の依頼など
    * 大量データにはならない

# image
# src = https://raw.githubusercontent.com/apache/arrow-datafusion/master/ballista/docs/images/query-execution.png
# relative-width = 20
# relative-margin-right = -10
# align = right
# vertical-align = top

さらにApache Arrow Flight

* 利用可能なリクエスト
* ミドルウェア
* 将来の展望

利用可能なリクエスト1

* Handshake
  * 認証
* ListFlights
  * 利用可能なデータの取得方法一覧を取得
  * GetSchema/DoGetなどで使える
* GetFlightInfo
  * 指定したデータの取得方法を取得
  * GetSchema/DoGetなどで使える

利用可能なリクエスト2

* GetSchema
  * 指定したデータのスキーマを取得
* DoGet:指定したデータを取得
* DoPut:データを送信
* DoExchange:データを送受信

利用可能なリクエスト3

* DoAction
  * 任意の処理を実行
  * 普通のRPCなので素のgRPCでも十分
* ListActions
  * 利用可能なアクション一覧を取得

ミドルウェア

* プラグインみたいなもの
  * サーバー側・クライアント側両方あり
* 利用例
  * 認証機能
  * 分散トレーシング機能

将来の展望1

* gRPC以外もサポートするかも
  * (('note:((<URL:https://issues.apache.org/jira/browse/ARROW-13889>))'))
  * メーリングリストで議論中
* 候補:UCX\n
  (('note:((<URL:https://openucx.org/documentation/>))'))
  * RDMA/GPUなどハードウェアも活用した高速通信

将来の展望2

* Apache Arrow Flight SQLの追加
  * (('note:((<URL:https://issues.apache.org/jira/browse/ARROW-9825>))'))
  * Apache Arrow Flight経由で各種RDBMSとやりとり
* GetFlightInfoでSQL送信
* DoGetで結果を受信\n
  * (('note:RDBMSとFlightアダプターの間のシリアライズがボトルネックになりそうな気がするんだけど、RDBMSのプロセス内にFlightアダプターを実装するのかな。。。'))

まとめ

* 大量データのやりとりは\n
  シリアライズ・デシリアライズが遅い
  * Apache Arrow Flightでそのコストをなくせる
* さらに高速に扱う仕組みもある
  * 並列転送やストリーム処理
  * 将来:UCXやFlight SQL

次のステップ

  * もっと詳しく知りたくなったから\n
    イベント・社内・…で紹介して!
    * ((<URL:https://www.clear-code.com/contact/>))
  * アンケートに答えてね!
    * ⇗のQRコードあるいは⇓\n
      (('note:((<URL:https://www.clear-code.com/surveys/db-tech-showcase-2021.html>))'))

# image
# src = images/survey-url.svg
# relative-width = 20
# relative-margin-right = -10
# align = right
# vertical-align = top