MyException - 我的异常网
当前位置:我的异常网» JavaScript » Nodejs学习笔记(9)- 与Redis的交互(mranney/node

Nodejs学习笔记(9)- 与Redis的交互(mranney/node_redis)入门

www.MyException.Cn  网友分享于:2015-08-26  浏览:0次
Nodejs学习笔记(九)--- 与Redis的交互(mranney/node_redis)入门

目录

简介和安装

  • redis简介:
  1. 开源高性能key-value存储;采用内存中(in-memory)数据集的方式,也可以采用磁盘存储方式(前者性能高,但数据可能丢失,后者正好相反)
  2. 支持字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)和 有序集合(sorted sets)等;支持对复杂数据结构的高速操作。
  3. 特性多,支持主从同步、pub/sub等
  4. 支持多种客户端(http://redis.io/clients
  5. ...

  注:应用场景没有提到,暂时没有太多实际体会,不瞎说,以免误导人,但是从它的简介和特性来说,起码缓存场景是不错的!

  Redis下载地址: https://github.com/dmajkic/redis/downloads  

  node.js客户端:node_redis https://github.com/mranney/node_redis/

  • redis安装(Windows平台)

   redis非常方便,直接下载解压就可以使用,因为开发环境是win7 64位,直接下载(示例下载的安装包:redis-2.4.5-win32-win64.zip)

  • redis运行

  解压到后运行"64bit"文件夹下的redis-server.exe即可,但是这样运行会出现一个如下警告提示:

  #Warning: no config file specified,using the default config. In order to specify a config file use ‘redis-server /path/to/redis.conf’

  提示也比较明显,没有明确的配置文件,使用的是默认配置,请使用‘redis-server /path/to/redis.conf’指定明确的配置文件

   根据提示运行redis成功(如下图)

  在redis-server.exe同级目录下可以看到一个redis.conf文件,这就是配置文件

  • node_redis安装
npm install redis
或者
npm install hiredis redis

  我这里采用 npm install hiredis redis 安装

  注:两种都可用,区别在于性能,hiredis是非阻塞的,而且速度更快;如果安装了hiredis,node_redis则会默认以它为解析器,没安装就会用纯javascript解释器,对于学习或者开发环境,用哪个都无所谓

redis.createClient()连接到redis服务器

  环境都准备好了,就开始写一代简单的代码测试用nodejs连接一下服务器

var redis = require('redis'),
    client = redis.createClient();

client.on('ready',function(err){
    console.log('ready');
});
示例源码

  从上图中可以看到运行结果,输出ready,表示成功!  

  对代码还是讲一下:

  redis.createClient():返回的是一个RedisClient的对象,大家可以输出来看一下此对象的具体信息。

  ready:Redis的Connection事件之一,当与redis服务器连接成功后会触发这个事件,此时表示已经准备好接收命令,当这个事件触发之前client命令会存在队列中,当一切准备就绪后按顺序调用

 

  对于上面的几句代码就能连接成功redis服务器,原因是当前redis服务器在本地,如果不在本地,怎么连接呢?

var redis = require('redis'),
    RDS_PORT = 6379,        //端口号
    RDS_HOST = '127.0.1.1',    //服务器IP
    RDS_OPTS = {},            //设置项
    client = redis.createClient(RDS_PORT,RDS_HOST,RDS_OPTS);

client.on('ready',function(res){
    console.log('ready');    
});
示例源码

  也是成功!这种方式和上一种在redis.createClient()时分别传入了端口号、服务器IP和设置项

  这样就可以用于连接远程的redis服务器,或者利用第三个参数进行一些配置!

  redis的默认端口:6379

认证 client.auth(password, callback)

  上面试过了,连接到redis服务器,可以看出我们并没有输入密码进行验证的过程就成功连接到了服务器,因为redis服务器默认不需要密码,不过这不太安全,我们肯定要设置一下密码

  打开redis.conf文件,找到requirepass,取消注释,设置密码为:porschev

requirepass porschev

  然后重启redis服务器;再次利用上面的代码连接到redis服务器,出现错误提示(如下图):ERR operation not permitted

  那么如何连接到有密码的redis服务器呢?

  简单的试了一下,有两种方法(可能有更多,没试,其实一种完全就够了,多了也没用^_^!)

  方式一:通过设置redis.createClient()的第三个参数,也就是设置项来完成

 

var redis = require('redis'),
    RDS_PORT = 6379,        //端口号
    RDS_HOST = '127.0.1.1',    //服务器IP
    RDS_PWD = 'porschev',
    RDS_OPTS = {auth_pass:RDS_PWD},            //设置项
    client = redis.createClient(RDS_PORT,RDS_HOST,RDS_OPTS);

client.on('ready',function(res){
    console.log('ready');    
});
示例源码

  上图可以连接成功,通过设置连接设置项中的auth_pass来通过认证!

  auth_pass:默认值为null,默认情况下客户端将不通过auth命令连接,如果设置了此项,客户端将调用auth命令连接

  方式二:通过client.auth(password, callback)

var redis = require('redis'),
    RDS_PORT = 6379,        //端口号
    RDS_HOST = '127.0.1.1',    //服务器IP
    RDS_PWD = 'porschev',
    RDS_OPTS = {},            //设置项
    client = redis.createClient(RDS_PORT,RDS_HOST,RDS_OPTS);

client.auth(RDS_PWD,function(){
    console.log('通过认证');
});

client.on('ready',function(res){
    console.log('ready');    
});
示例源码

  此方法也可以成功,第一个参数为密码,第二个为回调函数!

单值set和get

var redis = require('redis'),
    RDS_PORT = 6379,        //端口号
    RDS_HOST = '127.0.1.1',    //服务器IP
    RDS_PWD = 'porschev',    //密码    
    RDS_OPTS = {},            //设置项
    client = redis.createClient(RDS_PORT,RDS_HOST,RDS_OPTS);

client.auth(RDS_PWD,function(){
    console.log('通过认证');
});

client.on('connect',function(){
    client.set('author', 'Wilson',redis.print);
    client.get('author', redis.print);
    console.log('connect');
});

client.on('ready',function(err){
    console.log('ready');
});
示例源码

  从输出结果可以看出,set一个值和获取这个值都成功!

  代码讲一下:

  client.set(key,value,[callback]):设置单个key和value,回调函数可选

  client.get(key,[callback]):得到key得到value,回调函数可选(虽然可选,但不写回调函数获取又有什么意义呢^_^!)

  connect:Redis的Connection事件之一,在不设置client.options.no_ready_check的情况下,客户端触发connect同时它会发出ready,如果设置了client.options.no_ready_check,当这个stream被连接时会触发connect,

          这时候就可以自由尝试发命令

  redis.print:简便的回调函数,测试时显示返回值(从示例的输出结果中可以看出)

 

  其它补充说明:

      client.options.no_ready_check:默认值为false,当连接到一台redis服务器时,服务器也许正在从磁盘中加载数据库,当正在加载阶段,redis服务器不会响应任何命令,node_redis会发送一个“准备确认”的INFO命令,

                 INFO命令得到响应表示此时服务器可以提供服务,这时node_redis会触发"ready"事件,如果该设置项设置为true,则不会有这种检查

  client.set([key,value],callback):与client.set(key,value,[callback]);效果一致(可以自行对上面示例源码进行修改进行测试),必须要有回调函数

多值get和set

var redis = require('redis'),
    RDS_PORT = 6379,        //端口号
    RDS_HOST = '127.0.1.1',    //服务器IP
    RDS_PWD = 'porschev',    //密码    
    RDS_OPTS = {},            //设置项
    client = redis.createClient(RDS_PORT,RDS_HOST,RDS_OPTS);

client.auth(RDS_PWD,function(){
    console.log('通过认证');
});

client.on('connect',function(){
    client.hmset('short', {'js':'javascript','C#':'C Sharp'}, redis.print);
    client.hmset('short', 'SQL','Structured Query Language','HTML','HyperText Mark-up Language', redis.print);

    client.hgetall("short", function(err,res){
        if(err)
        {
            console.log('Error:'+ err);
            return;
        }            
        console.dir(res);
    });
});

client.on('ready',function(err){
    console.log('ready');
});
示例源码

  从输出结果可以看出,set多值和获取都成功!

  代码讲一下:

  client.hmset(hash, obj, [callback]):赋值操作,第一个参数是hash名称;第二个参数是object对象,其中key1:value1。。,keyn:valuen形式;第三个参数是可选回调函数

  client.hmset(hash, key1, val1, ... keyn, valn, [callback]):与上面做用一致,第2个参数到可选回调函数之前的参数都是key1, val1, ... keyn, valn形式;

  client.hgetall(hash, [callback]):获取值操作,返回一个对象

 

  其它补充说明:

  console.dir()用于显示一个对象所有的属性和方法

打包执行多个命令[事务]

var redis = require('redis'),
    RDS_PORT = 6379,        //端口号
    RDS_HOST = '127.0.1.1',    //服务器IP
    RDS_PWD = 'porschev',    //密码    
    RDS_OPTS = {},            //设置项
    client = redis.createClient(RDS_PORT,RDS_HOST,RDS_OPTS);

client.auth(RDS_PWD,function(){
    console.log('通过认证');
});

client.on('end',function(err){
    console.log('end');
});

client.on('connect',function(){
    var key = 'skills';
      client.sadd(key, 'C#','java',redis.print);
      client.sadd(key, 'nodejs');
      client.sadd(key, "MySQL");
      
      client.multi()      
      .sismember(key,'C#')
      .smembers(key)
      .exec(function (err, replies) {
            console.log("MULTI got " + replies.length + " replies");
            replies.forEach(function (reply, index) {
                console.log("Reply " + index + ": " + reply.toString());
            });
            client.quit();
    });
});
示例源码

  官方有个示例,我修改一下,可能更好理解一些,下面一步步说吧!

    先了解一下API再看结果

  client.multi([commands]):这个标记一个事务的开始,由Multi.exec原子性的执行;github上描述是可以理解为打包,把要执行的命令存放在队列中,redis服务器会原子性的执行所有命令,node_redis接口返回一个Multi对象

  Multi.exec( callback ):执行事务内所有命令;github上描述是client.multi()返回一个Multi对象,它包含了所有命令,直到Multi.exec()被调用;

  Multi.exec( callback )回调函数参数err:返回null或者Array,出错则返回对应命令序列链中发生错误的错误信息,这个数组中最后一个元素是源自exec本身的一个EXECABORT类型的错误

  Multi.exec( callback )回调函数参数results返回null或者Array,返回命令链中每个命令的返回信息

  end:redis已建立的连接被关闭时触发

  client.sadd(key,value1,...valuen,[callback]):集合操作,向集合key中添加N个元素,已存在元素的将忽略;redis2.4版本前只能添加一个值

  sismember(key,value,[callback]):元素value是否存在于集合key中,存在返回1,不存在返回0

  smembers(key,[callback]):返回集合 key 中的所有成员,不存在的集合key也不会报错,而是当作空集返回

  client.quit():与之对应的还有一个client.end()方法,相对比较暴力;client.quit方法会接收到所有响应后发送quit命令,而client.end则是直接关闭;都是触发end事件

 

  再看结果应该就比较简单了,client.multi打包了sismember和smembers两个命令,执行exec方法后,回调函数得到两个回应,分别输出两个回应的结果!

其它...

  redis.debug_mode:这个在开发中可能有用,大家自行设置试一下,设置为true后,看输出

  Publish / Subscribe:这个官方示例比较简单清晰,大家运行起来看一下就能理解,深入的网上还有很多用它实现的聊天、监控示例,大家看一下,如果以后觉得有必要就再做个示例分享一下

  client.monitor:监控,可能以后会用到,有需要的深入研究一下,入门可以略过

 

  其它redis命令还有不少,能讲到的非常有限,深入练习可以对照:http://redis.readthedocs.org/en/latest/index.html

 

  参数资料:

  https://github.com/mranney/node_redis/

  http://redis.readthedocs.org/en/latest/index.html

  http://dumbee.net/archives/114

文章评论

Java程序员必看电影
Java程序员必看电影
一个程序员的时间管理
一个程序员的时间管理
 程序员的样子
程序员的样子
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
鲜为人知的编程真相
鲜为人知的编程真相
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
程序员和编码员之间的区别
程序员和编码员之间的区别
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
老程序员的下场
老程序员的下场
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
总结2014中国互联网十大段子
总结2014中国互联网十大段子
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
程序员必看的十大电影
程序员必看的十大电影
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
为什么程序员都是夜猫子
为什么程序员都是夜猫子
程序员都该阅读的书
程序员都该阅读的书
我的丈夫是个程序员
我的丈夫是个程序员
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
程序员的鄙视链
程序员的鄙视链
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
编程语言是女人
编程语言是女人
代码女神横空出世
代码女神横空出世
如何成为一名黑客
如何成为一名黑客
10个调试和排错的小建议
10个调试和排错的小建议
程序员应该关注的一些事儿
程序员应该关注的一些事儿
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
我是如何打败拖延症的
我是如何打败拖延症的
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
每天工作4小时的程序员
每天工作4小时的程序员
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
那些争议最大的编程观点
那些争议最大的编程观点
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有