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>))