注: PG-Strom 5.x以降のバージョンのPG-StromをUbuntuで動かしたい場合は、CUDA 12.2以降のバージョンをインストールしてください。この注を書いた2024/06/14時点ではCUDA 12.5.0が最新版であり、Ubuntu 20.04や22.04は対応していますがUbuntu 24.04は対応していません。
PG-Stromとは
PG-StromはCUDA、GPUとGPUDirect Storage対応したストレージを組み合わせて使うことで、 PostgreSQLの処理をスケールさせて高速化するソフトウェアです。 また、PG-StromでApache Arrow形式のデータを外部テーブルとして利用する機能も含まれます。
Apache Arrow形式はデータの読み出しがとにかく速いので、PostgreSQLで使えるとかなり データ分析が捗ります。
- Arrow形式は必要なところだけしか読み出さないので、読み出しが高速化
- PG-Stromは処理部分はGPUにスケールするので、CPUで動かすよりもデータ処理を高速に
- Arrow形式のファイルを適当なところにおいて登録するだけで他のデータ同様使える
- 他のノードにデータを転送して同様に登録するだけで移行完了という手軽さ
- Fluentdを介して、ログデータをArrow形式にしてPG-Stromノードで分析できる
インストール方法は次のオフィシャルドキュメントがありますが、今回はUbuntu 20.04で動かしてみたいと思います。
必要なもの
今回、手元で動作確認したバージョンと組み合わせは次のとおりです。
- Ubuntu Server 20.04.5 (20.04.6+GAカーネルでも動作することを確認)
- CUDA 12.0.1
- Pascal世代以降のNVIDIA GPUでCUDAサポートのGPU
- PostgreSQL 15
CUDA 11.4 < CUDA 12.0.1をインストール
PG-StromはCUDA 11.4以降のCUDAを利用します。現在テストされているバージョンはCUDA 12までのバージョンです(12.0.1も含む)。 この範囲のバージョンでかつ、サポートされているOS、カーネルの組み合わせでインストールしてください。 正しくない組み合わせではそもそもCUDAが正常インストールできません。インストールするバージョンのCUDAのドキュメント を確認してください。
事前に開発ツールなどをインストールします。
sudo apt-get install build-essential libicu-dev sudo systemctl set-default multi-user.target sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
次にCUDAをインストールします。次はUbuntu Serverに最低限のCUDA環境をセットアップする例です。
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600 wget https://developer.download.nvidia.com/compute/cuda/12.0.1/local_installers/cuda-repo-ubuntu2004-12-0-local_12.0.1-525.85.12-1_amd64.deb sudo dpkg -i cuda-repo-ubuntu2004-12-0-local_12.0.1-525.85.12-1_amd64.deb sudo cp /var/cuda-repo-ubuntu2004-12-0-local/cuda-*-keyring.gpg /usr/share/keyrings/ sudo apt-get update sudo apt-get install --no-install-recommends cuda
再起動とドライバーの確認
ここで一旦再起動して、再起動後にドライバーが正常に導入されたかコマンドを実行して確認します。
sudo reboot ... nvidia-smi (実行してエラーが出ないことを確認)
PostgreSQL 15をインストール
PostgreSQL Serverをインストールします。PG-Strom 3.xはPostgreSQL 12以降をサポートしますが、今回PostgreSQLコミュニティのパッケージを入れます。
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - sudo apt-get update sudo apt-get -y install postgresql-client-15 postgresql-15 postgresql-server-dev-15 libpq-dev
PG-Stromのインストール
間もなくPG-Strom 5.xがリリース予定ですが、今回はバージョン3.xをインストールしてみます。次のように実行してインストールしてください。
git clone -b v3.5 https://github.com/heterodb/pg-strom.git cd pg-strom make PG_CONFIG=/usr/bin/pg_config sudo make install PG_CONFIG=/usr/bin/pg_config
ビルド後の設定
インストール後、次のような設定を行います。
Ubuntuの場合、PostgreSQLパッケージがインストールされた時点でinitdb
は実行済みなので、設定の変更など行うだけです。
sudo su - postgres
テスト用ユーザーを作成
ログインするためのユーザーを作成します。パスワード入力を求められますので、このユーザーに対するパスワードを設定してください。
createuser -d -r -s -P mypguser
PostgreSQL設定の変更
PostgreSQLの設定に対して、PG-Strom共有ライブラリの設定とちょっとしたチューニングを施します。例記されている設定のうち、特に重要なのがshared_buffers
です。実装しているメモリーの25%程度を設定するのが適切です。
cd /etc/postgresql/15/main/ vi postgresql.conf ... #------------------------------------------------------------------------------ # CUSTOMIZED OPTIONS #------------------------------------------------------------------------------ # Add settings for extensions here shared_preload_libraries = '$libdir/pg_strom' max_worker_processes = 100 shared_buffers = 4GB work_mem = 1GB listen_addresses = '*'
PostgreSQLの再起動
カスタマイズした設定を適用するためにサービス再起動します。
$ sudo systemctl restart postgresql@15-main.service
PostgreSQLにログイン
作ったユーザーでログインします。
$ psql -h 127.0.0.1 -U mypguser -d postgres
ユーザーを作ったときのパスワードを入力すると、ログインできます。
$ psql -h 127.0.0.1 -U mypguser -d postgres Password for user mypguser: psql (15.3 (Ubuntu 15.3-1.pgdg20.04+1)) SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off) Type "help" for help. postgres=#
次のように実行すると、現在接続中のDBでPG-Stromが使えます。
postgres=# CREATE EXTENSION pg_strom;
PG-Strom Quickstart
次のように実行してテストデータテーブルを作ってみてください。
postgres=# CREATE TABLE t_test1 AS SELECT x, 'a'::char(100) AS y, 'b'::char(100) AS z FROM generate_series(1, 5000000) AS x ORDER BY random();
次のように実行してみます。QUERY PLAN(実行計画)が表示されて、出力からGPUが使われていることがわかります。
EXPLAIN VERBOSE SELECT count(*) FROM t_test1 WHERE sqrt(x) > 0 GROUP BY y; QUERY PLAN ------------------------------------------------------------------------------------------------------------------ GroupAggregate (cost=100031.53..100031.55 rows=1 width=109) Output: pgstrom.sum((pgstrom.nrows())), y Group Key: t_test1.y -> Sort (cost=100031.53..100031.53 rows=2 width=109) Output: (pgstrom.nrows()), y Sort Key: t_test1.y -> Gather (cost=100031.31..100031.52 rows=2 width=109) Output: (pgstrom.nrows()), y Workers Planned: 2 -> Parallel Custom Scan (GpuPreAgg) on public.t_test1 (cost=99031.31..99031.32 rows=1 width=109) Output: (pgstrom.nrows()), y GPU Output: (pgstrom.nrows()), y GPU Setup: '1'::bigint, y Reduction: GroupBy (Global+Local [nrooms: 1974]) Group keys: t_test1.y Outer Scan: public.t_test1 (cost=2833.33..98814.29 rows=694445 width=101) Outer Scan Filter: (sqrt((t_test1.x)::double precision) > '0'::double precision) GPU Preference: None Kernel Source: /var/lib/postgresql/15/main/pgsql_tmp/pgsql_tmp_strom_8423.0.gpu JIT: Functions: 8 Options: Inlining false, Optimization false, Expressions true, Deforming true (22 rows)
次のように実行すると500万行のデータの検索が812ミリ秒、つまり1秒以下で終えられたことがわかります。速いですね。
postgres=# \timing Timing is on. postgres=# SELECT count(*) FROM t_test1 WHERE sqrt(x) > 0 GROUP BY y; count | ---------+------------------- 5000000 | a (1 row) Time: 812.535 ms
これでPostgreSQLのクエリ実行にPG-StromでGPUを使って処理をスケールすることができるようになりました。 PG-Stromの利用ガイド などをみて、色々試してみてください。 Apache ArrowとかFluentd連携周りはなかなか面白いですよ。
より大規模なデータを取り扱うには商用ライセンスが必要ですが、それによりマルチGPUやGPUDirect Storageが利用できるようになり、100ギガバイトやテラバイトクラスのデータの処理を高速化できるようになります。
現在開発中のPG-Strom 5.xではロジックの改良を行っているとのことです。 まずは手元の環境でお試ししてみてください。