= Apache Arrow
: subtitle
A cross-language development platform\nfor in-memory data
: author
Kouhei Sutou
: institution
ClearCode Inc.
: content-source
SciPy Japan 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 2004\n
(('note:2004年からRubyコミッター'))
= Why do I talk at SciPy?\n(('note:なぜSciPyで話しているのか?'))
To introduce\n
((*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-language\n(('note:多言語対応'))
* C, C++, C#, Go, Java,
* JavaScript, MATLAB, ((*Python*)),
* R, ((*Ruby*)) and Rust
= Development platform\n(('note:開発プラットフォーム'))
Apache Arrow ...
* specifies standards and\n
(('note:標準化'))
* provides implementations\n
(('note:実装'))
to advance cooperation by many people\n
(('note:多くの人が協力できるように'))
= For in-memory data\n(('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 Python\n(('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 me\n(('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 serialization\n
(('note:効率的なシリアライズ'))
= Why effective?\n(('note:なぜ効率的なのか'))
* Don't parse data\n
(('note:データをパースしないから'))
* Use data directly\n
(('note:データをそのまま使うから'))
= Data format: Number\n(('note:データフォーマット:数値'))
Contiguous data (Same as C array)
連続データ(Cの配列と同じ)
32bit integer: [1, 2, 3]
0x01 0x00 0x00 0x00 0x02 0x00 0x00 0x00 0x03 ...
= Compare to JSON\n(('note:JSONと比較'))
"[1, 2, 3]"
↓
"1" → 1 (String → Number)
"2" → 2 (String → Number)
"3" → 3 (String → Number)
= Merit of direct data use\n(('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:メタデータをパースするだけでよい'))
= Performance\n(('note:性能'))
# image
# src = images/serialize-list.png
# relative_height = 77
(('note:(())'))
(('note:Apache License 2.0: (c) 2016-2019 The Apache Software Foundation'))
= Zero copy and large data\n(('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 representation\n(('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: String\n(('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 format\n
(('note:データフォーマットを仕様化'))
= Why do Arrow specify?\n(('note:なぜArrowは仕様化するのか'))
Effective\n
data exchange\n
(('note:効率的なデータ交換のため'))
= Effective data exchange\n(('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フォーマットをだれが使っているか'))
* (()): For NVIDIA GPU
* (()), (()): For FPGA
* (()): 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:https://arrow.apache.org/blog/2017/07/26/spark-arrow/>))'))
= Feature (3)\n(('note:機能(3)'))
Optimized\n
data processing\n
modules\n
(('note:最適化されたデータ処理モジュール'))
= Optimized data processing\n(('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 locality\n
(('note:データを局所化'))
= Data locality\n(('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)'))
SIMD\n
(('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 branch\n(('note:条件分岐なし'))
# img
# src = images/simd-null.svg
# relative_height = 100
== Slide property
: enable-title-on-image
false
= FYI: null\n(('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 thread\n(('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 kernels\n
(('note:計算カーネル'))
= Compute kernels\n(('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 compiler\n
(('note:サブグラフコンパイラー'))
= Subgraph compiler: Gandiva\n(('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 engine\n
(('note:クエリーエンジン'))
= Query engine\n(('note:クエリーエンジン'))
* For single node\n
(('note:シングルノード向け'))
* Dataflow-style operator execution\n
(('note:データが流れるように演算を実行'))
* scan → project → filter → aggregate → ...\n
(('note:データ取得→射影→フィルター→集計→…'))
(('note:(())'))
= Query engine from Python\n(('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)'))
Datasets\n
(('note:データセット'))
= Datasets\n(('note:データセット'))
* Scan data from storage/database\n
(('note:ストレージ・データベースからデータ取得'))
* File systems: local, HDFS, ...
* Formats: CSV, Parquet, ...
* Databases: MySQL, PostgreSQL, ...
(('note:(())'))
= Fast datasets\n(('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:(())'))
= Wrap up\n(('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 step\n(('note:次の一歩'))
* (()): dev@arrow.apache.org
* Chat in Japanese:
* (())
* Apache Arrow Tokyo Meetup 2019 (('note:this summer?'))
* See also: (())