前言
本文基于redis和co-redis,對redis的操作方法進(jìn)行了封裝屁擅,主要實(shí)現(xiàn)以下特性
- 使用
co
風(fēng)格訪問DB - 整個程序使用單一
redis client
-
redis client
的初始化在第一次訪問時進(jìn)行 - 封裝
scan
命令替代keys
和smembers
準(zhǔn)備DB配置文件
// config.js
var redis = {
RDS_PORT: 6379,
RDS_HOST: '127.0.0.1',
RDS_DB: '1'
};
導(dǎo)入第三方Package
var commands = require('redis-commands');
var redis = require('redis');
var wrapper = require('co-redis');
var config = require('./config'); //配置文件
- redis-commands提供了所有redis支持的命令
- redis封裝了nodejs訪問redis的所有操作
-
co-redis對redis提供的所有方法進(jìn)行了
co
風(fēng)格轉(zhuǎn)化
定義redis client的初始化操作
使用redisCo
直接進(jìn)行DB訪問,初始為undifined
,第一次進(jìn)行DB訪問時颠黎,使用initClient
函數(shù)對該對象進(jìn)行初始化
initClient
方法中,首先使用redis創(chuàng)建client
,之后配置該client
的錯誤監(jiān)聽函數(shù)待德,最后使用co-redis進(jìn)行co
化
var redisCo;
var initClient = function() {
var client = redis.createClient(config.redis.RDS_PORT,
config.redis.RDS_HOST, {
db: config.redis.RDS_DB
});
client.on('error', function(err) {
console.log('Error ' + err);
});
redisCo = wrapper(client);
};
定義helper對象作為該utils模塊的對外接口
在helper
對象的構(gòu)造函數(shù)中
- 首先使用redis-commands獲取所有
redis
命令 - 對每一個
redis
命令,在helper
中添加與該命令同名的函數(shù) -
helper
中的每個redis
的函數(shù)中枫夺,檢查并初始化redisCo
之后将宪,調(diào)用co-redis執(zhí)行該命令
由于co-redis封裝時所提供的redis命令也是從redis-commands中讀取的,從而保證了helper中命令轉(zhuǎn)發(fā)時的正確性
(參見co-redis和redis的源碼)
var helper = function() {
var self = this;
commands.list.forEach(function(command) {
self[command] = function*() {
if (redisCo === undefined) {
initClient();
}
var res = {};
var params = arguments;
res = yield redisCo[command].apply(this, params);
return res;
};
});
};
// 省略
module.exports = new helper();
為helper添加自定義方法
-
cleanup
用于批量刪除redis
中的key
橡庞,可以通過參數(shù)指定要刪除的key
的pattern
较坛,參數(shù)未指定時,刪除所有的key
helper.prototype.cleanup = function*(count) {
var partern = '';
switch (count) {
case '0':
partern = '0x01:*';
break;
case '1':
partern = '0x02:*';
break;
case '2':
partern = '0x10:*';
break;
case '3':
partern = '0x90:*';
break;
case '4':
partern = '0x91:*';
break;
default:
partern = '*';
break;
}
var keys = yield this.keys(partern);
if (keys.length !== 0) {
yield this.del(keys);
}
};
-
scanKeys
用于替代keys命令獲取符合指定pattern
的所有key
helper.prototype.scanKeys = function*(pattern) {
var ret = [];
var cursor = 0;
while (true) {
var res = yield this.scan(cursor, 'MATCH', pattern, 'COUNT', 10);
cursor = parseInt(res[0]);
ret = ret.concat(res[1]);
if (cursor === 0) {
break;
}
}
return ret;
-
scanMembers
用于替代smember
命令獲取指定set
的所有成員
helper.prototype.scanMembers = function*(key) {
var ret = [];
var cursor = 0;
while (true) {
var res = yield this.sscan(key, cursor, 'COUNT', 10);
cursor = parseInt(res[0]);
ret = ret.concat(res[1]);
if (cursor === 0) {
break;
}
}
return ret;
};
- 其他
完整的代碼
//dbhelper.js
'use strict';
var commands = require('redis-commands');
var redis = require('redis');
var wrapper = require('co-redis');
var config = require('../config');
var redisCo;
var initClient = function() {
var client = redis.createClient(config.redis.RDS_PORT,
config.redis.RDS_HOST, {
db: config.redis.RDS_DB
});
client.on('error', function(err) {
console.log('Error ' + err);
});
redisCo = wrapper(client);
};
var helper = function() {
var self = this;
commands.list.forEach(function(command) {
self[command] = function*() {
if (redisCo === undefined) {
initClient();
}
var res = {};
var params = arguments;
res = yield redisCo[command].apply(this, params);
return res;
};
});
};
helper.prototype.cleanup = function*(count) {
var partern = '';
switch (count) {
case '0':
partern = '0x01:*';
break;
case '1':
partern = '0x02:*';
break;
case '2':
partern = '0x10:*';
break;
case '3':
partern = '0x90:*';
break;
case '4':
partern = '0x91:*';
break;
default:
partern = '*';
break;
}
var keys = yield this.keys(partern);
if (keys.length !== 0) {
yield this.del(keys);
}
};
helper.prototype.scanKeys = function*(pattern) {
var ret = [];
var cursor = 0;
while (true) {
var res = yield this.scan(cursor, 'MATCH', pattern, 'COUNT', 10);
cursor = parseInt(res[0]);
ret = ret.concat(res[1]);
if (cursor === 0) {
break;
}
}
return ret;
};
helper.prototype.scanMembers = function*(key) {
var ret = [];
var cursor = 0;
while (true) {
var res = yield this.sscan(key, cursor, 'COUNT', 10);
cursor = parseInt(res[0]);
ret = ret.concat(res[1]);
if (cursor === 0) {
break;
}
}
return ret;
};
module.exports = new helper();