Redisとは?
オープンソースのKey-Value型のデータベース。利用できるデータ構造は様々存在する。パフォーマンスの高速性からとても人気がある。
今回はDockerからこれを立てて、もう一つのコンテナから接続、操作をしてみる。
まずは立ててみよう
公式イメージが用意されている。
以下のdocker-compose.yml
からコンテナを作ってみる。
version: '3.7'
services:
redis:
image: redis
ports:
- 6379:6379
これでコンテナを作成。
docker compose up
ターミナルからデータを操作してみよう
作成したターミナルに接続してみる。
docker exec -it <作成したコンテナid> bash
redis-cli
で中を見てみる。
redis-cli
試しにデータの操作を行ってみよう。set key value
で値を入れる。
127.0.0.1:6379> set test-key test-value
OK
keys *
で全てのキーを取得、set key value
で値を確認できる。
127.0.0.1:6379> keys *
1) "test-key"
127.0.0.1:6379> get test-key
"test-value"
del key value
でキーの削除ができる。
127.0.0.1:6379> del test-key
(integer) 1
127.0.0.1:6379> keys *
(empty array)
このように操作ができた。コマンドはこの他にも以下のようなもの↓がいろいろある。
別のコンテナから操作してみる
別のコンテナからredisに対しての接続を行い、ioredis
を用いて操作してみる。
docker-compose.yml
を修正する。
version: '3.7'
services:
redis:
image: redis
volumes:
- ./redis/data:/data
ports:
- 6379:6379
app:
image: node
volumes:
- ./app:/app
depends_on:
- redis
ports:
- 3000:3000
tty: true
working_dir: "/app"
command: bash -c "npm run start"
- redisとappの二つのコンテナを作成する。
-
docker-compose.yml
を置いたディレクトリに、app
ディレクトリとredis
ディレクトリを作成する。-
volumes:
でその中身をコピーする。
-
- appへの接続はポート
3000
で行い、そこからredisへの接続はポート6379
で行う。
-
app
下でnpm init -y
を行う。ここに以下のファイルindex.ts
を作成する。
import express from "express";
import Redis from "ioredis";
const app = express();
const port = 3000;
const redisPort = 6379;
const redis = new Redis(redisPort, "redis")
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.post("/posts", async(req, res) => {
await redis.set(req.body.id, req.body.name);
return res.send(req.body);
})
app.get("/gets", async(req, res) => {
const name = await redis.get(<string>req.query.id);
return res.send(name);
})
app.listen(port, () => console.log(`SERVER started on localhost:${port}`));
posts
で受け取った情報をredis.set(req.body.id, req.body.name)
で登録、
gets
で指定されたidからredis.get(<string>req.query.id)
で値を取得して返す。
package.json
で以下のスクリプトをセットしておく。
"scripts": {
"start": "npx ts-node index.ts"
}
コンテナ実行時にbash -c "npm run start"
でこれが実行される。
localhost:3000/posts
とlocalhost:3000/gets
に対してPOST,リクエストを送信し、正しく取得できれば成功。
ハッシュ型のデータ構造
別のデータ構造を試してみる。まず前のデータを消しておこう。
flushall
ハッシュ型のデータ構造を試してみる。
こちらではkey
とfield
の二つから情報を登録することができる。RDBのような感覚で使うことができるようになる。
HSET key field value
HGET key field
index.tsを以下のように書き換える。
import express from "express";
import Redis from "ioredis";
const app = express();
const port = 3000;
const redisPort = 6379;
const redis = new Redis(redisPort, "redis")
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.post("/posts", async(req, res) => {
await redis.hset(<string>req.body.id, <string>req.body.field, <string>req.body.value);
return res.send(req.body);
})
app.get("/gets", async(req, res) => {
const value = await redis.hget(<string>req.query.id, <string>req.query.field);
return res.send(value);
})
app.listen(port, () => console.log(`SERVER started on localhost:${port}`));
id, fieldの二つから登録、取得ができればOK.
そのほかList型などのデータ構造が存在する。
pub/subを使ってみる
redisにはpubsubによるメッセージングの機能がある。
これを使ってみよう。
先ほどのindex.tsに以下を加える。
redis.on("message", (channel, msg) =>{
console.log("getMessage");
console.log({channel});
console.log({msg});
});
redis.subscribe("pubsubMessage");
- redisが
message
イベントを受け取ったとき、その内容を出力する。 - redisが
"pubsubMessage"
チャンネルをsubscribeすることを登録する。
これを動かした状態で、今度はコマンドからこのチャンネルを叩いてみる。redisのコンテナのターミナルにアクセスし、以下を実行する。
redis-cli
ここから、以下のようにメッセージを送信する。
publish pubsubMessage "test"
これで先ほど動かしておいたindex.tsの方の出力でこの内容を受け取れていればOK。
参考