文章目錄
- string 字符串
- 常用命令
- 設置和獲取
- set
- get
- mget & mset
- 計數操作
- incr & incrby
- decr & decrby
- incrbyfloat
- 字符串操作
- append
- strlen
- getrange
- setrange
- 應用場景
string 字符串
關于 Redis 的字符串,有幾點需要注意
- Redis 所有的 key 的類型都是字符串類型
- value 的多種數據結構也都是在字符串的基礎上構建的,例如列表和集合的元素類型都是字符串類型
- 字符串類型的值,可以是字符串,包括一般格式的字符串、JSON、XML格式的字符串;數字,可以是整數、浮點型;也可以是二進制數據流,例如圖片、音頻、視頻
- 一個字符串的最大長度不能超過 512MB
- Redis 內部存儲字符串完全是按照二進制流的形式保存,所以不處理編碼問題,客戶端傳入什么字符集編碼,就存儲什么
常用命令
設置和獲取
set
將 string 類型的 value 設置到 key 中。如果 key 存在,則覆蓋,無論原來的類型是什么。如果之前有設置 TTL(過期時間),也會失效
set key value [expiration EX seconds | PX milliseconds] [NX | XX]
[ ] 中為可選選項
- EX seconds:使用秒為單位設置 key 的過期時間
- PX milliseconds:使用毫秒為單位設置 key 的過期時間
- NX:key 不存在時才進行設置
- XX:key 存在時才進行設置
如果設置成功,返回 OK;如果由于選項 NX 或 XX 條件不滿足,set 不會執行,并返回(nil)
Redis 也支持上述選項和 set 的合并,如 SETEX、PSETEX、SETNX、SETXX
示例:
127.0.0.1:6379> set key1 111 ex 10
OK
127.0.0.1:6379> ttl key1
(integer) 7
127.0.0.1:6379> ttl key1
(integer) 5
127.0.0.1:6379> set key2 hello nx
OK
127.0.0.1:6379> set key2 111 nx
(nil)
127.0.0.1:6379> set key2 111 xx
OK
127.0.0.1:6379> get key2
"111"
127.0.0.1:6379> setnx key3 hi
(integer) 1
127.0.0.1:6379> psetex key4 1000000 hello
OK
127.0.0.1:6379> pttl key4
(integer) 997750
set、setxx、setnx 執行流程如下:
get
獲取 key 對應的 value。如果 key 不存在,返回 nil。如果 value 的數據類型不是 string,則會報錯
get key
mget & mset
mget
一次性獲取多個 key 的值。如果對應的 key 不存在或者對應的數據類型不是 string,返回 nil
如果 mget 多個 key,其中有不存在的,不會報錯,而是返回 nil
mget key [key…]
示例:
127.0.0.1:6379> keys *
1) "key2"
2) "key3"
3) "key4"
127.0.0.1:6379> mget key2 key1 key4
1) "111"
2) (nil)
3) "hello"
mset
一次性設置多個 key
mset key value [key value…]
只要 key value 沒問題,則返回都是 OK
示例:
127.0.0.1:6379> mset key1 111 key2
(error) ERR wrong number of arguments for MSET
127.0.0.1:6379> mset key1 111 key2 hello
OK
因為 Redis 是客戶端服務器架構,需要進行網絡通信,多個 get/set 命令意味著多次網絡通信,而 mget/mset 可以將多次 get/set 合并,減少網絡通信,性能會更好
PS:但同時也要注意,Redis 執行命令是單線程,不宜單條命令太多復雜,如果 mget/mset 執行過久,會導致其他業務阻塞,無法與 Redis 交互
計數操作
incr & incrby
incr
將 key 對應的 string 表示的數字加一
如果 key 不存在,則先設置 key 對應的 value 為0,再加一
如果 key 對應的 string 不是一個整數或者范圍超過 64 位有符號整型,則報錯
incr key
127.0.0.1:6379> set key1 111
OK
127.0.0.1:6379> incr key1
(integer) 112
127.0.0.1:6379> incr key2
(integer) 1
incrby
將 key 對應的 string 表示的數字加上對應的值,值可正可負
如果 key 不存在,則視為 key 對應的 value 為 0
如果 key 對應的 string 不是整型或者范圍超過64位有符號整數,則報錯
incrby key decrement
127.0.0.1:6379> get key1
"112"
127.0.0.1:6379> incrby key1 100
(integer) 212
decr & decrby
decr
用法同 incr 和 incrby,效果是減去
如果不存在 key,則視為 key 對應的 value 為 0
如果 key 對應的 string 不是整型或者范圍超過64位有符號整數,則報錯
decr key
127.0.0.1:6379> get key1
"212"
127.0.0.1:6379> decr key1
(integer) 211
decrby
decrby key decrement
127.0.0.1:6379> get key1
"211"
127.0.0.1:6379> decrby key1 100
(integer) 111
incrbyfloat
將 key 對應的 string 表示的浮點數加上對應的值,值可正可負
如果 key 不存在,則視為 key 對應的 value 是 0。
如果 key 對應的不是 string,或者不是?個浮點數,則報錯。
允許采用科學計數法表示浮點數
incrbyfloat key
示例:
127.0.0.1:6379> set float1 10.50
OK
127.0.0.1:6379> incrbyfloat float1 0.1
"10.6"
127.0.0.1:6379> incrbyfloat float1 -5.0
"5.6"
127.0.0.1:6379> set float2 6.0e3
OK
127.0.0.1:6379> get float2
"6.0e3"
127.0.0.1:6379> incrbyfloat float2 3.0e2
"6300"
PS:很多存儲系統和編程語言內部使用 CAS 機制實現計數功能,有一定的 CPU 開銷,但因為 Redis 是單線程架構,任何命令在 Redis 服務端都要順序執行,所以不存在上述開銷
字符串操作
append
如果 key 已經存在并且是一個 string,則會將 value 追加到 原有 string 的后面。如果 key 不存在,則效果會等同于 set 命令
append key value
返回值:追加后 string 的長度,單位是字節
示例:
127.0.0.1:6379> set key1 hello
OK
127.0.0.1:6379> append key1 world
10
127.0.0.1:6379> get key1
helloworld127.0.0.1:6379> append key2 你好
6
127.0.0.1:6379> append key2 hello
11
127.0.0.1:6379> get key2
你好hello
PS:因為 Redis 存儲是不對字符串進行處理的,存入什么編碼就是什么編碼,此處是在 Xshell 操作客戶端,使用的是 UTF-8 編碼,漢字占三個字節,所以 “你好” 占 6 個字節
另外,使用 redis-cli
啟動客戶端,get 是讀取字節,對于漢字是不會進行翻譯的
127.0.0.1:6379> get key2
"\xe4\xbd\xa0\xe5\xa5\xbdhello"
可以添加參數 redis-cli --raw
啟動客戶端,get 獲取到漢字時就會嘗試進行翻譯
strlen
獲取 key 對應的 string 的長度。當 key 存放的類型不是 string 時,報錯
strlen key
返回值:string 的長度,單位是字節;當 key 不存在時,返回 0
示例:
127.0.0.1:6379> set key1 "hello world"
OK
127.0.0.1:6379> strlen key1
(integer) 11
127.0.0.1:6379> keys *
1) "key1"
127.0.0.1:6379> strlen key2
(integer) 0
getrange
返回 key 對應的 string 的子串,由 start 和 end 確定(左閉右閉),單位為字節。可以使用負數表示倒數,-1 表示倒數第一個字節,-2 表示倒數第二個,以此類推。超過范圍的偏移量會根據 string 的長度調整為正確的值
getrange key start end
返回值:獲取到的 string 的子串。如果 key 不存在,返回空串
示例:
127.0.0.1:6379> get key1
hello world
127.0.0.1:6379> get key2
你好
127.0.0.1:6379> getrange key1 0 -1
hello world
127.0.0.1:6379> getrange key1 1 -2
ello worl
127.0.0.1:6379> getrange key2 0 -1
你好
127.0.0.1:6379> getrange key2 1 -2
?
127.0.0.1:6379> getrange key3 0 4
因為使用 XShell,編碼格式為 UTF-8,漢字占3個字節,getrange 獲取 “你好” 的第 1 字節到 第 4 字節,會出現亂碼問題
setrange
覆蓋字符串的一部分,從指定的偏移量開始,覆蓋的范圍根據 value 指定
setrange key offset value
返回值:替換后的 string 的長度,單位字節
示例:
127.0.0.1:6379> get key1
"hello world"
127.0.0.1:6379> setrange key1 1 aaa
(integer)11
127.0.0.1:6379> get key1
"haaao world"127.0.0.1:6379> setrange key1 3 aaaaaaaaaaaaaaa
(integer)18
127.0.0.1:6379> get key1
"haaaaaaaaaaaaaaaaa"127.0.0.1:6379> get key3
(nil)
127.0.0.1:6379> setrange key3 1 aaa
(integer) 4
127.0.0.1:6379> get key3
"\x00aaa"
PS:當 key 不存在時,效果相當于 set,如果此時偏移量不為0,則前面用 0x00
填充
應用場景
1. 緩存
Redis 的一大功能就是作為緩沖層,MySQL 作為存儲層
先嘗試從 Redis 中獲取數據,數據不存在時,再去 MySQL 中獲取數據,返回時緩存在 Redis 中,因為局部性原則,該數據一段時間內還可能會被再次訪問,可視為熱點數據
Redis 沒有表、字段這種命名空間,也沒有對鍵名有強制要求,但設計合理的鍵名,有利于防止鍵沖突和項目的可維護性
比較推薦的方式是使用業務名:對象名:唯一標識:屬性
作為鍵名,例如 MySQL 的數據庫叫 csdn,用戶表名為 user_info,那么對應的鍵可以為csdn:user_info:1234
、csdn:user_info:1234:name
PS:因為 Redis 是客戶端服務器架構,使用網絡通信,所以當鍵名過長時,會增大網絡開銷,可以使用團隊內部都認同的縮寫減小帶寬,例如user:1234:friends:message:6666
替換為u:1234:fr:m:6666
2. 計數
許多應用都會使用 Redis 作為計數的基礎工具,因為其自身就支持快速計數的功能,同時查詢緩存速度快,還可以異步處理或者將數據落地到其他數據倉庫(通常用于數據分析)
例如,視頻網站的視頻播放次數,點贊數
3. 手機驗證碼
平時在用手機號登錄賬號的時候,都會通過驗證碼的形式。
此處有兩種需求:
- 驗證碼的有效時間
- 一分鐘內不能多次獲取驗證碼
Redis 都可以很簡單的滿足上述需求,通過 過期時間
實現驗證碼的有效時間;通過 incr
和 ex
實現不允許多次獲取驗證碼
以下是 一分鐘不能超過5次獲取驗證碼的偽代碼
std::string 發送驗證碼(phoneNumber) {key = "shortMsg:limit:" + phoneNumber;// 設置過期時間為 1 分鐘(60 秒)// 使? NX,只在不存在 key 時才能設置成功bool r = Redis 執?命令:set key 1 ex 60 nxif (r == false) {// 說明之前設置過該?機的驗證碼了long c = Redis 執?命令:incr keyif (c > 5) {// 說明超過了?分鐘 5 次的限制了// 限制發送return null;}}// 說明要么之前沒有設置過?機的驗證碼;要么次數沒有超過 5 次std::string validationCode = ?成隨機的 6 位數的驗證碼();validationKey = "validation:" + phoneNumber;// 驗證碼 5 分鐘(300 秒)內有效Redis 執?命令:set validationKey validationCode ex 300;// 返回驗證碼,隨后通過?機短信發送給??return validationCode ;
}
// 驗證??輸?的驗證碼是否正確
bool 驗證驗證碼(phoneNumber, validationCode) {validationKey = "validation:" + phoneNumber;std::string value = Redis 執?命令:get validationKey;if (value == null) {// 說明沒有這個?機的驗證碼記錄,驗證失敗return false;}if (value == validationCode) {return true;} else {return false;}
}
以上就是本篇博客的所有內容,感謝你的閱讀
如果覺得本篇文章對你有所幫助的話,不妨點個贊支持一下博主,拜托啦,這對我真的很重要。