1.String字符串
字符串類型是Redis中最基礎的數據結構,關于數據結構與要特別注意的是:首先Redis中所有的鍵的類型都是字符串類型,而且其他集中數據結構也都是在字符串類似基礎上進行構建,例如列表和集合的元素類型是字符串類型,所有字符串類型能為其他4中數據結構的學習奠定基礎。其次字符串類型的值可以是字符串,包含一般格式的字符串和JSON,XML格式的字符串;數字,也可以是整數或者浮點數;甚至是二進制流數據,例如圖片,音頻,視頻等。不過一個字符串的最大值不能超過512MB
2.常見命令
2.1 SET
將String類型的value設置到key中。如果之前key存在,則覆蓋,無論原來的數據類型是什么。之前關于此key的TTL也會全部失效。
語法:SET key value [expiration EX seconds | PX milliseconds]? [NX |XX]
時間復雜度:O(1)
選項:
EX seconds ——使用秒作為單位設置key的過期時間
PX milliseconds——使用毫秒作為單位設置key的過期時間
NX——只要key不存在時才進行設置,即如果key之前已經存在,設置不執行
XX——只在key存在時才進行設置,即如果key之前已經存在,設置不執行
返回值:
如果設置成功,返回OK。
如果由于SET指定NX或者XX但條件不滿足,SET不會執行,并返回(nil)
示例:
?2.2 MGET
一次性獲取多個key的值。如果對應的key不存在或者對應的數據類型不是string,返回nil
語法:MGET key [key ...]
時間復雜度:O(1)(或O(N),N是key的數量)
返回值:對應value的列表
示例:
2.3 MSET
一次設置多個key的值
語法:MSET key value [key value...]
時間復雜度:O(1)(或O(N),N是key的數量)
返回值:永遠是OK
示例:
多次 get vs單次mget
Redis是一個客戶端-服務器結構的程序,客戶端和服務器之間通信是通過網絡實現的,多次get產生了多次請求,進行多次網絡通信。單次mget只進行一次網絡通信,mget減少了網絡事件,所以性能較高
2.4 SETNX
設置key-value但只允許在key之前不存在的情況下
語法:SETNX key value
時間復雜度:O(1)
返回值:1表示設置成功,0表示沒有設置成功
示例:
2.5 INCR
將key對應的value(String類型)表示的數字+1。如果key不存在,則視為key對應的value是0。如果key對應的string不是一個整數或者范圍超過了64位有符號整數,則報錯
語法:INCR key
時間復雜度:O(1)
返回值:integer類型的加完后的數值
示例:
2.6 INCRBY
將key對應的string表示的數字加上對應的值。如果key不存在,則視為key對應的value是0.如果key對應的string不是一個整數或者范圍超過了64位有符號整數,則報錯
語法:INCRBY key decrement
時間復雜度:O(1)
返回值:integer類型的加完后的數值
示例:
?2.7 DECR
將key對應的string表示的數字減一。如果key對應的value是0.如果key對應的string不是一個整數或者范圍超過了64位有符號整數,則報數
語法:DECR key
時間復雜度:O(1)
返回值:integer類型的減完后的數值
示例:
2.8 INCRBYFLOAT
將key對應的string表示的浮點數加上對應的值。如果對應的值是負數,則視為減去對應的值。如果key不存在,則視為key對應的value是0.如果key對應的不是string,或者不是一個浮點數,則報錯。允許采用科學計數法表示浮點數
語法:INCRBYFLOAT
時間復雜度:O(1)
返回值:加/減完后的數值
示例:
2.9 APPEND
如果key已經存在并且是一個string,命令會將value追加到原有的string的后面。如果key不存在,則效果等同于SET命令
語法:APPEND KEY VALUE
時間復雜度:O(1)
返回值:追加完成之后string的長度
示例:
2.10 GETRANGE
返回key對應的string的子串,有start和end確定(左閉右閉)。可以使用負數表示倒數。-1表示倒數第一個字符,其他的于此類似。超過范圍的偏移量會根據string的長度調整成正確的值
語法:GETRANGE key start end
時間復雜度:O(N),N為[start,end]區間的長度。由于string通常比較短,可以視為是O(1)
返回值:string類型的子串
示例:
2.11 SETRANGE
覆蓋字符串的一部分,從指定的偏移開始
語法:SETRANGE key offset value
時間復雜度:O(N),N為value的長度,由于一般的value比較短,通常視為O(1)
返回值:替換后的string
示例:
2.11 STRLEN
獲取key對應的string的長度。當key存放的類型不是string時,報錯
語法:STRLEN key?
時間復雜度:O(1)
返回值:string的長度,或者當key不存在時,返回0
示例:
3.String的內部編碼
字符串類型的內部編碼有3種:
int:8個字節的長整型
embstr:小于等于39個字節的字符串
raw:大于39個字節的字符串
Redis會根據當前值的類型和長度動態決定使用那種內部編碼實現
redis存儲小數,本質上還是當字符串來存儲的,這意味著每次進行算數運算時,都需要將字符串轉為小數,再將運算結果轉為字符串,計算過程中的轉換都是開銷
4.String的典型場景
4.1緩存功能
緩存功能是String比較典型的運用場景,其中Redis作為緩沖層,MySQL作為存儲層,絕大部分請求的數據都是從Redis中獲取。由于Redis具有支撐高并發的特性,所以緩存通常能起到加速讀寫和降低后端壓力的作用
MySQL+Redis組成的緩存存儲框架結構
業務層 也可以看做是應用服務器,緩存層是Redis服務器(用于存放熱點數據),存儲層是MySQL服務器
假設業務是根據用戶uid獲取用戶信息:
首先從Redis獲取用戶信息,如果沒有從Redis中得到用戶信息,及緩存miss,則進一步從MySQL中獲取對應的信息,隨后寫入緩存并返回。如果從Redis中獲取到用戶的信息,則直接返回。通過增加緩存的功能,可以極大地提高查詢的效率,也降低了對MySQL的訪問次數
4.2計數功能
許多應用都會使用Redis作為技術的基礎工具,他可以實現快速的技術,查詢緩存的功能,同時數據可以一步處理或者落地到其他的數據源
?實際的開發一個成熟,穩定的真實技術系統,要面臨的挑戰遠不止如此簡單:防作弊,按照不同的維度技術,避免單點問題(單個redis掛了,數據丟失),數據持久化到底層數據源等
4.3共享會話
一個分布式Web服務將用戶的Session信息保存在各自的服務器中,但這樣會造成一個問題:處于負載均衡的考慮,分布式服務會將用戶的訪問請求均衡到不同的服務器上,并且通常無法保證用戶每次請求都會被均衡到同一臺服務器上,這樣當用戶刷新一次訪問是可能會發現需要重新登陸的,這個問題對于用戶來說是非常不適的
Session分散存儲
為了解決這個問題,可以使用Redis將用戶的Session信息進行集中管理。
Redis集中管理Session
?這種模式下,無論用戶被均衡到哪臺服務器上,都會集中從Redis中查詢,更新Session信息
4.4短信驗證碼?
很多應用處于安全考慮,會在每次登陸時,讓用戶輸入手機號并且配合給手機發送驗證碼,然后讓用戶輸入收到的驗證碼進行驗證,從而確定是否是用戶本人。為了短信接口不會頻繁訪問,會限制用戶每分鐘獲取驗證碼的頻率,例如一分鐘不能超過五次等
解決思路:
通過Redis命令對制定的key設置有效時間,在有效時間內訪問Redis即可成功,如果超出有效時間就登錄失敗
當然實際中并不會像我描述的這么簡單,還需要根據業務的場景進行具體的編寫