標籤:
目錄
- 簡介和安裝
- redis簡介
- redis安裝
- redis運行
- node_redis安裝
- 串連到redis伺服器redis.createClient()
- 認證 client.auth(password, callback)
- 單值set和get
- client.set(key,value,[callback])
- client.get(key,[callback])
- client.set([key,value],callback)
- 多值get和set
- client.hmset(hash,obj,[callback])
- client.hmset(hash,key1,val1, ... keyn,valn,[callback])
- client.hgetall(hash,[callback])
- 打包執行多個命令[事務]
- 其它...
簡介和安裝
- 開源高效能key-value儲存;採用記憶體中(in-memory)資料集的方式,也可以採用磁碟儲存方式(前者效能高,但資料可能丟失,後者正好相反)
- 支援字串(strings)、雜湊(hashes)、列表(lists)、集合(sets)和 有序集合(sorted sets)等;支援對複雜資料結構的高速操作。
- 特性多,支援主從同步、pub/sub等
- 支援多種用戶端(http://redis.io/clients)
- ...
註:應用情境沒有提到,暫時沒有太多實際體會,不瞎說,以免誤導人,但是從它的簡介和特性來說,起碼緩衝情境是不錯的!
Redis: https://github.com/dmajkic/redis/downloads
node.js用戶端:node_redis https://github.com/mranney/node_redis/
redis非常方便,直接下載解壓就可以使用,因為開發環境是win7 64位,直接下載(樣本下載的安裝包:redis-2.4.5-win32-win64.zip)
解壓到後運行"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檔案,這就是設定檔
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
Nodejs學習筆記(九)--- 與Redis的互動(mranney/node_redis)入門