Redis命令:Strings

Strings是Redis支持的最簡單數據類型,以下按照SET/GETINCR/DECRBIT 3種分類介紹字符串格式支持的命令。

SET/GET類???

最簡單的SET/GET操作:

SET mykey "hello" => "OK"
GET mykey => "hello"

SET操作會在Redis中創建一個值為hello的key(mykey)。如果key已經存在,它的值將會被覆蓋。GET操作用于獲取mykey對應的值hello。

SET操作可以附加一些參數:

SET mykey "hello" EX 10

EX 10會導致mykey在10秒后失效,超過10秒后使用GET操作會得到nil:

GET mykey => "(nil)"

PX 10000EX 10功?能相似,只是時間單位變成了毫秒。

SET mykey "hello" NX => "OK"
SET mykey "hello" XX => "OK"

NX的語義為當key不存在時才設置,XX的語義為當key存在才設置,失敗時會返回nil。

模式-通過Redis實現簡單鎖
SET lock "anyString" NX EX 10

通過上面的命令,可以借助Redis實現鎖的功能。當命令返回OK代表客戶端成功獲取到鎖;當超過10秒后,鎖會自動釋放;客戶端也可以通過DEL命令主動釋放鎖。

簡單鎖會存在兩個問題:
1、key只有一個;
2、client1獲取到鎖后,client2可以通過DEL命令釋放鎖;

改進:
1、key通過隨機算法生成字符串;
2、DEL操作前,還需要加入Value的比較,再做DEL操作;

引用一段Redis文檔中的代碼:

if redis.call("get",KEYS[1]) == ARGV[1]
then
    return redis.call("del",KEYS[1])
else
    return 0
end
批量SET/GET
MSET key1 "Hello" key2 "World" => "OK"

MGET key1 key2
=> 1) "Hello"
=> 2) "World"

批量版SET/GET操作,不過多介紹了。

SET的變種兄弟們
SETEX mykey 10 "hello" => "OK"

SET mykey "hello" EX 10具有相同功能。另還有PSETEX命令,單位為毫秒。

SETNX mykey "hello" => "(integer) 1"
SETNX mykey "hello" => "(integer) 0"

SET mykey "hello" NX具有相同功能,但返回值有些區別。

MSETNX key1 "hello" key2 "world" => "(integer) 1"
MSETNX key1 "hello" key3 "test" => "(integer) 0"

GET key3 => "(nil)"  

批量版的SETNX,只能全部寫入成功或全部失敗。

另一種鎖實現
SETNX lock.foo <current Unix time + lock timeout + 1>

假設有client1、client2、client3在競爭鎖,只有一個client的SETNX操作會返回1,代表當前client獲取到鎖。client后續可以通過DEL操作釋放鎖。

死鎖問題處理:
1、client1獲取到鎖后crash了;
2、client2通過SETNX操作嘗試獲取鎖,但是鎖仍然被client1持有,所有redis返回0;
3、client2通過GET操作,獲取lock.foo值中保存的時間戳,與當前時間比較,發現鎖已經超時;
4、client2發送GETSET lock.foo <current Unix timestamp + lock timeout + 1>操作,并檢查返回值是否依舊是超時的時間,如果超時說明client2已經獲取到了鎖;
5、如果不是超時,說明有另外的client已經修改了時間戳,client2會從步驟2重新嘗試獲取鎖;

其他

GETSET設置新值,返回老值;
SETRANGE/GETRANGE設置/獲取字符串中的一段;
STRLEN獲取字符串長度;

INCR/DECR類???

遞增操作:INCR INCRBY INCRBYFLOAT
遞減操作:DECR DECRBY

只有INCRBYFLOAT而沒有DECRBYFLOAT,但是可以通過用負數做參數實現同樣的效果。

BIT類

Bitmap,一串連續的二進制數字,可以在極少的空間內進行統計計算。Redis提供了一組的Bitmap操作。

SETBIT bitkey 10 1 => "(integer) 0"

GETBIT bitkey 10 => "(integer) 1"
GETBIT bitkey 1 => "(integer) 0"

SETBIT的值只能是0或1。當key不存在時會創建一個新的string值,Redis會確保string足夠保存指定offset的bit。offset的范圍從0到2^32-1。SETBIT的返回值是指定offset之前保存的bit。

BITCOUNT bitkey => "(integer) 1"
BITSET bitkey 0 1 => "(integer) 0"
BITCOUNT bitkey => "(integer) 2"

統計bitkey中有多少位被置為1。

模式-利用bitmap統計用戶訪問歷史
SETBIT user:yingzong 0 1 => "(integer) 0"

offset 0代表網站上線的第一天,每天遞增1。需要時可以通過BITCOUNT命令統計bitmap中被置為1的位數,代表用戶訪問天數。

便利操作BITFIELD

Redis3.2提供了BITFIELD操作,可以在一條指令中執行多個分段的Bitmap操作。

BITFIELD bitkey SET i4 0 5 => "1) (integer) 0"

用bitkey的值,0-3位保存有符號整數值5。i4代表4位有符號整數,u4代表4位無符號整數。

BITFIELD bitkey GET i4 => "1) (integer) 5"

獲取剛才保存的值。BITFIELD命令可以組合使用:

BITFIELD bitkey GET i4 0 SET u4 4 6 INCRBY u4 4 1
=> "1) (integer) 5"
=> "2) (integer) 0"
=> "3) (integer) 7"

另外BITFIELD還提供了三種溢出策略:
WRAP一個i8的整數,值為127,遞增1會導致值變為-128;
SAT一個i8的整數,值為120,遞增10會導致值變為127;
FAIL發生溢出時操作失敗;

BITFIELD bits SET i8 0 127 OVERFLOW WRAP INCRBY i8 0 1
=> "1) (integer) 0"
=> "2) (integer) -128"
其他操作

BITPOS返回第一個被設置為0或1的位置。

SETBIT pos 10 1 => "(integer) 0"

BITPOS pos 1 => "(integer) 10"

BITPOS的最后兩個參數是byte,如果執行以下命令:

BITPOS pos 0 1 => "(integer) 8" 

因為限制了從第一個字節開始(0計數),所以第一個為0的位的offset是8。

BITOP在多個key之間執行與、或、異或、非等邏輯操作。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容