本文轉自:https://blog.csdn.net/offbye/article/details/52452322html
Redis是一個經常使用的Nosql數據庫,通常用來代替Memcached作緩存服務,同時它也支持數據的持久化,有着比較普遍的應用場景。在Java中使用redis咱們已經比較熟悉了,那麼在node.js和koa.js框架中使用Redis的正確姿式是怎樣的呢?
Redis 是徹底開源免費的,遵照BSD協議,是一個高性能的key-value數據庫。
Redis 與其餘 key - value 緩存產品有如下三個特色:
* Redis支持數據的持久化,能夠將內存中的數據保持在磁盤中,重啓的時候能夠再次加載進行使用。
* Redis不單單支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。
* Redis支持數據的備份,即master-slave模式的數據備份。node
Redis經常使用命令能夠參考http://www.runoob.com/redis/redis-keys.htmles6
Node.js已經有不少redis相關的庫,我在npm.org上搜了下大概有十幾個吧,其中常常使用的redis,co-redis。 因爲我用koa作web框架,所以就直接用了koa-redis。這篇文章涉及koa.js,yield生成器和Promise相關的知識,須要先對這些概念有必定的認識。web
下面介紹下redis和koa.js相關的操做吧,我是在Mac下操做的。redis
1. 安裝redis,並啓動客戶端和服務器端
brew install redissql
啓動服務器端 redis-server數據庫
29322:C 06 Sep 17:39:25.109 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
29322:M 06 Sep 17:39:25.111 * Increased maximum number of open files to 10032 (it was originally set to 1024).
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 3.0.6 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 29322
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'npm
29322:M 06 Sep 17:39:25.116 # Server started, Redis version 3.0.6
29322:M 06 Sep 17:39:25.116 * The server is now ready to accept connections on port 6379
啓動客戶端 redis-cli 編程
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379>
2. 安裝node.js和koa.js,node的安裝這裏就不講了,經過brew install就能夠。
npm install koa redis koa-redispromise
能夠看到koa-redis已經依賴了co-redis, es6-promisify等庫
`-- koa-redis@2.1.2
+-- co-redis@2.1.1
| `-- es6-promisify@4.1.0
| `-- es6-promise@3.2.1
`-- hiredis@0.5.0
+-- bindings@1.2.1
`-- nan@2.4.0
3. koa.js操做redis數據
這塊是本文重點,因爲官方的文檔和例子不太詳細,不熟悉node的同窗折騰起來會比較累,因此本文提供了一個比較完整的例子。具體代碼裏面註釋已經寫的比較清楚了。
var session = require('koa-generic-session');
var redisStore = require('koa-redis');
var koa = require('koa');
var redis = require('redis');
// 注意: client默認是異步callback方式調用;
// store.client是通過了co-redis包裝,返回Promise, 在koa裏面用yield異步編程比較方便
var client = redis.createClient(6379, "172.19.65.240");
var app = koa();
app.keys = ['keys', 'keykeys'];
// var option={host: "172.19.65.240", db:1};
var options = {client: client, db: 1};
var store = redisStore(options);
app.use(session({
store: store
}));
app.use(function *() {
switch (this.path) {
case '/get':
get.call(this);
break;
case '/testKV':
// 保存key value
if (this.query.adminId) {
yield store.client.set("test1", this.query.adminId);
}
//同步讀取key value
this.body = yield store.client.get("test1");
break;
case '/testHM':
//操做hashmap
var result = yield store.client.hmset("hosts", "mjr", "123", "another", "23", "home", "1234");
console.log(result);
var obj = yield store.client.hgetall("hosts")
console.dir(obj);
//獲取hashmap key的值
this.body = yield store.client.hget("hosts", "home");
//保存hashmap,使用默認的callback方式
// client.hset("hash key", "hashtest 1", "some value", redis.print);
// client.hset(["hash key", "hashtest 2", "some other value"], redis.print);
// client.hmset("hosts", "mjr", "1", "another", "23", "home", "1234");
// client.hmset(["key", "test keys 1", "test val 1", "test keys 2", "test val 2"], function (err, res) {
// console.log(res);
// });
break;
case '/testSet':
//保存set
var key = "key1";
store.client.sadd("key1", "v1");
store.client.sadd("key1", "v2");
store.client.sadd("key1", "v3");
//讀取set
store.client.multi()
.sismember(key, 'v1')
.smembers(key)
.exec(function (err, replies) {
console.log("MULTI got " + replies.length + " replies");
replies.forEach(function (reply, index) {
console.log("Reply " + index + ": " + reply.toString());
});
});
//讀取set
this.body = yield store.client.smembers("key1");
break;
case '/testList':
//保存list
store.client.rpush("mylist", "bbb")
store.client.rpush("mylist", "ccc")
store.client.lpush("mylist", "aaa")
this.body = yield store.client.rpop("mylist");
break;
case '/remove':
remove.call(this);
break;
case '/regenerate':
yield regenerate.call(this);
break;
}
});
function get() {
var session = this.session;
session.count = session.count || 0;
session.count++;
var test = store.client.get("test");
console.log(test);
this.body = session.count;
}
function remove() {
this.session = null;
this.body = 0;
}
function *regenerate() { get.call(this); yield this.regenerateSession(); get.call(this);}