Apache Arrow

: subtitle

A cross-language development platform\nfor in-memory data

: author

Kouhei Sutou

: institution

ClearCode Inc.

: content-source

SciPy Japan Conference 2019

: date

2019-04-23

: start-time

2019-04-23T14:30:00+09:00

: end-time

2019-04-23T14:55:00+09:00

: theme

.

Me

Ruby committer since 2004n (('note:2004年からRubyコミッター'))

Why do I talk at SciPy?n(('note:なぜSciPyで話しているのか?'))

To introducen ((*Apache Arrow*))n (('note:((*Apache Arrow*))を紹介するため'))

Apache Arrow

# blockquote
# title = https://arrow.apache.org/

A cross-language development platform for in-memory data\n
(('note:インメモリーデータ向け多言語対応開発プラットフォーム'))

Cross-languagen(('note:多言語対応'))

* C, C++, C#, Go, Java,
* JavaScript, MATLAB, ((*Python*)),
* R, ((*Ruby*)) and Rust

Development platformn(('note:開発プラットフォーム'))

Apache Arrow …

* specifies standards and\n
  (('note:標準化'))
* provides implementations\n
  (('note:実装'))

to advance cooperation by many peoplen (('note:多くの人が協力できるように'))

For in-memory datan(('note:インメモリーデータ'))

Apache Arrow focuses on ↓ ((*for now*))n (('note:Apache Arrowは((*今のところ*))は↓に注力'))

* sharing columnar/tensor data\n
  (('note:カラムナーデータ・テンソルデータの共有'))
* analyzing columnar data\n
  (('note:カラムナーデータの分析'))
* RPC for columnar data\n
  (('note:カラムナーデータのRPC'))

Apache Arrow and Pythonn(('note:Apache ArrowとPython'))

* As pickle replacement\n
  (('note:pickleの代替'))
  * PySpark does\n
    (('note:PySparkはすでにやっている'))
* As dataframe library\n
  (('note:データフレームライブラリー'))
  * pandas and Vaes use Apache Arrow a bit\n
    (('note:pandasとVaesはApache Arrowを少し使っている'))

Apache Arrow and men(('note:Apache Arrowと私'))

  # image
  # src = images/apache-arrow-and-me.svg
  # align = right
  # vertical-align = bottom
  # relative-width = 65
  # relative-margin-right = 20
  # relative-padding-bottom = -15

* A release manager(('note:(リリースマネージャー)'))
  * 0.11.0 and 0.13.0 (('note:(the latest release/最新リリース)'))
* An active developer(('note:(アクティブな開発者)'))

(('tag:margin-top * 10'))

Feature (1)n(('note:機能(1)'))

Effective serializationn (('note:効率的なシリアライズ'))

Why effective?n(('note:なぜ効率的なのか'))

* Don't parse data\n
  (('note:データをパースしないから'))
* Use data directly\n
  (('note:データをそのまま使うから'))

Data format: Numbern(('note:データフォーマット:数値'))

Contiguous data (Same as C array)
連続データ(Cの配列と同じ)

32bit integer: [1, 2, 3]
0x01 0x00 0x00 0x00 0x02 0x00 0x00 0x00 0x03 ...

Compare to JSONn(('note:JSONと比較'))

    "[1, 2, 3]"
            ↓
"1" → 1 (String → Number)
"2" → 2 (String → Number)
"3" → 3 (String → Number)

Merit of direct data usen(('note:データを直接使うことのメリット'))

* Zero copy cost\n
  (('note:コピーコストをなくせる'))
  * Copy is costly for large data\n
    (('note:大きなデータではコピーはコストが高い'))
* (Nearly) zero parse cost\n
  (('note:(ほぼ)パースコストをなくせる'))
  * Only need to parse metadata\n
    (('note:メタデータをパースするだけでよい'))

Performancen(('note:性能'))

# image
# src = images/serialize-list.png
# relative_height = 77

(('note:((<Fast Python Serialization with Ray and Apache Arrow|URL:arrow.apache.org/blog/2017/10/15/fast-python-serialization-with-ray-and-arrow/>))'))

(('note:Apache License 2.0: © 2016-2019 The Apache Software Foundation'))

Zero copy and large datan(('note:ゼロコピーと大きなデータ'))

* pandas can't process large data\n
  (('note:pandasは大きなデータを扱えない'))
  * Because it needs to allocate memory\n
    (('note:メモリーを確保する必要があるから'))
* Apache Arrow supports memory mapping\n
  (('note:Apache Arrowはメモリーマッピング対応'))
  * Can use data in file directly without copy\n
    (('note:ファイル内のデータをコピーせずに使える'))

Effective string representationn(('note:効率的な文字列表現'))

* pandas: Array of strings\n
  (('note:pandas:文字列の配列'))
  * Use discontiguous memory\n
    (('note:非連続なメモリーを使う'))
* Apache Arrow: Data and array of lengths\n
  (('note:Apache Arrow:データと長さの配列'))
  * Use contiguous memory: Fast\n
    (('note:連続したメモリーを使う:速い'))

Data format: Stringn(('note:データフォーマット:文字列'))

Data bytes + length array

UTT-8 string: ["Hello", "", "!"]
Data bytes: "Hello!"
Length array: [0, 5, 5, 6]
i-th length: lengths[i+1] - lengths[i]
i-th data: data[lengths[i]:lengths[i+1]]

Feature(?) (2)n(('note:機能(?)(2)'))

Specify data formatn (('note:データフォーマットを仕様化'))

Why do Arrow specify?n(('note:なぜArrowは仕様化するのか'))

Effectiven data exchangen (('note:効率的なデータ交換のため'))

Effective data exchangen(('note:効率的なデータ交換'))

* Use common format widely\n
  (('note:みんなが同じフォーマットを使うこと'))
  * No format conversion reduces resource usage\n
    (('note:フォーマットを変換しなくてよいならリソース使用量を減らせる'))
* Use low {,de}serialize cost format\n
  (('note:シリアライズコストが低いフォーマットを使うこと'))
  * Fast

Who uses Arrow format?n(('note:Arrowフォーマットをだれが使っているか'))

* ((<RAPIDS|URL:https://rapids.ai/>)): For NVIDIA GPU
* ((<Fletcher|URL:https://github.com/johanpel/fletcher>)), ((<InAccel|URL:https://docs.inaccel.com/latest/manager/examples/#logistic-regression-with-apache-arrow>)): For FPGA
* ((<Spark|URL:https://spark.apache.org/>)): For interprocess data exchange\n
  (('note:Spark:プロセス間のデータ交換のために'))

CPU and GPU

* Can't share data on memory\n
  (('note:メモリー上のデータを共有できない'))
* Need to copy between CPU and GPU\n
  (('note:CPUとGPU間でコピーする必要がある'))
  * Effective data exchange improves performance\n
    (('note:データ交換を効率化することで高速化'))

CPU and FPGA

* Can't share data on memory\n
  (('note:メモリー上のデータを共有できない'))
* Need to copy between CPU and FPGA\n
  (('note:CPUとFPGA間でコピーする必要がある'))
  * Effective data exchange improves performance\n
    (('note:データ交換を効率化することで高速化'))

Spark

* Process large data\n
  (('note:大きなデータを処理'))
* Need to pass data to worker processes\n
  (('note:ワーカープロセスにデータを渡す必要がある'))
  * Effective data exchange improves performance\n
    (('note:データ交換を効率化することで高速化'))

PySpark

* Worker by Python\n
  (('note:ワーカーはPython'))
  * Use pikcle to exchange data\n
    (('note:データ交換にpickleを使用'))
* Spark supports Arrow for data exchange\n
  (('note:Arrowを使ったデータ交換をサポート'))
  * Disabled by default\n
    (('note:デフォルトでは無効'))

PySpark with Arrow

In [2]: %time pdf = df.toPandas()
CPU times: user 17.4 s, sys: 792 ms, total: 18.1 s
Wall time: 20.7 s

In [3]: spark.conf.set("spark.sql.execution.arrow.enabled", "true")

In [4]: %time pdf = df.toPandas()
CPU times: user 40 ms, sys: 32 ms, total: 72 ms
Wall time: 737 ms

(('note:((< Speeding up PySpark with Apache Arrow|URL:arrow.apache.org/blog/2017/07/26/spark-arrow/>))'))

Feature (3)n(('note:機能(3)'))

Optimizedn data processingn modulesn (('note:最適化されたデータ処理モジュール'))

Optimized data processingn(('note:最適化されたデータ処理モジュール'))

* Apache Arrow targets large data\n
  (('note:Apache Arrowは大きなデータを対象にしている'))
  * Performance is important\n
    (('note:性能は重要'))
* How to get high performance...?\n
  (('note:どうすれば速くできる。。。?'))

High performance (1)n(('note:高速化(1)'))

Data localityn (('note:データを局所化'))

Data localityn(('note:データを局所化'))

* Minimize cache misses\n
  (('note:キャッシュミスを減らす'))
* Storage is very slow\n
  (('note:ストレージはすごく遅い'))
* Memory is slow\n
  (('note:メモリーは遅い'))
* CPU cache is fast\n
  (('note:CPUキャッシュは速い'))

High performance (2)n(('note:高速化(2)'))

SIMDn (('note:Single Instruction Multi Data'))n (('note:一気に複数のデータを処理する方法'))

SIMD

* Data must be contiguous and aligned\n
  (('note:データは連続していてアラインされていないといけない'))
  * Arrow format is SIMD ready\n
    (('note:ArrowフォーマットはSIMDを使える'))
* No condition branch\n
  (('note:条件分岐がないこと'))
  * Use bitmap instead of "missing" for null\n
    (('note:nullを表現するために「欠損値」ではなく別途ビットマップを使う'))\n
    (('note:((<"Is it time to stop using sentinel values for null / NA values?"|URL:http://wesmckinney.com/blog/bitmaps-vs-sentinel-values/>))'))

No condition branchn(('note:条件分岐なし'))

# img
# src = images/simd-null.svg
# relative_height = 100

Slide property

: enable-title-on-image

false

FYI: nulln(('note:参考情報:null'))

* All data types support null in Arrow\n
  (('note:Arrowはすべての型でnullをサポート'))
* Some types only support null in NumPy\n
  (('note:NumPyは一部の型でnullをサポート'))\n
  (('note:((<欠損値の制約 - PythonとApache Arrow|URL:https://speakerdeck.com/sinhrks/pythontoapache-arrow-eaf72479-ce30-4161-8c73-15b555cc56c7?slide=11>))'))

High performance (3)n(('note:高速化(3)'))

Thread

Thread

* Use multi-cores in single process\n
  (('note:シングルプロセスで複数コアを使う'))
* Minimize resource conflict\n
  (('note:リソースの競合をなくすこと'))
  * Locking to avoid conflict reduces performance\n
    (('note:競合を避けるためにロックすると性能劣化'))
* Approaches(('note:(アプローチ)'))
  * Read only or copy (shared nothing)\n
    (('note:リードオンリーにするかコピー(なにも共有しない)'))

Apache Arrow and threadn(('note:Apache Arrowとスレッド'))

* Data is read only\n
  (('note:データはリードオンリー'))
  * Share data in threads without lock overhead\n
    (('note:ロックのオーバーヘッドなしでスレッド間でデータを共有'))
* Avoid both locking and copying\n
  (('note:ロックもコピーも避ける'))
  * They reduce performance\n
    (('note:どちらも性能劣化するから'))

High performance (4)n(('note:高速化(4)'))

Compute kernelsn (('note:計算カーネル'))

Compute kernelsn(('note:計算カーネル'))

* SIMD ready primitive operations\n
  (('note:SIMDを使ったプリミティブな演算'))
* Projection, Filter, Aggregation, ...\n
  (('note:射影とかフィルターとか集計とかとか'))
  * compare, take, mean, ...\n
    (('note:比較とか行選択とか平均とか'))

High performance (5)n(('note:高速化(5)'))

Subgraph compilern (('note:サブグラフコンパイラー'))

Subgraph compiler: Gandivan(('note:サブグラフコンパイラー:Gandiva'))

* Compile operator graphs at run-time\n
  (('note:実行時に演算グラフをコンパイル'))
  * Operator graph: combined multiple operations\n
    (('note:演算グラフ:演算のまとまり'))
  * (({table.a + table.b < table.c && ...}))
* Usable for query engine backend\n
  (('note:クエリーエンジンのバックエンドとして使える'))

High performance (6)n(('note:高速化(6)'))

Query enginen (('note:クエリーエンジン'))

Query enginen(('note:クエリーエンジン'))

* For single node\n
  (('note:シングルノード向け'))
* Dataflow-style operator execution\n
  (('note:データが流れるように演算を実行'))
  * scan → project → filter → aggregate → ...\n
    (('note:データ取得→射影→フィルター→集計→…'))

(('note:((<Apache Arrow Query Engine for C++|URL:docs.google.com/document/d/10RoUZmiMQRi_J1FcPeVAUAMJ6d_ZuiEbaM2Y33sNPu4/edit#>))'))

Query engine from Pythonn(('note:Pythonからクエリーエンジンを使う'))

* With pandas(('note:(pandasと使う)'))
  * Large data → execute → (({to_pandas()}))\n
    (('note:大きなデータ→実行→(({to_pandas()}))'))
* With Dask(('note:(Daskと使う)'))
  * Dask will be able to use this as backend\n
    (('note:Daskのバックエンドで使えるかも?'))

High performance (7)n(('note:高速化(7)'))

Datasetsn (('note:データセット'))

Datasetsn(('note:データセット'))

* Scan data from storage/database\n
  (('note:ストレージ・データベースからデータ取得'))
  * File systems: local, HDFS, ...
  * Formats: CSV, Parquet, ...
  * Databases: MySQL, PostgreSQL, ...

(('note:((<Apache Arrow C++ Datasets|URL:docs.google.com/document/d/1bVhzifD38qDypnSjtf8exvpP3sSB5x_Kw9m-n66FB2c/edit#heading=h.22aikbvt54fv>))'))

Fast datasetsn(('note:高速なデータセット'))

* Predicate pushdown\n
  (('note:条件のプッシュダウン'))
  * Scan only needed data\n
    (('note:必要なデータのみ取得'))
* Parallel scan\n
  (('note:並列取得'))

Feature (4)n(('note:機能(4)'))

RPC

RPC: Arrow Flight

* Fast RPC framework for Arrow\n
  (('note:Arrow用の高速なRPC'))
* Based on gRPC with low-level extensions\n
  (('note:gRPCベースでいくつか低レベルの拡張をしている'))

(('note:((<Apache 0.11.0 Release|URL:arrow.apache.org/blog/2018/10/09/0.11.0-release/>))'))

Wrap upn(('note:まとめ'))

* Arrow is useful for SciPy community\n
  (('note:SciPyコミュニティーにArrowは有用'))
  * in not only Python but also other languages\n
    (('note:Pythonだけでなく他の言語でも有用'))
* Join Apache Arrow development!\n
  (('note:Apache Arrowの開発に参加しよう!'))
  * Ask me how to start\n
    (('note:なにから始めればよいかは私に相談してね'))

Next stepn(('note:次の一歩'))

* ((<Mailing list|URL:https://lists.apache.org/list.html?dev@arrow.apache.org>)): dev@arrow.apache.org
* Chat in Japanese:
  * ((<URL:https://gitter.im/apache-arrow-ja/community>))
* Apache Arrow Tokyo Meetup 2019 (('note:this summer?'))
  * See also: ((<Apache Arrow Tokyo Meetup 2018|URL:https://speee.connpass.com/event/103514>))