Rabbit Slide Show

Apache Arrow Flight SQLでPostgreSQLをもっと速く!

2023-11-24

Description

PostgreSQLとの接続には独自プロトコルが使われていますが、やりとりするデータが大きくなるとクエリーの処理ではなくこのプロトコルがボトルネックになることが知られています。Apache ArrowFlight SQLプロトコルはこのボトルネックを解消できるプロトコルです。Apache Arrow Flight SQLの詳細、どのくらい速くなるのか、プロトコルを拡張する仕組みのないPostgreSQLでどのように実装したのかといった実装の詳細を紹介します。

Text

Page: 1

Apache Arrow Flight SQLで
PostgreSQLをもっと速く!
須藤功平
株式会社クリアコード
PostgreSQL Conference Japan 2023
2023-11-24
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 2

対象ユースケース
✓ ETL/ELT (Extract, Transform, Load)
✓ PostgreSQLからの大量データの読み込み
✓ PostgreSQLへの大量データの書き込み
✓ 探索的データ分析
✓ PostgreSQL内のデータを理解
✓ サブセットをローカルにダウンロードし、
インタラクティブに集計・加工・可視化など
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 3

対象ユースケースの特徴
✓ 大量ローカルデータ→PostgreSQLデータ
✓ 大量PostgreSQLデータ→ローカルデータ
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 4

対象ユースケースの処理
PostgreSQL
ローカル
alt
[ロード]
INSERT/COPY用にデータを変換
データ送信
データ保存
[抽出]
データ送信
ローカル用にデータを変換
ローカル
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
PostgreSQL
Powered by Rabbit 3.0.4

Page: 5

注目ポイント
PostgreSQL
ローカル
alt
[ロード]
INSERT/COPY用にデータを変換
データ送信
データ保存
データ変換処理
[抽出]
データ送信
ローカル用にデータを変換
ローカル
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
PostgreSQL
Powered by Rabbit 3.0.4

Page: 6

なぜデータ変換処理に注目するのか
データ量に比例する処理だから
↓
大量データだと影響が大きい
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 7

高速化アプローチ
低データ変換コストの
フォーマットを使う
↓
Apache Arrow
フォーマット
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 8

自己紹介
✓ 須藤功平/@kou/@ktou
✓ Apache Arrowのコミット数1位
✓ Apache Arrowの3代目PMC代表
PMC:プロジェクト管理委員会
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 9

Apache Arrowフォーマット
✓ データ交換に最適化
✓ パースコストほぼ0
✓ データ転送コストのみで交換できる
✓ インメモリーのデータ分析に最適化
✓ ローカルデータの表現としても優秀
✓ 受け取ったデータをそのまま使える
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 10

高速化ポイント
PostgreSQL
ローカル
alt
[ロード]
INSERT/COPY用にデータを変換
データ送信
データ保存
速くなる!
[抽出]
データ送信
ローカル用にデータを変換
ローカル
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
PostgreSQL
Powered by Rabbit 3.0.4

Page: 11

実現方法
✓ PostgreSQLプロトコルで
Apache Arrowを扱えるようにする
✓ COPYのFORMATでApache Arrowサポート
✓ Apache Arrowを扱える
別のプロトコルを使う
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 12

COPYでApache Arrow
✓ メリット:
✓ 既存の仕組み・ツールを使える
✓ デメリット:
✓ PostgreSQL開発者は受け入れてくれるのか?
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 13

Apache Arrow対応の別プロトコル
✓ メリット:
✓ PostgreSQLの拡張機能で実現すれば
PostgreSQLとは独立して開発できる
✓ デメリット:
✓ 既存の仕組み・ツールを使えない
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 14

選んだ方法
Apache Arrow対応の
別プロトコル
↓
Apache Arrow
Flight SQL
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 15

Apache Arrow Flight SQL
✓ クエリー言語:SQL
✓ PostgreSQLになじむ
✓ データフォーマット:Apache Arrow
✓ 高速化できる
✓ ベースのプロトコル:gRPC
✓ 既存の仕組みを再利用できる
注意:まだexperimentalなプロトコル
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 16

別プロトコルを選んだ理由
✓ Apache Arrowでこの問題を解決できるか
広く検証したい
✓ PostgreSQLの変更だと試してくれる人が少なそう
✓ PostgreSQL開発者と相談するには
Apache Arrowでどのくらい改善するかの
データが必要
✓ このアプローチでの実績をもって
PostgreSQL開発者と相談したい
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 17

実現方法
✓ PostgreSQLの拡張機能として実装
✓ Apache Arrow Flight SQL adapter for PostgreSQL
https://arrow.apache.org/flight-sql-postgresql/
(プロジェクト名が長い!以後AFSと省略)
✓ 別の実現方法
✓ PostgreSQLのリバースプロキシとして実装
例:PostgREST
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 18

新プロトコル対応方法:PostgREST
PostgREST
PostgreSQL
ユーザー
HTTP
PostgreSQLプロトコル
PostgreSQLプロトコル
HTTP
PostgREST
PostgreSQL
ユーザー
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 19

新プロトコル対応方法:AFS
PostgreSQL
AFS
ユーザー
ワーカープロセス起動
Apache Arrow Flight SQL
Apache Arrow Flight SQL
PostgreSQL
AFS
ユーザー
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 20

Apache Arrowで速くなるのか?
✓ 検証1:integerのSELECT
✓ 検証2:stringのSELECT
✓ 検証3:integerのINSERT
✓ 検証4:stringのINSERT
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 21

検証1:integerのSELECT
✓ 1カラムのみN件のランダムデータ
✓ N: 10万、100万、1000万
✓ 比較対象
✓ libpqでSELECTして結果をパース:ベースライン
✓ AFS:提案方法
✓ libpqでCOPYして結果をパース:既存の高速な方法
✓ PostgreSQL:17(未リリース)
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 22

検証1:integerのSELECT:結果
✓ バーが短いほど速い
✓ 10万レコードでは
どれも変わらない
✓ ✓AFSが速い
✓ 参考:カラム数が
増えるほど差は開く
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 23

検証2:stringのSELECT
✓ 1カラムのみN件の64バイトランダムデータ
✓ N: 10万、100万、1000万
✓ 比較対象
✓ libpqでSELECTして結果をパース:ベースライン
✓ AFS:提案方法
✓ libpqでCOPYして結果をパース:既存の高速な方法
✓ PostgreSQL:17(未リリース)
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 24

検証2:stringのSELECT:結果
✓ バーが短いほど速い
✓ ✕AFSが遅い
✓ 参考:カラム数が
増えるほど差は開く
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 25

AFSがなぜ遅いか
✓ そもそもSELECT/COPYが速い
✓ データをそのまま送っているのでパースコスト0
✓ 数値は文字列表現→数値の変換が必要
✓ 無駄なデータコピーがある?
✓ SPI_getbinval()が遅い?
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 26

検証3:integerのINSERT
✓ 1カラムのみN件のランダムデータ
✓ N: 10万、100万、1000万
✓ 比較対象
✓ INSERTを作ってlibpqで実行:ベースライン
✓ AFS:提案方法
✓ COPY用データを作って実行:既存の高速な方法
✓ PostgreSQL:17(未リリース)
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 27

検証3:integerのINSERT:結果
✓ バーが短いほど速い
✓ ✕AFSが遅い
✓ COPYが速い
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 28

AFSがなぜ遅いか
✓ N回SPI_execute("INSERT")しているから
✓ 現在はFlight SQLにバルクインサート用APIがない
✓ PREPARE + パラメーターバインドで実現
✓ 今後:
✓ バルクインサート用APIを設計中
https://github.com/apache/arrow/issues/38255
✓ より効率的な内部実装にできる予定
(でもSPIでCOPY FROM STDINを使えないんだよな…)
(SPI_register_relation()は速いのかな?)
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 29

検証4:stringのINSERT
✓ 1カラムのみN件の64バイトランダムデータ
✓ N: 10万、100万、1000万
✓ 比較対象
✓ INSERTを作ってlibpqで実行:ベースライン
✓ AFS:提案方法
✓ COPY用データを作って実行:既存の高速な方法
✓ PostgreSQL:17(未リリース)
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 30

検証4:stringのINSERT:結果
✓ バーが短いほど速い
✓ integerと同じ傾向
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 31

ユーザー向けの話のまとめ
✓ 課題:大量データの読み書きが遅い
✓ 解決方法:
✓ Apache Arrowフォーマット/Flight SQL
✓ 現状:
✓ ✓数値の読み込みは速い→今すぐ体験できる!
✓ ✕文字列の読み込みは遅い→今後に期待!
✓ ✕書き込みは遅い→今後に期待!
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 32

開発者向けの話
✓ Apache Arrow Flight SQL
✓ 認証
✓ 追加プロトコル対応
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 33

Apache Arrow Flight SQL
✓ プロトコル
✓ Apache Arrow(列指向)データに最適化
✓ すでにArrowベースなデータ処理システムになじむ
✓ 例:Polars, pandas, PG-Strom, ...
✓ 複数ノードから並列ダウンロード可
✓ postgres_fdwを使ったPostgreSQLクラスターから
並列ダウンロードとか?
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 34

SELECT
クライアント
サーバー
GetFlightInfo("SELECT ...")
FlightInfo(データ取得のための情報)
DoGet(FlightInfo)
Apache Arrowデータ(ストリームで送信)
クライアント
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
サーバー
Powered by Rabbit 3.0.4

Page: 35

SELECT:並列ダウンロード
クライアント
サーバー
ノード1
ノード2
GetFlightInfo("SELECT ...")
FlightInfo1, FlightInfo2
par
[ノード1からデータ取得]
DoGet(FlightInfo1)
Apache Arrowデータ
[ノード2からデータ取得]
DoGet(FlightInfo2)
Apache Arrowデータ
クライアント
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
サーバー
ノード1
ノード2
Powered by Rabbit 3.0.4

Page: 36

INSERT
クライアント
サーバー
DoAction("CreatePreparedStatement", "INSERT ... VALUES (?)")
ハンドル(プリペアドステートメントのID)
DoPut(ハンドル, Apache Arrowデータ)(ストリームで送信)
変更したレコード数
クライアント
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
サーバー
Powered by Rabbit 3.0.4

Page: 37

INSERT:今後
クライアント
サーバー
これで速くなるといいな!
DoPut(テーブル, Apache Arrowデータ)
変更したレコード数
クライアント
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
サーバー
Powered by Rabbit 3.0.4

Page: 38

開発者向けの話:認証
✓ Apache Arrow Flight SQL
✓ 認証
✓ 追加プロトコル対応
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 39

認証
✓ PGプロトコルを使わない→自前実装が必要
✓ PGの認証実装はPGプロトコルと蜜結合
✓ でも、認証情報の二重管理はしたくない!
✓ →PostgreSQLの認証情報で認証
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 40

PostgreSQLの認証情報
✓ pg_hba.conf
✓ ホストベースの認証情報
✓ 接続可の接続元は?SSLは必須?とか
✓ CREATE ROLE
✓ PostgreSQL内にユーザーを作成
✓ パスワードはPostgreSQLで管理または別途管理
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 41

対応済み認証方法
✓ trust認証
✓ 接続可のホストから接続されればOK
✓ 本番環境では使わないこと!
✓ パスワード認証
✓ PostgreSQL内のパスワードを使って認証
✓ SSLを有効にすること!
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 42

その他の認証方法
✓ scram-sha-256
✓ チャレンジレスポンスが必要なので未対応
✓ 今はHTTP/2のauthorization: Basicを使っている
✓ 証明書認証(mTLS)
(Mutual Transport Layer Security・相互TLS)
✓ サーバーがクライアントの証明書を検証
✓ 簡単に実装できるはずなので実装予定
(実装にはSSL対応が必須)
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 43

SSL対応
✓ 実装済み
✓ Apache Arrow Flight SQLはSSL対応
✓ mTLSにも対応
✓ SSL対応に必要なもの
✓ 証明書・証明書の秘密鍵・認証局
✓ すべてPostgreSQLで設定可
✓ →AFSは↑を使っている
(二重管理を避ける!)
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 44

開発者向けの話:認証
✓ Apache Arrow Flight SQL
✓ 認証
✓ 追加プロトコル対応
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 45

追加プロトコル対応
✓ PostgreSQLは別プロトコルでの
接続を想定していない
✓ 拡張ポイントがたくさんあるPostgreSQLだが
プロトコル追加用の拡張ポイントはない
✓ ソケットをlistenしないといけない
✓ PostgreSQLはシングルスレッドなので
既存プロセスでやるとブロックする
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 46

バックグランドワーカー
✓ PG管理の別プロセスを
起動する仕組み
PostgreSQL
AFS
ユーザー
起動
✓ ここでlistenすれば
既存処理をブロックしない
Apache Arrow Flight SQL
Apache Arrow Flight SQL
PostgreSQL
AFS
ユーザー
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 47

接続
✓ ✕listenするプロセスでSQL実行
✓ listenするプロセスはマルチスレッド
✓ PGはマルチスレッド非対応→PGのAPIを呼べない
✓ プロセスを分離:
PostgreSQL
AFS server
AFS executor
マルチスレッド
ユーザー
シングルスレッド
起動
Apache Arrow Flight SQL
✓ listenするプロセス:
server
起動
実行依頼
実行
結果返却
✓ 各接続を処理するプロセス:
executor (シングルスレッド)
Apache Arrow Flight SQL
PostgreSQL
AFS server
AFS executor
ユーザー
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 48

executorの起動方法
✓ ✕マルチスレッド下でfork
✓ serverはマルチスレッド
✓ ✕serverからexecutorを起動
PostgreSQL
AFS server
AFS executor
マルチスレッド
ユーザー
起動
Apache Arrow Flight SQL
起動
だめ!!!
✓ この構成は危険
実行依頼
結果返却
Apache Arrow Flight SQL
PostgreSQL
AFS server
AFS executor
ユーザー
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 49

安全なexecutorの起動方法
✓ executor起動用プロセスを追加
✓ main:シングルスレッド
PostgreSQL
AFS main
AFS server
シングルスレッド
ユーザー
AFS executor
マルチスレッド
起動
✓ serverはmainに起動依頼
起動
Apache Arrow Flight SQL
executor起動依頼
✓ mainからexecutorを起動
起動
実行依頼
実行
結果返却
Apache Arrow Flight SQL
PostgreSQL
AFS main
AFS server
AFS executor
ユーザー
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 50

executorでの実行
✓ やり方は2つ
✓ libpq:PostgreSQLに
接続して実行
✓ SPI:プロセス内で実行
(Server Programming Interface)
✓ AFSはSPI
✓ libpqだと意味がない
(PostgreSQLプロトコルを使ってしまう)
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
PostgreSQL
alt
AFS executor
[libpq]
PostgreSQLプロトコルで接続
実行依頼
別プロセスを立ち上げて実行するけど省略
結果返却
[SPI]
自分で実行
PostgreSQL
AFS executor
Powered by Rabbit 3.0.4

Page: 51

プロセス間通信
✓ serverとexecutorで
Apache Arrowデータのやりとりが必要
✓ 通信方法
PostgreSQL
AFS main
AFS server
AFS executor
ユーザー
✓ 共有メモリーで
リングバッファー
✓ ナイーブな自前実装
起動
起動
Apache Arrow Flight SQL
executor起動依頼
起動
実行依頼
共有メモリーでリングバッファー
(高速化の余地あり)
結果返却
Apache Arrow Flight SQL
✓ shm_mqでいいかも…
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
PostgreSQL
AFS main
AFS server
AFS executor
ユーザー
Powered by Rabbit 3.0.4

Page: 52

開発者向けの話のまとめ
✓ 設計判断も含めて全体の構成を紹介
✓ 改良案も含めて課題も紹介
↓
一緒に開発しよう!
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 53

全体のまとめ
✓ 課題:大量データの読み書きが遅い
✓ 解決方法:
✓ Apache Arrowフォーマット/Flight SQL
✓ 現状:✓数値の読み込みは速い
✓ 今後:
✓ このアプローチの改良
✓ COPYのApache Arrowフォーマット対応
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Page: 54

サポート
✓ コミュニティー:
✓ https://github.com/apache/arrow-flight-sql-postgresql/issues
✓ https://arrow.apache.org/community/#mailing-lists
✓ クリアコードによる有償サポート:
✓ https://www.clear-code.com/contact/
✓ PGroongaのサポートも可
PGroonga:PostgreSQLに高速日本語全文検索機能を追加
Apache Arrow Flight SQLでPostgreSQLをもっと速く!
Powered by Rabbit 3.0.4

Other slides

Apache Arrow Apache Arrow
2018-12-08
Apache Arrow Apache Arrow
2018-11-17
Apache Arrow Apache Arrow
2017-06-13
Apache Arrow Apache Arrow
2017-05-28
Mroonga! Mroonga!
2015-10-30