4. PG-Stromとは?
OSC.Kyoto Online ~GPUが拓くIoT/M2Mデータ処理と地理情報分析の世界~4
【機能】
集計/解析ワークロードの透過的なGPU高速化
SSD-to-GPU Direct SQLによるPCIeバスレベルの最適化
Apache Arrow対応によるデータ交換、インポート時間をほぼゼロに
GPUメモリにデータを常駐。OLTPワークロードとの共存
一部PostGIS関数のサポート。位置情報分析を高速化
PG-Strom: GPUとNVME/PMEMの能力を最大限に引き出し、
テラバイト級のデータを高速処理するPostgreSQL向け拡張モジュール
App
GPU
off-loading
for IoT/Big-Data
for ML/Analytics
➢ SSD-to-GPU Direct SQL
➢ Columnar Store (Arrow_Fdw)
➢ GPU Memory Store (Gstore_Fdw)
➢ Asymmetric Partition-wise
JOIN/GROUP BY
➢ BRIN-Index Support
➢ NVME-over-Fabric Support
➢ Inter-process Data Frame
for Python scripts
➢ Procedural Language for
GPU native code (w/ cuPy)
➢ PostGIS Support
NEW
NEW
11. GpuScan + GpuJoin + GpuPreAgg Combined Kernel (1/3)
Aggregation
GROUP BY
JOIN
SCAN
SELECT cat, count(*), avg(x)
FROM t0 JOIN t1 ON t0.id = t1.id
WHERE y like ‘%abc%’
GROUP BY cat;
count(*), avg(x)
GROUP BY cat
t0 JOIN t1
ON t0.id = t1.id
WHERE y like ‘%abc%’
実行結果
OSC.Kyoto Online ~GPUが拓くIoT/M2Mデータ処理と地理情報分析の世界~11
GpuScan
GpuJoin
Agg
+
GpuPreAgg
SeqScan
HashJoin
Agg
23. 背景① データはどこで生成されるのか?
ETL
OLTP OLAP
伝統的なOLTP&OLAPシステム - データはDBシステムの内側で生成される
Data
Creation
IoT/M2M時代 - データはDBシステムの外側で生成される
Log
processing
BI Tools
BI Tools
Gateway Server
Data
Creation
Data
Creation
Many Devices
OSC.Kyoto Online ~GPUが拓くIoT/M2Mデータ処理と地理情報分析の世界~23
DBシステムへのデータのインポートが、集計処理以上に時間のかかる処理に!
Data
Import
Import!
24. 背景② PostgreSQLのデータ構造は結構無駄が多い
OSC.Kyoto Online ~GPUが拓くIoT/M2Mデータ処理と地理情報分析の世界~24
8kB
HeapTuple
Table Segment Block
HeapTupleHeader nullmap 列A 列B 列D 列E
Tuple
SELECT B FROM this_table WHERE E like ‘%hoge%’;
要る?
26. Apache Arrowとは(2/2)– データ型のマッピング
Apache Arrowデータ型 PostgreSQLデータ型 補足説明
Int int2, int4, int8
FloatingPoint float2, float4, float8 float2 is an enhancement of PG-Strom
Binary bytea
Utf8 text
Bool bool
Decimal numeric
Date date adjusted to unitsz = Day
Time time adjusted to unitsz = MicroSecond
Timestamp timestamp adjusted to unitsz = MicroSecond
Interval interval
List array types Only 1-dimensional array is supportable
Struct composite types
Union ------
FixedSizeBinary char(n)
FixedSizeList array types?
Map ------
大半のデータ型はApache Arrow PostgreSQLの間で変換可能
OSC.Kyoto Online ~GPUが拓くIoT/M2Mデータ処理と地理情報分析の世界~26
31. 《補足》PostgreSQLデータベースからArrowファイルを生成する
✓ 基本的な使い方は、-cで指定したSQLの実行結果を、
-oで指定したファイルに書き出す。
$ pg2arrow --help
Usage:
pg2arrow [OPTION] [database] [username]
General options:
-d, --dbname=DBNAME Database name to connect to
-c, --command=COMMAND SQL command to run
-t, --table=TABLENAME Table name to be dumped
(-c and -t are exclusive, either of them must be given)
-o, --output=FILENAME result file in Apache Arrow format
--append=FILENAME result Apache Arrow file to be appended
(--output and --append are exclusive. If neither of them
are given, it creates a temporary file.)
Arrow format options:
-s, --segment-size=SIZE size of record batch for each
Connection options:
-h, --host=HOSTNAME database server host
-p, --port=PORT database server port
-u, --user=USERNAME database user name
-w, --no-password never prompt for password
-W, --password force password prompt
Other options:
--dump=FILENAME dump information of arrow file
--progress shows progress of the job
--set=NAME:VALUE config option to set before SQL execution
--help shows this message
Pg2Arrow により、SQL実行結果をArrow形式で書き出す事ができる。
Apache Arrow
Data Files
Arrow_Fdw
Pg2Arrow
OSC.Kyoto Online ~GPUが拓くIoT/M2Mデータ処理と地理情報分析の世界~31
58. Gstore_Fdw外部テーブルの定義
CREATE FOREIGN TABLE ft (
id int,
x float,
y float,
z text
) server gstore_fdw
options (gpu_device_id '1',
base_file '/opt/pgdata-dev/ft.base',
redo_log_file '/opt/pmem-dev/ft.redo’,
max_num_rows '4000000',
primary_key 'id');
(補足)
base_fileはNVMEストレージ上に配置するのが望ましい。
✓ mmap(2)してバイト単位のランダムアクセスが多発するため、
PMEMの微妙なアクセスの遅さが性能差として見えてしまう。
redo_log_fileはPMEM上に配置するのが望ましい。
✓ トランザクションのコミット時にREDOログを永続化する必要があるため。
追記書き出しのみだが、細かい単位でCPUキャッシュをフラッシュする。
(逆にブロックデバイスのようなfsyncは必要ないが)
OSC.Kyoto Online ~GPUが拓くIoT/M2Mデータ処理と地理情報分析の世界~58
59. 更新処理のパフォーマンス(1/2)
--- 200万行を投入
INSERT INTO ft (SELECT x, 100*random(),
100*random(),
md5(x::text)
FROM generate_series(1,2000000) x);
--- 以下のクエリを pgbench で投入
--- (クライアント数:20を想定)
UPDATE ft SET x = 100*random(),
y = 100*random()
WHERE id = (SELECT 20*(100000.0*random())::int + :client_id);
--- 実行計画
EXPLAIN ....;
QUERY PLAN
-------------------------------------------------------------------
Update on ft (cost=0.02..100.03 rows=10000 width=58)
InitPlan 1 (returns $0)
-> Result (cost=0.00..0.02 rows=1 width=4)
-> Foreign Scan on ft (cost=0.00..100.01 rows=10000 width=58)
Filter: (id = $0)
Index Cond: id = $0
(6 rows)
OSC.Kyoto Online ~GPUが拓くIoT/M2Mデータ処理と地理情報分析の世界~59
60. 更新処理のパフォーマンス(2/2)
$ pgbench -p 6543 postgres -n -f test.sql -c 20 -j 10 -T 10
transaction type: test.sql
scaling factor: 1
query mode: simple
number of clients: 20
number of threads: 10
duration: 10 s
number of transactions actually processed: 1236401
latency average = 0.162 ms
tps = 123631.393482 (including connections establishing)
tps = 123674.819689 (excluding connections establishing)
(補足)
まだ排他ロックで実装している箇所があり、クライアント数が20を越えた辺りで
サチり始める。
➔ Row-Idの払い出しや、REDOログの書き込み位置などロックレス化できるハズ。
PostgreSQLの通常テーブル(on NVME-SSD):
20クライアント 65k TPS、80クライアント160k TPS程度
通常テーブルと外部テーブルの内部ロジックの違いに起因する差異は未検証
OSC.Kyoto Online ~GPUが拓くIoT/M2Mデータ処理と地理情報分析の世界~60
61. 検索処理のパフォーマンス(1/2)
--- GpuScan (GPU版PostGIS) + Gstore_Fdw
=# SELECT count(*) FROM ft
WHERE st_contains('polygon ((10 10,90 10,90 12,12 12,12 88,90 88,90 90,¥
10 90,10 10))’, st_makepoint(x,y));
count
-------
94440
(1 row)
Time: 75.466 ms
--- 通常版PostGIS + PostgreSQLテーブル
=# SET pg_strom.enabled = off;
SET
=# SELECT count(*) FROM tt
WHERE st_contains('polygon ((10 10,90 10,90 12,12 12,12 88,90 88,90 90,¥
10 90,10 10))', st_makepoint(x,y));
count
-------
94440
(1 row)
Time: 332.300 ms
200万個のPointから、
指定領域内の数をカウント
OSC.Kyoto Online ~GPUが拓くIoT/M2Mデータ処理と地理情報分析の世界~61