2023-06-20
Redis上の各種データをPostgreSQLのテーブルとしてアクセス可能になります。Redisは番号で分けてDBを複数持つことができて、切り替えは
redis-cli select 1 # 好きなDB番号に切り替え
などとして、空間を分けることができます。これを利用して、PostgreSQLでは別テーブルとして扱えます。
1、redis_fdwのインストール
redisのC言語ライブラリがインストールされていない場合、入れます。
git clone https://github.com/redis/hiredis.git cd hiredis/ make sudo make install
PGXSを使うのでpostgresql-server開発ツールをインストールします。
apt search postgresql-server-dev Sorting... Done Full Text Search... Done postgresql-server-dev-11/stable,stable 11.7-0+deb10u1 amd64 development files for PostgreSQL 11 server-side programming postgresql-server-dev-all/stable,stable 200+deb10u3 all extension build tool for multiple PostgreSQL versions sudo apt install postgresql-server-dev-11
redis_fdwが対応しているPostgreSQLのバージョンを確認します。
https://github.com/pg-redis-fdw/redis_fdw/branches/stale
自分のPostgreSQLのバージョンが11系列なら、REL_11_STABLEを選択すればいいことがわかります。
psql --version psql (PostgreSQL) 11.7 (Debian 11.7-0+deb10u1)
redis_fdwのダウンロード、コンパイル、インストール
git clone https://github.com/pg-redis-fdw/redis_fdw.git cd redis_fdw 該当PostgreSQLバージョンにスイッチ git checkout -b REL_11_STABLE origin/REL_11_STABLE Branch 'REL_11_STABLE' set up to track remote branch 'REL_11_STABLE' from 'origin'. Switched to a new branch 'REL_11_STABLE' make USE_PGXS=1 sudo make USE_PGXS=1 install
2、PostgreSQLでの使用開始宣言とRedisでのモニター開始
スーパーユーザーでpsqlします。
CREATE EXTENSION redis_fdw; CREATE SERVER redis_server FOREIGN DATA WRAPPER redis_fdw OPTIONS (address '127.0.0.1', port '6379'); CREATE EXTENSION hstore; CREATE USER MAPPING FOR PUBLIC SERVER redis_server; \dx List of installed extensions Name | Version | Schema | Description -----------+---------+------------+-------------------------------------------------- hstore | 1.5 | public | data type for storing sets of (key, value) pairs plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language redis_fdw | 1.0 | public | Foreign data wrapper for querying a Redis server (3 rows)
Redisでは、どのようなコマンドに変換されるか見るため、MONITORを立ち上げておきましょう。
redis-cli monitor
3、HASH型テーブルを扱う(singleton_keyを使わない場合)
RedisのHASH型を扱うテーブルをPostgreSQLで宣言し、Redisで登録して、PostgreSQLで抽出してみます。
PostgreSQL
CREATE FOREIGN TABLE redisdb10 (key text, value text) SERVER redis_server OPTIONS (tabletype 'hash', database '10');
Redis
select 10 hset key1 field1 value1 hset key1 field2 value2 hset key2 field2 value2
PostgreSQL
時間計測を入れておく
\timing SELECT * FROM redisdb10; key | value ------+--------------------------------------- key2 | {"field2","value2"} key1 | {"field1","value1","field2","value2"} (2 rows) Time: 1.353 ms
無事取得できましたが、こんなので1.3ミリ秒もかかっていたら使い物にならない…!
Redisモニタ(どんなコマンドが発行されているか)
"SELECT" "10" "DBSIZE" "SELECT" "10" "SCAN" "0" "COUNT" "1000" "HGETALL" "key2" "HGETALL" "key1"
うーむ、くどい…
4、HASH型テーブルを扱う(singleton_keyを使う場合)
singleton_keyを指定してテーブル作成をすると、KEY名がそれに固定される用途になるため、出力が大きく異なってきます。
PostgreSQL
CREATE FOREIGN TABLE redisdb11 (key text, value text) SERVER redis_server OPTIONS (tabletype 'hash', singleton_key 'PG', database '11');
Redis
キーは"PG"固定になります。
select 11 hset PG field1 value1 hset PG field2 value2 hset PG field3 value3
PostgreSQL
\timing SELECT * FROM redisdb11; key | value --------+-------- field1 | value1 field2 | value2 field3 | value3 (3 rows) Time: 1.114 ms
本来keyが入る箇所にfieldが入ってくるので、valueはfield-valueの配列にならずそのまま複数行として返ります。
Redisモニタ
"SELECT" "11" "HLEN" "PG" "SELECT" "11" "HGETALL" "PG"
キーが固定なので多少早くなったような、しかしこれHASHの意味全然ないですよね…。
5、STRING型テーブルを扱う
最もスタンダードなKEY-VALUEタイプです。PostgreSQLからのINSERTも簡単にできるので、SELECT結果をINSERTで大量にRedisに流し込む用途には最適といえます。
PostgreSQL
CREATE FOREIGN TABLE redisdb12 (key text, value text) SERVER redis_server OPTIONS (database '12');
tabletypeをstringなどと指定すると何故かエラーになるので注意
Redis
select 12 set key1 value1 set key2 value2 set key3 value3
PostgreSQL
\timing SELECT * FROM redisdb12; key | value ------+-------- key2 | value2 key3 | value3 key1 | value1 (3 rows) Time: 1.524 ms
Stringなら爆速!と期待したものの、Hashより遅い。。
Redisモニタ
"SELECT" "12" "DBSIZE" "SELECT" "12" "SCAN" "0" "COUNT" "1000" "GET" "key2" "GET" "key3" "GET" "key1"
うーむ、くどい…
PostgreSQL
INSERT,UPDATE, SELECTの結果を受けての大量INSERTも可能。
INSERT INTO redisdb12 (key, value) VALUES ('key4','value4'); INSERT 0 1 Time: 0.872 ms SELECT * FROM redisdb12; key | value ------+-------- key4 | value4 key2 | value2 key3 | value3 key1 | value1 (4 rows) Time: 1.403 ms
6、テーブルの削除
PostgreSQL
DROP FOREIGN TABLE redisdb12;
Redis側のデータが消える訳ではないので注意。
※本記事内容の無断転載を禁じます。
ご連絡は以下アドレスまでお願いします★
さくらインターネットでPython MecabをCGIから使う
さくらインターネットのPHPでAnalytics-G4 APIを使う
インクルードパスの調べ方
【Git】特定ファイルを除外する.gitignore
【Ubuntu/Debian】NVIDIA関係のドライバを自動アップデートさせない
【Python】Spacyを使用して文章から出発地と目的地を抜き出す
HomeBrewでApache2を入れて自動起動つきで動かしPHPモジュールと連携する
macOSに標準付属のApacheを自動起動つきで動かす
HomeBrewでPostgreSQLを入れて自動起動つきで動かす
Windows版Google Driveが使用中と言われアンインストールできない場合
【C/C++】小数点以下の切り捨て・切り上げ・四捨五入
進研ゼミチャレンジタッチをAndroid端末化する
Windows11+WSL2でUbuntuを使う【2】ブリッジ接続+固定IPの設定
Googleスプレッドシートで図形をコピーして使いまわすには
【Linux】iconv/libiconvをソースコードからインストール
【Apache】サーバーに同時接続可能なクライアント数を調整する
Pythonで処理にかかった時間を計測するには
Windows11のコマンドプロンプトでテキストをコピーする