redis_fdw は、リレーショナルデータベース PostgreSQL からキーバリューストア Redis にアクセスする拡張モジュールです。redis_fdw を使うことで、高速なデータの読み書きができる Redis と、SQL で複雑なデータの操作ができる PostgreSQL 間で円滑なデータの連携ができます。
この記事では、redis_fdw の概要、インストール、基本的な使い方、テーブルオプションについて説明します。なお、Redis 自体の説明については Redis の紹介 をお読みください。
redis_fdw とは
redis_fdw の名前につく fdw は外部データラッパ (Foreign Data Wrapper) を表し、PostgreSQL から Oracle や CSV ファイルなど、PostgreSQL 外のデータに外部テーブルとしてアクセスする機能です。redis_fdw はこの機能を使って Redis 上のデータにアクセスします。
redis_fdw は、もともと PostgreSQL 開発者の一人 Dave Page 氏が実験的に開発し、その後、Andrew Dunstan 氏が開発を引き継ぎ、本番利用向けに改修しました。
ソースコードは GitHub リポジトリ上で公開され、PostgreSQL ライセンスに従って配布されています。PostgreSQL の対応バージョンは 9.1 以降で、2022 年 8 月時点で最新の PostgreSQL 14 にも対応しています。
なお、PGDG リポジトリ[1] で同じ名前のパッケージが配布されていますが、ここで取り上げる redis_fdw とは異なるもので、便宜上、リポジトリ名をとって rw_redis_fdw と呼びます。
rw_redis_fdw も Redis 用外部データラッパで、名前につく rw は読み書き (Read-Write) を表し、以前は書き込みに対応していなかった redis_fdw に対して名づけられたものと考えられますが、現在は redis_fdw も書き込みに対応しています。
rw_redis_fdw は redis_fdw に比べて機能は多いですが、ここでは、より広く使われている redis_fdw を取り上げます。
redis_fdw のインストール
redis_fdw をインストールします。
ここでは、Rocky Linux 8 上に PostgreSQL、Redis をセットアップした上、redis_fdw をソースコードからビルドし、インストールします。
- PGDG リポジトリをインストールします。
$ sudo dnf -qy install https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %rhel-%_arch)/pgdg-redhat-repo-latest.noarch.rpm Installed: pgdg-redhat-repo-42.0-24.noarch
PostgreSQL は PGDG リポジトリからインストールします。
これ以降、
dnf
コマンドの実行時に署名つきパッケージの検証に必要な PGP キーの取り込みを表すメッセージが出力される場合があります。 - PostgreSQL モジュールを無効にします。
$ sudo dnf -qy module disable postgresql
OS 標準のリポジトリからも PostgreSQL をインストールできますが、バージョンが古いので、PGDG リポジトリのほうを使うように、PostgreSQL モジュールを無効にしています。
- PostgreSQL をインストールします。
$ sudo dnf -qy install postgresql14-server Installed: lz4-1.8.3-3.el8_4.x86_64 postgresql14-14.4-1PGDG.rhel8.x86_64 postgresql14-libs-14.4-1PGDG.rhel8.x86_64 postgresql14-server-14.4-1PGDG.rhel8.x86_64
ここでは、PostgreSQL 14 をインストールしています。
パッケージ名
postgresql14-server
をはじめ、これ以降、コマンドラインに含まれる14
は PostgreSQL のバージョンを表します。お使いになるバージョンに合わせ、適宜、読み替えてください。 - データベースクラスタを作成します。
$ PGSETUP_INITDB_OPTIONS="-E UTF8 --no-locale" sudo -E /usr/pgsql-14/bin/postgresql-14-setup initdb Initializing database ... OK
データベースクラスタはデータベースを格納する領域です。作成には通常
initdb
コマンドを使いますが、ここでは、パッケージに付属のスクリプトを使います。環境変数
PGSETUP_INITDB_OPTIONS
にはinitdb
コマンドに渡すオプションを指定します。ここでは、デフォルトのエンコーディングを UTF8、ロケールをなしに指定しています。 - PostgreSQL のサービスを起動します。
$ sudo systemctl start postgresql-14
- Redis をインストールします。
$ sudo dnf -qy install redis Installed: redis-5.0.3-5.module+el8.5.0+657+2674830e.x86_64
- Redis のサービスを起動します。
$ sudo systemctl start redis
- EPEL リポジトリ[2] をインストールします。
$ sudo dnf -qy install epel-release Installed: epel-release-8-13.el8.noarch
redis_fdw の動作に必要な Redis 用 C 言語ライブラリ Hiredis は EPEL リポジトリからインストールします。
- redis_fdw のビルドに必要なパッケージをインストールします。
$ sudo dnf -qy install make redhat-rpm-config postgresql14-devel hiredis-devel Upgraded: libgcc-8.5.0-10.1.el8_6.x86_64 libgomp-8.5.0-10.1.el8_6.x86_64 libstdc++-8.5.0-10.1.el8_6.x86_64 Installed: annobin-10.29-3.el8.x86_64 binutils-2.30-113.el8.x86_64 clang-13.0.1-1.module+el8.6.0+825+7e27476a.x86_64 clang-devel-13.0.1-1.module+el8.6.0+825+7e27476a.x86_64 clang-libs-13.0.1-1.module+el8.6.0+825+7e27476a.x86_64 clang-resource-filesystem-13.0.1-2.module+el8.6.0+987+d36ea6a1.x86_64 clang-tools-extra-13.0.1-1.module+el8.6.0+825+7e27476a.x86_64 cmake-filesystem-3.20.2-4.el8.x86_64 compiler-rt-13.0.1-1.module+el8.6.0+825+7e27476a.x86_64 cpp-8.5.0-10.1.el8_6.x86_64 dwz-0.12-10.el8.x86_64 efi-srpm-macros-3-3.el8.noarch emacs-filesystem-1:26.1-7.el8.noarch gcc-8.5.0-10.1.el8_6.x86_64 gcc-c++-8.5.0-10.1.el8_6.x86_64 ghc-srpm-macros-1.4.2-7.el8.noarch glibc-devel-2.28-189.5.el8_6.x86_64 glibc-headers-2.28-189.5.el8_6.x86_64 go-srpm-macros-2-17.el8.noarch hiredis-0.13.3-13.el8.x86_64 hiredis-devel-0.13.3-13.el8.x86_64 isl-0.16.1-6.el8.x86_64 kernel-headers-4.18.0-372.13.1.el8_6.x86_64 libicu-devel-60.3-2.el8_1.x86_64 libmpc-1.1.0-9.1.el8.x86_64 libomp-13.0.1-1.module+el8.6.0+825+7e27476a.x86_64 libomp-devel-13.0.1-1.module+el8.6.0+825+7e27476a.x86_64 libstdc++-devel-8.5.0-10.1.el8_6.x86_64 libxcrypt-devel-4.1.1-6.el8.x86_64 llvm-13.0.1-1.module+el8.6.0+825+7e27476a.x86_64 llvm-devel-13.0.1-1.module+el8.6.0+825+7e27476a.x86_64 llvm-libs-13.0.1-1.module+el8.6.0+825+7e27476a.x86_64 llvm-static-13.0.1-1.module+el8.6.0+825+7e27476a.x86_64 llvm-test-13.0.1-1.module+el8.6.0+825+7e27476a.x86_64 make-1:4.2.1-11.el8.x86_64 ocaml-srpm-macros-5-4.el8.noarch openblas-srpm-macros-2-2.el8.noarch perl-srpm-macros-1-25.el8.noarch postgresql14-devel-14.4-1PGDG.rhel8.x86_64 python-rpm-macros-3-41.el8.noarch python-srpm-macros-3-41.el8.noarch python3-rpm-macros-3-41.el8.noarch qt5-srpm-macros-5.15.2-1.el8.0.1.noarch redhat-rpm-config-129-1.el8.noarch rust-srpm-macros-5-2.el8.noarch unzip-6.0-46.el8.x86_64 zip-3.0-23.el8.x86_64
- redis_fdw のソースコードをダウンロードします。
$ curl -LOs https://github.com/pg-redis-fdw/redis_fdw/archive/refs/heads/REL_14_STABLE.tar.gz
redis_fdw のソースコードは PostgreSQL のバージョンごとにブランチが分かれていて、ダウンロード時はブランチ名を指定する必要があります。ここでは、PostgreSQL 14 に対応したブランチ
REL_14_STABLE
を指定しています。 - redis_fdw のソースコードを展開します。
$ tar -xzf REL_14_STABLE.tar.gz
- redis_fdw をビルドします。
$ make -C redis_fdw-REL_14_STABLE USE_PGXS=1 PG_CONFIG=/usr/pgsql-14/bin/pg_config make: ディレクトリ '/home/vagrant/redis_fdw-REL_14_STABLE' に入ります gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -fPIC -I. -I./ -I/usr/pgsql-14/include/server -I/usr/pgsql-14/include/internal -D_GNU_SOURCE -I/usr/include/libxml2 -I/usr/include -c -o redis_fdw.o redis_fdw.c gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -fPIC -shared -o redis_fdw.so redis_fdw.o -L/usr/pgsql-14/lib -Wl,--as-needed -L/usr/lib64 -L/usr/lib64 -Wl,--as-needed -Wl,-rpath,'/usr/pgsql-14/lib',--enable-new-dtags -lhiredis /usr/bin/clang -Wno-ignored-attributes -fno-strict-aliasing -fwrapv -Wno-unused-command-line-argument -Wno-compound-token-split-by-macro -O2 -I. -I./ -I/usr/pgsql-14/include/server -I/usr/pgsql-14/include/internal -D_GNU_SOURCE -I/usr/include/libxml2 -I/usr/include -flto=thin -emit-llvm -c -o redis_fdw.bc redis_fdw.c make: ディレクトリ '/home/vagrant/redis_fdw-REL_14_STABLE' から出ます
引数の変数
USE_PGXS
には PostgreSQL 用拡張モジュールの構築基盤 PGXS を使うことを表す1
、PG_CONFIG
にはpg_config
コマンドのパスを指定します。 - redis_fdw をインストールします。
$ sudo make -C redis_fdw-REL_14_STABLE install USE_PGXS=1 PG_CONFIG=/usr/pgsql-14/bin/pg_config make: ディレクトリ '/home/vagrant/redis_fdw-REL_14_STABLE' に入ります /usr/bin/mkdir -p '/usr/pgsql-14/lib' /usr/bin/mkdir -p '/usr/pgsql-14/share/extension' /usr/bin/mkdir -p '/usr/pgsql-14/share/extension' /usr/bin/install -c -m 755 redis_fdw.so '/usr/pgsql-14/lib/redis_fdw.so' /usr/bin/install -c -m 644 .//redis_fdw.control '/usr/pgsql-14/share/extension/' /usr/bin/install -c -m 644 .//redis_fdw--1.0.sql '/usr/pgsql-14/share/extension/' /usr/bin/mkdir -p '/usr/pgsql-14/lib/bitcode/redis_fdw' /usr/bin/mkdir -p '/usr/pgsql-14/lib/bitcode'/redis_fdw/ /usr/bin/install -c -m 644 redis_fdw.bc '/usr/pgsql-14/lib/bitcode'/redis_fdw/./ cd '/usr/pgsql-14/lib/bitcode' && /usr/bin/llvm-lto -thinlto -thinlto-action=thinlink -o redis_fdw.index.bc redis_fdw/redis_fdw.bc make: ディレクトリ '/home/vagrant/redis_fdw-REL_14_STABLE' から出ます
ソースコードと、それを展開したディレクトリはインストール後、削除しても構いません。
redis_fdw の基本的な使い方
redis_fdw を使って PostgreSQL から Redis 上のデータを操作してみます。
- PostgreSQL のスーパーユーザに切り替わります。
$ sudo su - postgres
- データベースを作成します。
$ createdb redis_db
ここでは、
redis_db
という名前のデータベースを作成しています。 - データベースに接続します。
$ psql redis_db psql (14.4) "help"でヘルプを表示します。 =#
ここでは、作成した
redis_db
データベースに接続しています。終了するには\q
またはCtrl
+D
を入力します。 - データベースに redis_fdw をインストールします。
=# CREATE EXTENSION redis_fdw; CREATE EXTENSION
redis_fdw はプログラムとしてはインストール済みですが、実際に使うにはデータベースごとにインストールする必要があります。
ここでは、接続中の
redis_db
データベースにインストールしています。 - 外部サーバを作成します。
=# CREATE SERVER redis_server FOREIGN DATA WRAPPER redis_fdw OPTIONS (address '127.0.0.1', port '6379'); CREATE SERVER
外部サーバとは、外部データラッパを使って外部データにアクセスするのに必要な接続情報を定義したオブジェクトです。作成時には、外部サーバ名、外部データラッパ名、オプションを指定します。
redis_fdw では、以下のオプションが指定できます。
オプション デフォルト値 説明 address
127.0.0.1
Redis サーバの IP アドレスまたはホスト名 port
6379
Redis サーバのポート番号 ここでは、
redis_server
という名前で redis_fdw の外部サーバを作成しています。オプションは例示のため、指定していますが、デフォルトでよければ、指定する必要はありません。 - 外部サーバのユーザマッピングを作成します。
=# CREATE USER MAPPING FOR PUBLIC SERVER redis_server OPTIONS (password 'secret'); CREATE USER MAPPING
外部サーバのユーザマッピングとは、外部サーバとユーザの対応づけを定義したオブジェクトです。作成時には、ユーザ名、外部サーバ名、オプションを指定します。
redis_fdw では、以下のオプションが指定できます。
オプション デフォルト値 説明 password
(なし) Redis サーバ接続時の認証に使うパスワード ここでは、すべてのユーザを表す
PUBLIC
と外部サーバredis_server
を対応づけるユーザマッピングを作成しています。password
オプションはパスワードが未設定であれば、指定する必要はありません。 - 外部テーブルを作成します。
=# CREATE FOREIGN TABLE string_table (key text, val text) SERVER redis_server OPTIONS (database '0'); CREATE FOREIGN TABLE
外部テーブルとは、外部データラッパを使って外部データにテーブルとしてアクセスできるように定義した特別なテーブルです。作成時には、テーブル定義、外部サーバ名、オプションを指定します。
redis_fdw では、以下のオプションが指定できます。
オプション デフォルト値 説明 database
0
Redis のデータベース番号。 0
からデフォルトでは15
まで指定可能tabletype
(なし) Redis のデータ型。 list
、hash
、set
、zset
が指定可能。未指定はstring
tablekeyprefix
(なし) 指定した接頭辞をもつキーに対象データを絞り込む tablekeyset
(なし) 指定したキーをもつ集合に含まれるキーに対象データを絞り込む singleton_key
(なし) 指定したキーの単一データを展開して対象データにする tabletype
オプションを指定しないと、文字列を表すstring
型になりますが、値としてstring
は指定できません。teblekeyprefix
、tablekeyset
、singleton_key
はいずれも対象データを指定するオプションで、1 つのみ指定でき、指定しないと、すべてのデータが対象になります。詳しくは redis_fdw のテーブルオプション で説明します。ここでは、
tabletype
オプションは指定せず、テーブル定義はtext
型のkey
とval
列を定義しています。Redis のキーとstring
型の値は PostgreSQL ではそれぞれtext
型に対応します。列名は任意です。database
オプションはデフォルトでよければ、指定する必要はありません。 - 外部テーブルのデータを操作します。データの操作を受けて Redis サーバがどう動作するかを確認するため、Redis サーバで実行されたコマンドを出力するようにしておきます。終了するには
Ctrl
+C
を入力します。$ redis-cli monitor OK
PostgreSQL 側でデータを 3 件登録します。
=# INSERT INTO string_table VALUES ('key1', 'val1'), ('key2', 'val2'), ('key3', 'val3'); INSERT 0 3
Redis 側で実行されたコマンドが出力されます。
1658092725.885750 [0 127.0.0.1:46042] "AUTH" "secret" 1658092725.886005 [0 127.0.0.1:46042] "SELECT" "0" 1658092725.886333 [0 127.0.0.1:46042] "EXISTS" "key1" 1658092725.886766 [0 127.0.0.1:46042] "SET" "key1" "val1" 1658092725.887016 [0 127.0.0.1:46042] "EXISTS" "key2" 1658092725.887387 [0 127.0.0.1:46042] "SET" "key2" "val2" 1658092725.887620 [0 127.0.0.1:46042] "EXISTS" "key3" 1658092725.887764 [0 127.0.0.1:46042] "SET" "key3" "val3"
PostgreSQL 側でデータを 1 件更新します。
=# UPDATE string_table SET val = 'val4' WHERE key = 'key1'; UPDATE 1
Redis 側で実行されたコマンドが出力されます。
1658092937.940434 [0 127.0.0.1:46044] "AUTH" "secret" 1658092937.940542 [0 127.0.0.1:46044] "SELECT" "0" 1658092937.940660 [0 127.0.0.1:46044] "DBSIZE" 1658092937.941136 [0 127.0.0.1:46046] "AUTH" "secret" 1658092937.941352 [0 127.0.0.1:46046] "SELECT" "0" 1658092937.941445 [0 127.0.0.1:46046] "EXISTS" "key1" 1658092937.941835 [0 127.0.0.1:46048] "AUTH" "secret" 1658092937.941976 [0 127.0.0.1:46048] "SELECT" "0" 1658092937.942118 [0 127.0.0.1:46046] "GET" "key1" 1658092937.942385 [0 127.0.0.1:46048] "SET" "key1" "val4"
PostgreSQL 側でデータを 1 件削除します。
=# DELETE FROM string_table WHERE key = 'key2'; DELETE 1
Redis 側で実行されたコマンドが出力されます。
1658092947.811658 [0 127.0.0.1:46050] "AUTH" "secret" 1658092947.811792 [0 127.0.0.1:46050] "SELECT" "0" 1658092947.811875 [0 127.0.0.1:46050] "DBSIZE" 1658092947.812375 [0 127.0.0.1:46052] "AUTH" "secret" 1658092947.812605 [0 127.0.0.1:46052] "SELECT" "0" 1658092947.812729 [0 127.0.0.1:46052] "EXISTS" "key2" 1658092947.813055 [0 127.0.0.1:46054] "AUTH" "secret" 1658092947.813197 [0 127.0.0.1:46054] "SELECT" "0" 1658092947.813342 [0 127.0.0.1:46052] "GET" "key2" 1658092947.813438 [0 127.0.0.1:46054] "DEL" "key2"
PostgreSQL 側でデータを 1 件取得します。
=# SELECT val FROM string_table WHERE key = 'key3'; val ------ val3 (1 行)
Redis 側で実行されたコマンドが出力されます。
1658092954.987736 [0 127.0.0.1:46056] "AUTH" "secret" 1658092954.987827 [0 127.0.0.1:46056] "SELECT" "0" 1658092954.987876 [0 127.0.0.1:46056] "DBSIZE" 1658092954.988113 [0 127.0.0.1:46058] "AUTH" "secret" 1658092954.988283 [0 127.0.0.1:46058] "SELECT" "0" 1658092954.988375 [0 127.0.0.1:46058] "EXISTS" "key3" 1658092954.988482 [0 127.0.0.1:46058] "GET" "key3"
redis_fdw のテーブルオプション
redis_fdw を使って外部テーブルの定義時に指定できるオプションについて説明します。
tabletype
オプション
tabletype
は Redis のデータ型を指定するオプションです。オプションに指定できるデータ型について説明します。
list
型
list
は登録順に並べた文字列の集合を表すデータ型で、PostgreSQL では値を並べた text
型の配列に対応します。
=# CREATE FOREIGN TABLE list_table (key text, val text[]) SERVER redis_server OPTIONS (database '1', tabletype 'list'); CREATE FOREIGN TABLE =# INSERT INTO list_table VALUES ('key1', '{val1,val2,val3,val1}'); INSERT 0 1 =# SELECT * FROM list_table WHERE key = 'key1'; key | val ------+----------------------- key1 | {val1,val2,val3,val1} (1 行) =# SELECT key, unnest(val) FROM list_table WHERE key = 'key1'; key | unnest ------+-------- key1 | val1 key1 | val2 key1 | val3 key1 | val1 (4 行)
値 val1
、val2
、val3
、val1
を登録し、データを取得すると、値が登録順に並び、重複する値 val1
が残っています。取得したデータは unnest
関数で行の集合に展開できます。
hash
型
hash
はフィールドと値の文字列の組み合わせからなる集合を表すデータ型で、PostgreSQL ではフィールドと値を交互に並べた text
型の配列に対応します。
=# CREATE FOREIGN TABLE hash_table (key text, val text[]) SERVER redis_server OPTIONS (database '2', tabletype 'hash'); CREATE FOREIGN TABLE =# INSERT INTO hash_table VALUES ('key1', '{fld1,val1,fld2,val2,fld3,val3,fld1,val4}'); INSERT 0 1 =# SELECT * FROM hash_table WHERE key = 'key1'; key | val ------+--------------------------------- key1 | {fld1,val4,fld2,val2,fld3,val3} (1 行) =# SELECT key, json_object(val) FROM hash_table WHERE key = 'key1'; key | json_object ------+----------------------------------------------------- key1 | {"fld1" : "val4", "fld2" : "val2", "fld3" : "val3"} (1 行) =# SELECT key, (json_each_text(json_object(val))).* FROM hash_table WHERE key = 'key1'; key | key | value ------+------+------- key1 | fld1 | val4 key1 | fld2 | val2 key1 | fld3 | val3 (3 行)
フィールドと値の組み合わせ fld1
と val1
、fld2
と val2
、fld3
と val3
、fld1
と val4
を登録し、データを取得すると、フィールド fld1
が重複する値 val1
、val4
はあとから登録した値 val4
で上書きされています。取得したデータは json_object
関数で JSON オブジェクトに変換し、さらに json_each_text
関数でフィールドと値からなる行の集合に展開できます。
set
型
set
は順序づけがなく、重複がない文字列の集合を表すデータ型で、PostgreSQL では値を並べた text
型の配列に対応します。
=# CREATE FOREIGN TABLE set_table (key text, val text[]) SERVER redis_server OPTIONS (database '3', tabletype 'set'); CREATE FOREIGN TABLE =# INSERT INTO set_table VALUES ('key1', '{val1,val2,val3,val1}'); INSERT 0 1 =# SELECT * FROM set_table WHERE key = 'key1'; key | val ------+------------------ key1 | {val1,val3,val2} (1 行)
値 val1
、val2
、val3
、val1
を登録し、データを取得すると、重複する値 val1
が取り除かれ、1 つになっています。
zset
型
zset
はスコアで順序づけした、重複がない文字列の集合を表すデータ型で、PostgreSQL では値を並べた text
型の配列に対応します。
zset
型の使い方は基本的に set
型と同じです。スコアは登録順に 0
、1
、2
、… が割り当てられます。スコアを PostgreSQL で扱うには、singleton_key
オプション を指定する必要があります。
tablekeyprefix
オプション
tablekeyprefix
は指定した接頭辞をもつキーに対象データを絞り込むオプションで、1 つのデータベース内に異なる種類のデータをもたせ、別テーブルとしてアクセスするのに役立ちます。
=# CREATE FOREIGN TABLE keyprefix_table (key text, val text) SERVER redis_server OPTIONS (database '4', tablekeyprefix 'keyprefix_table:'); CREATE FOREIGN TABLE =# INSERT INTO keyprefix_table VALUES ('keyprefix_table:key1', 'val1'); INSERT 0 1 =# INSERT INTO keyprefix_table VALUES ('keyprefix_table:key2', 'val2'); INSERT 0 1 =# INSERT INTO keyprefix_table VALUES ('key3', 'val3'); ERROR: key 'key3' does not match table key prefix 'keyprefix_table:' =# SELECT * FROM keyprefix_table; key | val ----------------------+------ keyprefix_table:key2 | val2 keyprefix_table:key1 | val1 (2 行) =# \! redis-cli -n 4 SET key3 val3 OK =# \! redis-cli -n 4 KEYS \* 1) "keyprefix_table:key2" 2) "key3" 3) "keyprefix_table:key1" =# SELECT * FROM keyprefix_table; key | val ----------------------+------ keyprefix_table:key2 | val2 keyprefix_table:key1 | val1 (2 行)
tablekeyprefix
オプションを指定すると、指定した接頭辞 keyprefix_table:
をもつキー keyprefix_table:key1
、keyprefix_table:key2
のデータしか登録できず、接頭辞をもたないキー key3
の登録はエラーになります。\!
は PostgreSQL 外のコマンドを実行するコマンドで、Redis 上のデータを直接操作し、接頭辞をもたないキー key3
を登録し、データを取得すると、接頭辞をもたないキー key3
は結果に現れません。
大量のキーをもつデータベースでは、tablekeyprefix
オプションではキーの検索に時間がかかるため、tablekeyset
オプションでキーを集合に含まれるものに限ったほうがよいでしょう。
tablekeyset
オプション
tablekeyset
は指定したキーをもつ集合に含まれるキーに対象データを絞り込むオプションで、tablekeyprefix
オプションと同じく、1 つのデータベース内で異なる種類のデータを扱うのに使います。
=# CREATE FOREIGN TABLE keyset_table (key text, val text) SERVER redis_server OPTIONS (database '5', tablekeyset 'keyset_table_keys'); CREATE FOREIGN TABLE =# INSERT INTO keyset_table VALUES ('key1', 'val1'), ('key2', 'val2'), ('key3', 'val3'); INSERT 0 3 =# SELECT * FROM keyset_table; key | val ------+------ key3 | val3 key2 | val2 key1 | val1 (3 行) =# \! redis-cli -n 5 SREM keyset_table_keys key2 (integer) 1 =# \! redis-cli -n 5 SMEMBERS keyset_table_keys 1) "key3" 2) "key1" =# SELECT * FROM keyset_table; key | val ------+------ key3 | val3 key1 | val1 (2 行)
tablekeyset
オプションを指定すると、指定したキー keyset_table_keys
をもつ集合に登録したキー key1
、key2
、key3
が自動的に登録され、取得されるデータは集合に含まれるキーに限られます。Redis 上のデータを直接操作し、キー key2
を削除し、データを取得すると、削除したキー key2
は結果に現れなくなります。
singleton_key
オプション
singleton_key
は指定したキーの単一データを展開して対象データにするオプションで、tableytpe
オプション指定なしの string
型は 1 行 1 列、指定ありの list
または set
型は行の集合、hash
型はフィールドと値からなる行の集合、zset
型は値とスコアからなる行の集合に展開されます。
=# CREATE FOREIGN TABLE singleton_table (val text, sc numeric) SERVER redis_server OPTIONS (database '6', tabletype 'zset', singleton_key 'singleton_table'); CREATE FOREIGN TABLE =# INSERT INTO singleton_table VALUES ('val1', 10), ('val2', 20), ('val3', 30); INSERT 0 3 =# SELECT * FROM singleton_table; val | sc ------+---- val1 | 10 val2 | 20 val3 | 30 (3 行) =# UPDATE singleton_table SET sc = 40 WHERE val = 'val1'; UPDATE 1 =# SELECT * FROM singleton_table; val | sc ------+---- val2 | 20 val3 | 30 val1 | 40 (3 行)
singleton_key
オプションと併せて tabletype
オプションに zset
型を指定すると、PostgreSQL でスコアを扱えるようになります。スコアは PostgreSQL では numeric
型に対応します。ORDER BY
句で並び順を指定しなければ、データはスコアの昇順に取得されます。値 val1
のスコアを 10
から 40
に更新すると、並び順が更新したスコア順に変わり、値 val1
は最後に来るようになります。
おわりに
この記事では、Redis 用外部データラッパ redis_fdw の概要、インストール、基本的な使い方、テーブルオプションについて説明しました。redis_fdw を使うことで、高速なデータの読み書きができる Redis と、SQL で複雑なデータの操作ができる PostgreSQL の特長を互いに活かし、さらに利用の幅が広がることでしょう。
SRA OSS では、PostgreSQL や Redis、redis_fdw のサポートをはじめとして、オープンソースに関する様々なサービスを提供しています。SRA OSS のサービスに興味がありましたら、お気軽に こちら からお問い合わせください。
- PostgreSQL Global Development Group (PGDG) が運営する PostgreSQL 関連パッケージの Yum リポジトリ
- Fedora Project が運営するエンタープライズ Linux 向け追加パッケージ (Extra Packages for Enterprise Linux; EPEL) の Yum リポジトリ