Node.js+Redisタイマタスクの実装
4583 ワード
Node.js+Redisタイマタスクの実装
ラベル(スペース区切り):Node.js
[TOC]
概要
Redisの2.8.0バージョンの後、2.0.0バージョンのsubscribe
に合わせてこのタイミングタスクの操作を完了できるキー空間メッセージ(Redis Keyspace Notifications)が発売されましたが、タイミングの単位は秒です.
Redisのパブリケーションとサブスクリプション(Publish/Subscribe)
Redisは2.0.0以降、Pub / Sub
の命令を出した.つまり、パブリケーション側はRedisの特定のチャンネルにメッセージを送信し、サブスクリプション側はRedisの特定のチャンネルから値を取り、簡単なメッセージキューを形成した.
たとえば
パブリケーション側は、foo
チャンネルにメッセージbar
をプッシュすることができ、直接:PUBLISH foo bar
サブスクリプション側はクライアントでfooチャンネルをサブスクリプションするとこのメッセージを受け取ることができます.
例えばNode.jsの中でioredisというバッグを使うと、このように見えます.var Redis = require("ioredis");
var sub = new Redis(/** */);
sub.once("connect", function() {
// redis db, db 0
sub.select(DB_NUMBER, function(err) {
if(err) process.exit(4);
sub.subscribe("foo", function() {
//...
});
});
});
// `foo`
sub.on("message", function(channel, msg) {
console.log(channel, msg);
});
Redisのキースペースアラート(Redis Keyspace Notifications)
Redisには、キーの有効期限、キーの削除など、いくつかのイベントがあります.その後、Redis
がこれらのイベントをトリガーすると、特定のChannel
にメッセージをプッシュすることができます.
メッセージ・タイプとチャンネル名の命名規則
チャンネル名の命名規則
チャンネル名の命名規則は__keyspace@
+dbnumber
+__:
+key_name
である.例えば、db 0データベースにおけるキー名foo
のチャネル名__keyspace@0__:foo
メッセージ・タイプredis.conf
のファイルにnotify-keyspace-events
がある.その値はEx
、Klg
などであり、これらのアルファベットの具体的な意味は以下の通りである.K, keyspace , __keyspace@__ 。
E, keyevent , __keyevent@__ 。
g, , DEL、EXPIRE、RENAME 。
$, (String) 。
l, (List) 。
s, (Set) 。
h, (Hash) 。
z, (Sorted Set) 。
x, , g EXPIRE ,g EXPIRE EXPIRE key ttl , key 。
e, , key 。
A,g$lshzxe 。 AKE 。
redisの設定
redis.conf
プロファイルを変更し、次のプロファイルを開きます.notify-keyspace-events Ex //
サンプルコード
const redis = require('redis');
const uuid = require('node-uuid');
const redis_config = {
host: "172.16.203.138",
port: 6379,
password: 'user',
db: 1
}
//
const redis_server = redis.createClient(redis_config); //
redis_server.on('connect', () => {
console.log('redis_server connected')
})
redis_server.on('error', () => {
console.log('error occured from redis_server')
})
const redis_cli = redis.createClient(redis_config);
redis_cli.on('connect', () => {
console.log("redis_cli connected")
})
redis_cli.on('error', () => {
console.log("error occured from redis_cli")
})
//
const test = (message) => {
console.log(" test " + message)
}
const funcs = {
test
}
//
const SampleTaskMaker = (message, func_name, timeout) => {
let message_obj = {
message: message,
func_name: func_name,
timeout: timeout
}
let key = JSON.stringify(message_obj);
let content = "";
redis_server.multi()
.set(key, content)
.expire(key, timeout)
.exec((error) => {
if (error) {
console.log(" ");
return;
} else {
console.log(" ")
}
});
console.log({
key
})
return key;
}
//
SampleTaskMaker(" ", "test", 2);
//
const SampleOnExpired = (channel, key) => {
console.log(" ")
let message_obj = JSON.parse(key);
let message = message_obj.message;
let func_name = message_obj.func_name;
funcs[func_name](message);
}
// 。 @1 , db1. @1
let subscribeKey = "__keyevent@1__:expired";
//
redis_cli.once('connect', () => {
redis_cli.subscribe(subscribeKey, () => {
console.log(" ");
})
})
// ‘__keyevent@2__:expired’
redis_cli.on("message", SampleOnExpired);
リファレンスドキュメント
PUBLISH foo bar
var Redis = require("ioredis");
var sub = new Redis(/** */);
sub.once("connect", function() {
// redis db, db 0
sub.select(DB_NUMBER, function(err) {
if(err) process.exit(4);
sub.subscribe("foo", function() {
//...
});
});
});
// `foo`
sub.on("message", function(channel, msg) {
console.log(channel, msg);
});
K, keyspace , __keyspace@__ 。
E, keyevent , __keyevent@__ 。
g, , DEL、EXPIRE、RENAME 。
$, (String) 。
l, (List) 。
s, (Set) 。
h, (Hash) 。
z, (Sorted Set) 。
x, , g EXPIRE ,g EXPIRE EXPIRE key ttl , key 。
e, , key 。
A,g$lshzxe 。 AKE 。
notify-keyspace-events Ex //
const redis = require('redis');
const uuid = require('node-uuid');
const redis_config = {
host: "172.16.203.138",
port: 6379,
password: 'user',
db: 1
}
//
const redis_server = redis.createClient(redis_config); //
redis_server.on('connect', () => {
console.log('redis_server connected')
})
redis_server.on('error', () => {
console.log('error occured from redis_server')
})
const redis_cli = redis.createClient(redis_config);
redis_cli.on('connect', () => {
console.log("redis_cli connected")
})
redis_cli.on('error', () => {
console.log("error occured from redis_cli")
})
//
const test = (message) => {
console.log(" test " + message)
}
const funcs = {
test
}
//
const SampleTaskMaker = (message, func_name, timeout) => {
let message_obj = {
message: message,
func_name: func_name,
timeout: timeout
}
let key = JSON.stringify(message_obj);
let content = "";
redis_server.multi()
.set(key, content)
.expire(key, timeout)
.exec((error) => {
if (error) {
console.log(" ");
return;
} else {
console.log(" ")
}
});
console.log({
key
})
return key;
}
//
SampleTaskMaker(" ", "test", 2);
//
const SampleOnExpired = (channel, key) => {
console.log(" ")
let message_obj = JSON.parse(key);
let message = message_obj.message;
let func_name = message_obj.func_name;
funcs[func_name](message);
}
// 。 @1 , db1. @1
let subscribeKey = "__keyevent@1__:expired";
//
redis_cli.once('connect', () => {
redis_cli.subscribe(subscribeKey, () => {
console.log(" ");
})
})
// ‘__keyevent@2__:expired’
redis_cli.on("message", SampleOnExpired);