🔖
Node.jsのioredisを使ってRedisを操作する
はじめに
Node.jsのRedis Clientsは公式ドキュメントにもある通り node-redis
, ioredis
, tedis
などがあります。今回は ioredis
を少し触ってみたので、そのときのコードをメモしておきます。
実装コード
main.ts
import Redis from 'ioredis';
export class RedisClient {
// デフォルトは 127.0.0.1:6379 に接続する
constructor(private redis = new Redis()) {}
/**
* Redis にキーと値を設定する。
* 既に重複したキーが存在する場合は、上書きする。
*
* @param key キー
* @param value 値
*/
public async set(key: string, value: string | Buffer | number): Promise<void> {
await this.redis.set(key, value);
}
/**
* 引数で指定したキーを削除する。
*
* @param key 削除対象のキー
* @returns 削除できた場合は 1, できなかった場合は 0
*/
public async delete(key: string): Promise<number> {
return await this.redis.del(key);
}
/**
* Redis からキーに紐づく値を取得する。
* キーが存在しない場合は、null を返す。
*
* @param key 取得対象のキー
*/
public async get(key: string): Promise<string | null> {
return await this.redis.get(key);
}
/**
* Redis へのコネクションを切断する。
*/
public async quit(): Promise<void> {
await this.redis.quit();
}
/**
* コマンドを一括して送信する。
*
* @param params キーと値の配列
*/
public async pipeline(params: { key: string; value: string | Buffer | number }[]): Promise<void> {
const pipeline = this.redis.pipeline();
params.forEach((param) => {
pipeline.set(param.key, param.value);
});
await pipeline.exec();
}
/**
* list型を追加する。
*
* @param key キー
* @param value 値
*/
public async listPush(key: string, value: (string | number | Buffer)[]): Promise<void> {
await this.redis.rpush(key, ...value);
}
/**
* list型の値を取得する。
*
* @param key キー
* @param start 開始位置
* @param end 終了位置
*/
public async getList(key: string, start = 0, end = -1): Promise<string[]> {
return await this.redis.lrange(key, start, end);
}
/**
* すべてのキーを削除する。
*/
public async flushall(): Promise<void> {
await this.redis.flushall();
}
}
使い方(redis serverが起動していることが前提です。)
const redisClient = new RedisClient();
// キーと値を指定して、値を設定できる
await redisClient.set('key1', 'value');
console.log(await redisClient.get('key1')); // value
// 既に同一キーが設定されている場合、値を上書きする
await redisClient.set('key2', 'value');
await redisClient.set('key2', 'newValue');
console.log(await redisClient.get('key2')); // newValue
// キーが存在しない場合、 null を返す
console.log(await redisClient.get('notFound')); // null
// コマンドを一括して送信できる
await redisClient.pipeline([
{ key: 'pipelineKey1', value: 'pipelineValue1' },
{ key: 'pipelineKey2', value: 'pipelineValue2' },
{ key: 'pipelineKey3', value: 'pipelineValue3' },
]);
// キーを指定して、値を削除できる
await redisClient.set('deleteKey', 'value');
await redisClient.delete('deleteKey');
console.log(await redisClient.get('deleteKey')); // null
// リスト型を作成して値を追加できる
await redisClient.listPush('listKey', ['value1', 'value2', 'value3']);
console.log(await redisClient.getList('listKey')); // [ 'value1', 'value2', 'value3' ]
PubSubの仕組みも構築ができます。
pubsub.ts
import Redis from 'ioredis';
// 接続は同時に両方の役割を果たすことはできないので、それぞれでインスタンスを作成する
const pubRedis = new Redis();
const subRedis = new Redis();
// 一定時間ごとにメッセージを送信する
setInterval(() => {
const message = { foo: Math.random() };
const channel = `my-channel-${1 + Math.round(Math.random())}`;
pubRedis.publish(channel, JSON.stringify(message));
console.log('Published %s to %s', message, channel);
}, 1000);
// 指定したチャンネルのsubscribeを実施する
subRedis.subscribe('my-channel-1', 'my-channel-2', (err, count) => {
if (err) {
console.error('Failed to subscribe: %s', err.message);
} else {
console.log(`Subscribed successfully! This client is currently subscribed to ${count} channels.`);
}
});
// 設定されたsubscribeのメッセージを受信したら、コンソールに出力する
subRedis.on('message', (channel, message) => {
console.log(`Received ${message} from ${channel}`);
});
pubsub.ts
を実行結果
Subscribed successfully! This client is currently subscribed to 2 channels.
Published { foo: 0.8520497965522418 } to my-channel-2
Received {"foo":0.8520497965522418} from my-channel-2
Published { foo: 0.6859509912864634 } to my-channel-1
Received {"foo":0.6859509912864634} from my-channel-1
Published { foo: 0.5970506846840671 } to my-channel-1
Received {"foo":0.5970506846840671} from my-channel-1
Published { foo: 0.6241309846521499 } to my-channel-2
Received {"foo":0.6241309846521499} from my-channel-2
参考
Discussion