Node.js中使用redis数据库的正确姿势

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模式的数据备份。

Redis常用命令可以参考http://www.runoob.com/redis/redis-keys.html

Node.js已经有很多redis相关的库,我在npm.org上搜了下大概有十几个吧,其中经常使用的redis,co-redis。 由于我用koa做web框架,因此就直接用了koa-redis。这篇文章涉及koa.js,yield生成器和Promise相关的知识,需要先对这些概念有一定的认识。

下面介绍下redis和koa.js相关的操作吧,我是在Mac下操作的。

1. 安装redis,并启动客户端和服务器端

brew install redis

  • 启动服务器端 redis-server

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    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
    `-._ `-._`-.__.-'_.-' _.-'
    |`-._`-._ `-.__.-' _.-'_.-'|
    | `-._`-._ _.-'_.-' |
    `-._ `-._`-.__.-'_.-' _.-'
    `-._ `-.__.-' _.-'
    `-._ _.-'
    `-.__.-'

    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

    1
    2
    3
    4
    5
    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-redis

可以看到koa-redis已经依赖了co-redis, es6-promisify等库

1
2
3
4
5
6
7
`-- 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的同学折腾起来会比较累,所以本文提供了一个比较完整的例子。具体代码里面注释已经写的比较清楚了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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);
}

app.listen(8080);

关于在koa框架中使用redis就写这么多吧,其实还有发布-订阅等的用法,这里就不说了。

本文独立博客地址

Contents
  1. 1. 1. 安装redis,并启动客户端和服务器端
  2. 2. 2. 安装node.js和koa.js,node的安装这里就不讲了,通过brew install就可以。
  3. 3. 3. koa.js操作redis数据
,