Apache Arrowフォーマットはnなぜ速いのか¶ ↑
: author
須藤功平
: institution
株式会社クリアコード
: content-source
db tech showcase ONLINE 2020
: date
2020-12-08
: start-time
2020-12-08T15:30:00+09:00
: end-time
2020-12-08T16:10:00+09:00
: theme
.
Apache Arrowと私¶ ↑
* 2016-12-21に最初のコミット * 2017-05-10にコミッター * 2017-09-15にPMCメンバー * 2020-11-25現在コミット数2位(508人中)
Apache Arrow¶ ↑
* データ分析ツールの基盤を提供 * ツールで必要になるやつ全部入り * 各種プログラミング言語をサポート
全部ってなに!?¶ ↑
(('tag:left')) (('tag:wrap-word-char')) (('tag:justify')) データフォーマットとかそのデータを高速処理する機能とか他の各種データフォーマットと変換する機能とかローカル・リモートにあるデータを透過的に読み書きする機能とか高速RPCとかなんだけど、全部を説明すると「すごそうだけどよくわからないね!」と言われる!
今日のトピック¶ ↑
Apache Arrownフォーマット
Apache Arrowフォーマット¶ ↑
* データフォーマット * 通信用とインメモリー用の両方 * 表形式のデータ用 * =データフレーム形式のデータ用 * 速い!
速い!¶ ↑
* データ((*交換*))が速い! * データ((*処理*))が速い!
データ交換が速い!¶ ↑
(('tag:center')) (('tag:margin-bottom * -0.5')) Apache Arrowフォーマットにすると高速化!
# image # src = images/apache-arrow-and-data-interchange.svg # relative-height = 100
利用事例:Apache Spark¶ ↑
# image # src = images/apache-arrow-and-apache-spark.svg # relative-height = 100
スライドプロパティー¶ ↑
: enable-title-on-image
false
利用事例:Amazon Athena¶ ↑
# image # src = images/apache-arrow-and-amazon-athena.svg # relative-height = 100
スライドプロパティー¶ ↑
: enable-title-on-image
false
利用事例:RAPIDS¶ ↑
# image # src = https://docs.rapids.ai/overview/RAPIDS%200.15%20Release%20Deck.pdf # page = 3 # relative-height = 130 # relative-clip-y = 15 # relative-clip-height = 70
(('tag:right')) (('tag:margin-top * 6')) (('note:((<URL:docs.rapids.ai/overview/RAPIDS%200.15%20Release%20Deck.pdf#page=3>))'))
スライドプロパティー¶ ↑
: enable-clear-blue-slide-body-vertical-centering
false
: enable-title-on-image
false
利用事例:RAPIDS¶ ↑
# image # src = https://docs.rapids.ai/overview/RAPIDS%200.15%20Release%20Deck.pdf # page = 8 # relative-height = 120 # relative-clip-y = 15 # relative-clip-height = 80
(('tag:right')) (('tag:margin-top * 5')) (('note:((<URL:docs.rapids.ai/overview/RAPIDS%200.15%20Release%20Deck.pdf#page=8>))'))
スライドプロパティー¶ ↑
: enable-clear-blue-slide-body-vertical-centering
false
: enable-title-on-image
false
どうして速いの?¶ ↑
* シリアライズコストが低い * すぐに送れるようになる * デシリアライズコストが低い * 受け取ったデータをすぐに使えるようになる
シリアライズ処理¶ ↑
(1) メタデータを用意 (2) メタデータ+元データそのものを送信 * 元データを加工しないから速い! * なにもしないのが最速!
元データを加工する例:JSON¶ ↑
0x01 0x02(8bit数値の配列) ↓ "[1,2]"(JSON) 0x01→0x49(数値→ASCIIの文字:'1') 0x02→0x50(数値→ASCIIの文字:'2')
元データそのものを使うと…¶ ↑
* 変換処理にCPUを使わなくてよい * 速い * 変換後のデータ用のメモリー確保ゼロ * 大きなメモリー確保はコストが高い * 一定の作業領域を使い回すとかしなくてよい * 速い
デシリアライズ処理¶ ↑
(1) メタデータをパース (2) メタデータを基に元データを取り出す * 元データをそのまま使えるから速い! * なにもしないのが最速!
元データを元に戻す例:JSON¶ ↑
"[1,2]"(JSON) ↓ 0x01 0x02(8bit数値の配列) 0x49→0x01(ASCIIの文字:'1'→数値) 0x50→0x02(ASCIIの文字:'2'→数値)
元データを取り出せると…¶ ↑
* 変換処理にCPUを使わなくてよい * 速い * 変換後のデータ用のメモリー確保ゼロ * すでにあるデータをそのまま使うのでゼロコピー * 速い * メモリーマップで直接データを使える * ディスク上のメモリー以上のデータを扱える
{,デ}シリアライズコスト¶ ↑
* Apache Arrowフォーマット * ほぼメタデータのパースコストだけ * それ以外の多くのフォーマット * データ変換処理(CPU) * 作業用メモリー確保処理(メモリー)
データ交換が速い!¶ ↑
(('tag:center')) (('tag:margin-bottom * -0.5')) Apache Arrowフォーマットにすると高速化!
# image # src = images/apache-arrow-and-data-interchange.svg # relative-height = 100
利用事例:Apache Spark¶ ↑
# image # src = images/apache-arrow-and-apache-spark.svg # relative-height = 100
スライドプロパティー¶ ↑
: enable-title-on-image
false
利用事例:Amazon Athena¶ ↑
# image # src = images/apache-arrow-and-amazon-athena.svg # relative-height = 100
スライドプロパティー¶ ↑
: enable-title-on-image
false
利用事例:RAPIDS¶ ↑
# image # src = https://docs.rapids.ai/overview/RAPIDS%200.15%20Release%20Deck.pdf # page = 8 # relative-height = 120 # relative-clip-y = 15 # relative-clip-height = 80
(('tag:right')) (('tag:margin-top * 5')) (('note:((<URL:docs.rapids.ai/overview/RAPIDS%200.15%20Release%20Deck.pdf#page=8>))'))
スライドプロパティー¶ ↑
: enable-clear-blue-slide-body-vertical-centering
false
: enable-title-on-image
false
データサイズは?¶ ↑
* CPU・メモリーにやさしくて速いんだね! * じゃあ、データサイズはどうなの? * 大きいとネットワーク・IOがボトルネック * 本来のデータ処理を最大限リソースを使いたい * データ交換をボトルネックにしたくない
データサイズ¶ ↑
* 別に小さくない * 元データそのままなのでデータ量に応じて増加 * Zstandard・LZ4での圧縮をサポート * ゼロコピーではなくなるがサイズは数分の1 * 圧縮・展開が必要→元データそのものを使えない * CPU・メモリー負荷は上がるが\n ネットワーク・IO負荷は下がる * ネットワーク・IOがボトルネックになるなら効く
圧縮時のデータサイズと読み込み速度¶ ↑
# image # src = https://ursalabs.org/20200414_file_sizes.png # align = left # vertical-align = top # relative-width = 75 # image # src = https://ursalabs.org/20200414_read_py.png # align = right # vertical-align = bottom # relative-width = 75 # relative-clip-y = 12 # relative-margin-top = 12 # relative-margin-left = -3.8
(('tag:right')) (('tag:margin-top * 15')) (('note:((<URL:ursalabs.org/blog/2020-feather-v2/>))'))
スライドプロパティー¶ ↑
: enable-clear-blue-slide-body-vertical-centering
false
: enable-title-on-image
false
データ交換が速い!のまとめ¶ ↑
* {,デ}シリアライズが速い * 元データをそのまま使うので処理が少ない * CPU・メモリーにやさしい * 圧縮もサポート * ネットワーク・IOがボトルネックならこれ * CPU・メモリー負荷は上がるが\n データ交換のボトルネックを解消できるかも
交換したデータの扱い¶ ↑
* データ分析はデータ交換だけじゃない * データ交換だけ速くしても基盤とは言えない * データ処理も速くしないと! * データ処理を速くするにはデータ構造が大事
高速処理のためのデータ構造¶ ↑
* 基本方針: * 関連するデータを近くに置く * 効果: * CPUキャッシュミスを減らす * SIMDを活用できる
データ分析時の関連データ¶ ↑
* 分析時はカラムごとの処理が多い * 集計・ソート・絞り込み… * 同じカラムのデータを近くに置く * カラムナーフォーマット
カラムナーフォーマット¶ ↑
# img # src = images/columnar.svg # relative_height = 100
スライドプロパティー¶ ↑
: enable-title-on-image
false
各カラムでのデータの配置¶ ↑
* 関連するデータを近くに置く * 定数時間でアクセスできるように置く * SIMDできるように置く * アラインする\n (('note:アライン:データの境界を64の倍数とかに揃える')) * 条件分岐をなくす
真偽値・数値のデータの配置¶ ↑
固定長データなので連続して配置 32ビット整数:[1, 2, 3] 0x01 0x00 0x00 0x00 0x02 0x00 0x00 0x00 0x03 ...
文字列・バイト列:データの配置¶ ↑
実データバイト列+長さ配列に配置 UTF-8文字列:["Hello", "", "!"] 実データバイト列:"Hello!" 長さ配列:[0, 5, 5, 6] i番目の長さ:長さ配列[i+1] - 長さ配列[i] i番目のデータ: 実データバイト列[長さ配列[i]..長さ配列[i+1]] 注:長さ→データ→長さ→データ→…で置くと 定数時間でi番目にアクセスできない
nullと条件分岐¶ ↑
* null対応のアプローチ: * null値:Julia: ((<(({missing}))|URL:https://docs.julialang.org/en/v1/manual/missing/>)), R: ((<(({NA}))|URL:https://cran.r-project.org/doc/manuals/r-release/R-lang.html#NA-handling>)) * 別途ビットマップを用意:Apache Arrow * ビットマップを使うと条件分岐をなくせる
nullと条件分岐とSIMD¶ ↑
# img # src = images/simd-null.svg # relative_height = 100
スライドプロパティー¶ ↑
: enable-title-on-image
false
nullと条件分岐とSIMD¶ ↑
# image # src = https://wesmckinney.com/images/bitmaps_vs_sentinels.png # relative-height = 90
(('tag:right')) (('note:((<URL:wesmckinney.com/blog/bitmaps-vs-sentinel-values/>))'))
スライドプロパティー¶ ↑
: enable-clear-blue-slide-body-vertical-centering
false
: enable-title-on-image
false
高速なデータ処理のまとめ¶ ↑
* 高速なデータ処理にはデータ構造が重要 * データ分析にはカラムナーフォマットが適切 * 定数時間でアクセス可能なデータの配置 * SIMDにやさしいデータの持ち方 * アライン・null用のビットマップ
まとめ¶ ↑
* Apache Arrow * なんかデータ分析に便利そうなすごいやつ! * 「よくわからん」と言われるからといって\n 全体像を説明してもらえなかった! * 使い方も説明してもらえなかった! * Apache Arrowフォーマット * これだけ説明してもらえた!
まとめ:Apache Arrowフォーマット¶ ↑
* Apache Arrowフォーマット * 通信用・インメモリー用のデータフォーマット * 表形式のデータ用 * Apache Arrowフォーマットは速い * データ((*交換*))が速い * データ((*処理*))が速い * データ交換してすぐに高速処理できるフォーマット
まとめ:なぜデータ交換が速いのか¶ ↑
* 元データをそのままやりとりできるから * {,デ}シリアライズコストが低い * CPU・メモリーにやさしい * ネットワーク・IOの負荷を下げたい * Zstandard・LZ4による圧縮 * CPU・メモリー負荷は上がるが\n ネットワーク・IO負荷は下がる
まとめ:なぜデータ処理が速いのか¶ ↑
* 最適化されたデータ構造 * カラムナーフォーマット * SIMDを使えるデータの持ち方 * 最適化された実装 * (('wait'))今回は紹介していない!!!
次回予告!¶ ↑
* 案1:Apache Arrowデータの高速処理 * 案2:Apache Arrowデータの高速RPC * 案3:○○言語でApache Arrowを使う方法 * ...
次のステップ¶ ↑
* もっと詳しく知りたくなったから\n イベント・社内・…で紹介して! * ((<URL:https://www.clear-code.com/contact/>)) * 使いたくなったから技術サポートして! * ((<URL:https://www.clear-code.com/contact/>)) * Apache Arrowの開発に参加したい! * ((<URL:https://arrow.apache.org/community/>))