Skip to main content
Writable Arrow_Fdw
HeteroDB,Inc
Chief Architect & CEO
KaiGai Kohei <kaigai@heterodb.com>
Arrowって何よ?(1/3)
▌Apache Arrow 形式
 構造化データを列形式で保存・交換するためのデータ形式。
 “ビッグデータ処理” 向けデータ交換の形式として広く利用されつつある。
✓Spark、Impala、Drill、Python (PyArrow)、R、etc...
 整数、実数、日付時刻、文字列など基本的なデータ型を定義。
NVIDIA GPU
PostgreSQL / PG-Strom
PostgreSQL Unconference Apr-20202
Arrowって何よ?(2/3)
▌Apache Arrow形式の内部構造
 Header
• “ARROW1¥0¥0” という文字列。
 Schema Definition
• 列定義情報。データ型、列名、列番号など。
 Record Batch
• 一定の行数のデータを列形式で配置したブロック
• 例えば、N = 100万行で (Int32, Float64) というデータ
定義なら、Int32が100万個並び、次いで Float64 が
100万個並んでこの領域に書き込まれる。
 Dictionary Batch
• 辞書圧縮のための領域。
1 = 東京都、2 = 神奈川県、3 = 大阪府、、、
• 処理系がきちんと対応していたら褒めてあげて。
 Footer
• RecordBatchやDictionaryBatchのオフセット、サイズな
どの情報を保持する。
Header “ARROW1¥0¥0”
Schema Definition
DictionaryBatch-0
RecordBatch-0
RecordBatch-k
Footer
• DictionaryBatch[0] (offset, size)
• RecordBatch[0] (offset, size)
:
• RecordBatch[k] (offset, size)
Apache Arrow ファイル
PostgreSQL Unconference Apr-20203
Arrowって何よ?(3/3)-参考:列データと可変長データ
▌詳しく知りたい方は、@stou さんの発表資料をご覧ください
 Apache Arrow 東京ミートアップ
https://www.slideshare.net/kou/apachearrowtokyomeetup2018
 Apache Arrowの最新情報(2019年9月版)
https://www.clear-code.com/blog/2019/9/30.html
列A (Int32) - nullmap
列A (Int32) - values
列B (Utf8) - nullmap
列B (Utf8) - offset
列B (Utf8) - values
RecordBatch
1101101
12 34 0 56 78 0 89
列A (Int32) - nullmap
列A (Int32) - values
1101101
0 5 8 8 13 17 17
列B (Utf8) - nullmap
列B (Utf8) - offset
列B (Utf8) - values
‘R’ ‘a’ ‘m’ ‘e’ ‘n’ ‘I’ ‘c’ ‘e’ ‘C’ ‘u’ ‘r’
21
文字列長 = offset[i+1] - offset[i]
PostgreSQL Unconference Apr-20204
Arrow_Fdwって?(1/2)
PostgreSQL
Table
Foreign Table
file_fdw
Foreign Table
Arrow_fdw
CSVファイル Apache Arrow
ファイル
CSV➔Heap変換 ArrowHeap変換
Apache Arrow形式のファイルを、
あたかも PostgreSQL のテーブル
であるかのように読み書きする
ためのドライバ機能
PostgreSQL Unconference Apr-20205
Arrow_Fdwって?(2/2)
ファイルをコピーするだけでデータのインポートが完了する。
データ
ソース
Apache Arrow
INSERT INTO ...
COPY FROM ...
cp -f /path/from/source
/path/to/destination
• バイナリ互換データ形式
• 非トランザクショナル
従来の方法
• テキスト ➔ バイナリ変換
• トランザクションログにも書き出し
PostgreSQL Unconference Apr-20206
ログ収集デーモン:
想定利用シーン:IoT/M2Mログの集計・解析処理
PostgreSQL Unconference Apr-20207
Manufacturing Logistics Mobile Home electronics
なぜApache Arrowか?
 分析のためにDBへデータを取り込む時間が馬鹿にならない。
 列データ形式なので、プロセッサ・I/Oの使用効率が高い。
JBoF: Just Bunch of Flash
NVME-over-Fabric
(RDMA)
DB管理者
BIツール(可視化)
機械学習アプリケーション
(E.g, 異常検知など)
共通データ
フレーム PG-Strom
Apache Arrowファイルの作り方
▌バイナリをゴニョる。
 KaiGaiの俺メモ:Dive into Apache Arrow(その1)
https://kaigai.hatenablog.com/entry/2019/01/14/144040
▌Pythonなどでライブラリを利用
 例えば、PyArrowのIPCモジュールを使って Data Frame を書き出す、など。
▌pg2arrow / mysql2arrow コマンド
 PostgreSQLやMySQLで実行したクエリの結果を Arrow 形式で書き出す
ためのコマンド。
 使用例)
% pg2arrow -h localhost -d pgsql ¥
-c ‘SELECT * FROM hoge’ ¥
-o /dev/shm/hoge.arrow
▌書き込み可能 Arrow_Fdw 外部テーブル
 Arrow_FdwへのINSERTをRecordBatchの追加と捉えて、外部テーブルの背後に
存在する Apache Arrow ファイルへ追記するための機能。
PostgreSQL Unconference Apr-20208
Writable Arrow_Fdw 外部テーブルを定義する
▌ポイント
① 外部テーブルのバックエンドに指定するファイルは1個だけ
② writableオプションに ‘true’ を指定する。
▌定義例
=# CREATE FOREIGN TABLE ft (
id int,
x real,
y real,
z real
) SERVER arrow_fdw
OPTIONS (file '/dev/shm/ft.arrow', writable 'true');
CREATE FOREIGN TABLE
PostgreSQL Unconference Apr-20209
Writable Arrow_Fdw 外部テーブルにINSERTする
=# INSERT INTO ft (SELECT x, pgstrom.random_float(1, -1000, 1000),
pgstrom.random_float(1, -1000, 1000),
pgstrom.random_float(1, -1000, 1000)
FROM generate_series(1,500) x);
=# SELECT * FROM ft limit 10;
id | x | y | z
----+------------+------------+------------
1 | -796.3072 | -980.48663 | 854.43024
2 | -167.9222 | 860.1901 | 158.72714
3 | 257.10052 | 835.6227 | 536.2602
4 | 34.197735 | 328.64984 | 427.6224
5 | -713.2156 | 27.131866 | 156.22997
6 | -271.762 | 20.40196 | 526.8236
7 | -251.07478 | -567.57733 | 623.1641
8 | -936.90576 | -843.47284 | -65.439545
9 | -908.04553 | 426.0469 | -399.97433
10 | -549.8333 | 651.3198 | 792.652
(10 rows)
PostgreSQL Unconference Apr-202010
生成された Apache Arrow ファイルを確認する
$ python3
>>> import pyarrow as pa
>>> f = pa.ipc.open_file('/dev/shm/ft.arrow')
>>> f.schema
id: int32
x: float
y: float
z: float
>>> f.get_record_batch(0).to_pandas()
id x y z
0 1 -796.307190 -980.486633 854.430237
1 2 -167.922195 860.190125 158.727142
2 3 257.100525 835.622681 536.260193
3 4 34.197735 328.649841 427.622406
4 5 -713.215576 27.131866 156.229965
.. ... ... ... ...
495 496 759.468506 866.489990 -883.853699
496 497 997.161987 70.487015 -544.648804
497 498 -883.911377 647.152466 -504.539886
498 499 -803.238892 -566.325012 -612.984070
499 500 40.926250 -209.205719 911.291443
[500 rows x 4 columns]
当然だが、SQLで
確認した結果と同じ
PostgreSQL Unconference Apr-202011
Arrowファイルへの追記メカニズム
Header “ARROW1¥0¥0”
Schema Definition
DictionaryBatch-0
RecordBatch-0
RecordBatch-k
Footer
• DictionaryBatch[0]
• RecordBatch[0]
:
• RecordBatch[k]
Arrowファイル(追記前)
Header “ARROW1¥0¥0”
Schema Definition
DictionaryBatch-0
RecordBatch-0
RecordBatch-k
Footer (new revision)
• DictionaryBatch[0]
• RecordBatch[0]
:
• RecordBatch[k]
• RecordBatch[k+1]
Arrowファイル(追記後)
RecordBatch-(k+1)
オリジナルの
フッターを
上書きする
1回の INSERT で
書き込まれた内容
PostgreSQL Unconference Apr-202012
Arrowファイルへの追記メカニズム
Header “ARROW1¥0¥0”
Schema Definition
DictionaryBatch-0
RecordBatch-0
RecordBatch-k
Footer
• DictionaryBatch[0]
• RecordBatch[0]
:
• RecordBatch[k]
Arrowファイル(追記前)
Header “ARROW1¥0¥0”
Schema Definition
DictionaryBatch-0
RecordBatch-0
RecordBatch-k
Footer (new revision)
• DictionaryBatch[0]
• RecordBatch[0]
:
• RecordBatch[k]
• RecordBatch[k+1]
Arrowファイル(追記後)
RecordBatch-(k+1)
オリジナルの
フッターを
上書きする
Footer
• DictionaryBatch[0]
• RecordBatch[0]
:
• RecordBatch[k]
元のフッタのイメージと
オフセット、サイズを
バックアップしておけば、
ロールバックも可能
PostgreSQL Unconference Apr-202013
ROLLBACKもできるYO!!
postgres=# INSERT INTO ft VALUES (1,'Tokyo'),(2,'Osaka');
INSERT 0 2
postgres=# BEGIN;
BEGIN
postgres=# INSERT INTO ft VALUES (3,'Nagoya'),(4,'Kyoto');
INSERT 0 2
postgres=# SELECT * FROM ft;
id | x
----+--------
1 | Tokyo
2 | Osaka
3 | Nagoya
4 | Kyoto
(4 rows)
PostgreSQL Unconference Apr-202014
ROLLBACKもできるYO!!
postgres=# SAVEPOINT sv;
SAVEPOINT
postgres=# INSERT INTO ft VALUES (5, 'Yokohama');
INSERT 0 1
postgres=# SELECT * FROM ft;
id | x
----+----------
1 | Tokyo
2 | Osaka
3 | Nagoya
4 | Kyoto
5 | Yokohama
(5 rows)
PostgreSQL Unconference Apr-202015
ROLLBACKもできるYO!!
postgres=# ROLLBACK TO sv;
ROLLBACK
postgres=# SELECT * FROM ft;
id | x
----+--------
1 | Tokyo
2 | Osaka
3 | Nagoya
4 | Kyoto
(4 rows)
postgres=# ABORT;
ROLLBACK
postgres=# SELECT * FROM ft;
id | x
----+-------
1 | Tokyo
2 | Osaka
(2 rows)
PostgreSQL Unconference Apr-202016
Writable Arrow_Fdwの制限事項
▌INSERTのみサポート
 UPDATE / DELETEはできません。
 そもそも Apache Arrow はそういうファイル形式ではありません。
▌同時に書き込みできるのは1トランザクションのみ
 バルクロード以外の用途で使うとは思っていないので…。
▌データを消去したい時は TRUNCATE で消去した後、再ロード
 と、思ったら、PostgreSQL v13では外部テーブルの
TRUNCATE が入らなかったので、当面の間は代わりに↓を。。。
pgstrom.arrow_fdw_truncate(regclass)
PostgreSQL Unconference Apr-202017
関連情報
▌リポジトリ
 https://github.com/heterodb/pg-strom
※ Arrow_FdwはPG-Stromの機能の一つとして実装されています
▌ドキュメント
 PG-Strom公式ドキュメント:列指向データストア (Arrow_Fdw)
http://heterodb.github.io/pg-strom/ja/arrow_fdw/
▌パッケージの入手
 HeteroDB Software Distribution Center
https://heterodb.github.io/swdc/
PostgreSQL Unconference Apr-202018
お知らせ ー GPU版PostGISのテストケースを作る人募集
https://heterodb.com/recruit/
PostgreSQL Unconference Apr-202019
20200424_Writable_Arrow_Fdw