redis的高速存取性能让人印象深刻,虽然是分布式存储,但相比本地内存,性能毫不逊色。
而且多次建立从redis存取数据的链接,操作完成后关闭,性能表现超出SQL一大截。(虽然这样的设计某种程度上算是对redis性能的浪费。。。)
redis的nodejs版本API支持其几乎所有命令,现对项目中涉及的记录如下。
根据redis中的数据类型区分:
0、建立node-redis的client端连接
1 // redis 链接 2 var redis = require(‘redis‘); 3 var client = redis.createClient(‘6379‘, ‘127.0.0.1‘); 4 5 // redis 链接错误 6 client.on("error", function(error) { 7 console.log(error); 8 }); 9 // redis 验证 (reids.conf未开启验证,此项可不需要) 10 // client.auth("foobared");
在我使用的Nodejs V 0.10中,已附带了node-reids API,不需要再npm安装了。
1、set的存取
1 client.set(‘key001‘, ‘AAA‘, function (err, response) { 2 if (err) { 3 console.log("err:", err); 4 } else { 5 console.log(response); 6 client.get(‘key001‘, function (err, res) { 7 if (err) { 8 console.log("err:", err); 9 } else { 10 console.log(res); 11 client.end(); 12 } 13 }); 14 } 15 });
运行结果为:
> node redistest.js
OK
AAA
2、hash存取
hash set的设值和抽取数据都有单个key和多个key两种方式:
※ 设定单个key的值,在取值时获取特定filed下指定key的值:
1 client.hset(‘filed002‘, ‘key001‘, ‘wherethersisadoor‘, function (err, res) { 2 if (err) { 3 console.log(err); 4 } else { 5 console.log(‘res:‘, res); 6 client.hget(‘filed002‘, ‘key001‘, function (err, getRslt) { 7 if (err) { 8 console.log(err); 9 } else { 10 console.log(‘getRslt:‘, getRslt); 11 client.end(); 12 } 13 }); 14 } 15 });
运行结果如下:
> node redistest.js
res: 1
getRslt: wherethersisadoor
注意:当hget方法在指定field下找不到指定的key时,会传给回调函数null,而非空字符或undefined。
※ 设定多个key的值,取值时获取指定field下指定单个或多个key的值
1 var qe = {a: 2, b:3, c:4}; 2 client.hmset(‘field003‘, qe, function(err, response) { 3 console.log("err:", err); 4 console.log("response:", response); 5 client.hmget(‘field003‘, [‘a‘, ‘c‘], function (err, res) { 6 console.log(err); 7 console.log(res); 8 client.end(); 9 }); 10 });
运行结果如下:
> node redistest.js
err: null
response: OK
null
[ ‘2‘, ‘4‘ ]
hmset方法的设定值可以是JSON格式的数据,但是redis中key的值是以字符串形式存储的,如果JSON数据层数超过一层,会出现值是‘[object Object]‘的情况。
hmget方法的返回值是个数组,其中元素的顺序对应于参数的key数组中的顺序,如果参数数组中有在field内不存在的key,返回结果数组的对应位置会是null,也即无论是否能取到值,结果数组中的元素位置始终与参数的key数组中元素位置一一对应。
获取hash中所有key的方法是client.keys(fieldname, callback); 需要注意的是如果hash中key的数目很多,这个方法的可能耗费很长时间。
3、sorted sets 有序集合
有序集合是redis中一种有意思的数据结构,集合中元素是有序的,排序的依据是元素对应的score,在向有序集合中加入元素时,需要同时设定数据的值和对应的score,数据在有序集合中的存储位置依据score确定。
score的类型被限定为浮点数,当两个不同的元素具有相同的score时,两者的位置按照字符串大小升序排列。
有序集合中每个元素都被限制为唯一的,向一个有序集合中设定两个值相同而score不同的元素,只会更新已经被设定元素的score,这点需要注意。
1 var vals = []; 2 for (var score = 0; score < 4; score++) { 3 for (var val = 10; val < 14; val++) { 4 vals.push(score); 5 vals.push(val); 6 } 7 } 8 9 client.zadd(‘004‘, vals, function(err, res) { 10 console.log(err); 11 console.log(res); 12 client.zrange(‘004‘, 0, -1, function(err, resp) { 13 console.log(err); 14 console.log(‘range result:‘, resp); 15 client.zcount(‘004‘, -Infinity, Infinity, function(err, respo) { 16 console.log(err); 17 console.log("len:", respo); 18 client.end(); 19 }); 20 }); 21 });
执行结果如下:
> node redistest.js
null
4
null
range result: [ ‘10‘, ‘11‘, ‘12‘, ‘13‘ ]
null
len: 4
zadd方法接收数组作为设定值的参数,数组中数据顺序为[score1, key1, score2, key2,...]的形式。
参数数组中原本会有score不同的4组值,但是由于score对应的元素值相同,最终集合中仅存在一组值。
zrange方法获取指定下标范围的内的所有key值,包括起始位置和终止位置。
zcount方法获取指定集合指定范围内的元素个数,设定为-Infinity, Infinity时,可以获取数组长度。
redis中的游标设计思想类似SQL中的游标,node-redis API中使用scan方法作为游标,对应不同的数据结构,有hscan和zscan等方法。
1 client.zscan(‘004‘, 0, ‘COUNT‘, ‘1‘, function(err, res) { 2 console.log(err); 3 console.log(res); 4 console.log(res[1].length); 5 client.end(); 6 });
执行结果如下:
> node redistest.js
null
[ ‘0‘, [ ‘10‘, ‘3‘, ‘11‘, ‘3‘, ‘12‘, ‘3‘, ‘13‘, ‘3‘ ] ]
8
返回结果是一个数组。数组第一个元素是游标的返回值,标明当前读取位置,用这个值作为参数再次调用scan方法,将会从前次终止的位置继续读取集合。
数组第二个元素是游标读取的内容,数组内元素格式是[key1, score1, key2, score2...]。‘COUNT‘参数的作用是限定scan方法的读取数量,此处为起作用,原因未明,需继续调查。
4、lists 列表
列表中的元素顺序就是插入顺序,元素没有唯一性限制。
1 client.del("003", function(err, respo) { 2 client.rpush("003", [1, 2, 3, 4, 5], function(err, res) { 3 console.log(err); 4 console.log(res); 5 client.lrange(‘003‘, 0, -1, function(err, resp) { 6 console.log(err); 7 console.log("resp:", resp); 8 client.end(); 9 }); 10 }); 11 });
执行结果如下:
> node redistest.js
null
5
null
resp: [ ‘1‘, ‘2‘, ‘3‘, ‘4‘, ‘5‘ ]
使用sort方法可得到排序后的结果。
list的push方法有左右两个版本,lpush和rpush,分别表示从list的头部和尾部插入元素。
总结,对于redis中的大规模数据,单一数据类型并不经常可以很好的实现业务需求,可以通过不同数据类型的组合,在快速存储数据的基础上,快速的索引匹配数据查找。在实际使用中,用到的是将大量数据存储在hash集合中,而hash集合的key存储在有序集合中,提取key中的数字部分作为score,在有序集合中取出特定位置的key,再根据key去hash集合中取值。
接触redis的时间不长,这是个很高效的存储工具,与SQL完全不同,在扩展程序功能方面有很多可以尝试的地方,以后在设计程序时,可以将redis因素加入考虑。
原文:http://www.cnblogs.com/harelion/p/5203710.html