玩轉Redis-Redis基礎資料結構及核心命令
《玩轉Redis》系列文章主要講述Redis的基礎及中高階應用,文章基於Redis5.0.4+。本文主要講述Redis的資料結構String,《玩轉Redis-Redis基礎資料結構及核心命令》相關操作命令為方便對比分析,使用腦圖展示(若手機端檢視圖片不方便,可搜尋zxiaofan前往PC網頁端<CSDN、 開源中國 等平臺>檢視)。
最新思維導圖原圖可聯絡公眾號【zxiaofan】後臺獲取。
本文更適合用於複習總結,閱讀》實戰》閱讀 更有效果喲,主要包含以下內容:
- String(字串);
- List(列表);
- Set(集合);
- Hash(雜湊);
後續會介紹其他高階資料結構:
- Sorted Set(有序集合);
- Bitmap(點陣圖);
- HyperLogLog;
- Streams(流);
文章思路:
- 資料結構應用場景及注意事項;
- 資料結構各命令對比分析;
異常統一說明:
error(out of range)導圖簡寫@EOOR;
負數偏移量表示倒數第幾,導圖簡寫@LBN(last but number);
1、String
1.1、String應用場景及注意事項
1.1.1、String應用場景
String可以說是Redis中最常見的資料結構,沒有之一。
String結構可儲存字串或者各種型別的二進位制資料。
- 分散式鎖;
- 計數器;
- 分散式全域性唯一ID;
1.1.2、String注意事項
String底層結構是動態字串,可修改指定位置資料,通過預分配冗餘空間減少記憶體的頻繁分配,實際分配的空間capacity一般要高於實際字串長度len。當字串長度小於1M時,擴容都是加倍現有的空間,如果超過1M,擴容時一次只會多擴1M的空間。字串最大長度為512M(51210241024個字元)。
數字及浮點數在Redis中以字串形式儲存。
// 如何證明 String最大長度是512M; // 512M=512*1024*1024; 127.0.0.1:6379> setrange ran 536870911 a (integer) 536870912 127.0.0.1:6379> strlen ran (integer) 536870912 127.0.0.1:6379> append ran a (error) ERR string exceeds maximum allowed size (512MB)
1.2、String各命令對比分析
String命令支援以下操作型別:單一操作、批量操作、字元操作、位操作、計數操作。
1.2.1、String單元素操作
【核心命令】:SET、SETNX、SETEX、PSETEX、GET、GETSET、APPEND、STRLEN;
注意:
- 【SET】:Redis2.6.12+版本支援設定value值時,同時設定過期時間,此操作為原子操作;
- 【PSETEX】:Redis2.6.0+版本支援,可將過期時間精確到毫秒;
【Redis-String單元素操作】命令簡述:
命令 | 功能 | 引數 |
---|---|---|
SET | 設定value值,支援選項 | key value [expiration EX seconds/PX milliseconds] [NX/XX] |
SETNX | key不存在才允許設定 | key value |
SETEX | 設定value及過期時間(秒) | key seconds value |
PSETEX | 設定value及過期時間(毫秒) | key milliseconds value |
GET | 查詢指定key | key |
GETSET | 查詢返回舊值設定新值 | key value |
APPEND | value追加字串 | key value |
STRLEN | 查詢value長度 | key |
【Redis-String單元素操作】命令詳細對比分析如下:
1.2.2、String批量操作
【核心命令】:MSET、MGET;
注意:
- MGET、MSET是Redis命令中的Boss,因為執行這兩個命令是絕不會失敗的。
- 【MSET】操作具有原子性,不存在部分key更新成功而部分key更新失敗的情況;
- 【MGET】如果value不是String型別,將返回nil;
【Redis-String批量操作】命令簡述:
命令 | 功能 | 引數 |
---|---|---|
MSET | 批量設定 | key value [key value ...] |
MGET | 批量查詢 | key [key ...] |
【Redis-String批量操作】命令詳細對比分析如下:
1.2.3、String指定範圍處理
【核心命令】:SETRANGE、GETRANGE;
注意:
- 【SETRANGE、GETRANGE】 在操作物件較小時,時間複雜度近似看成O(1);
- 【SETRANGE】在特定情況下會造成伺服器阻塞(value不存在或很小+偏移量offset很大),具體阻塞時長與伺服器有關;
【Redis-String指定範圍處理】命令簡述:
命令 | 功能 | 引數 |
---|---|---|
SETRANGE | 設定指定偏移量位置的字元 | key offset value |
GETRANGE | 查詢指定區間字串 | key start end【@LBN;offset大於len將自動以len為準】 |
【Redis-String指定範圍處理】命令詳細對比分析如下:
1.2.4、String遞增操作
【核心命令】:INCR/DECR、INCRBY/DECRBY、INCRBYFLOAT;
注意:
- String結構能儲存數字?因為數字在Redis中是以字串形式儲存的;
- 【INCR/DECR】 支援加減1;
- 【INCRBY/DECRBY】 支援 加減指定整數,引數支援負數;
- 【INCRBYFLOAT】 支援 加減指定浮點數,引數支援負數;
- 遞增命令時間負責度都是O(1);
【Redis-String遞增操作】命令簡述:
命令 | 功能 | 引數 |
---|---|---|
INCR/DECR | 遞增/1遞減1 | key |
INCRBY/DECRBY | 遞增n/遞減n | key increment(支援負數) |
INCRBYFLOAT | 遞增浮點值 | key increment(支援負數) |
【Redis-String遞增操作】命令詳細對比分析如下:
1.2.5、String位操作
【核心命令】:SETBIT、BITOP、GETBIT、BITCOUNT、BITFIELD、BITPOS;
注意:
- 【BITOP】支援邏輯操作,且AND、或OR、異或XOR、非NOT;
- 由於按位儲存非常節省空間,位操作特別適合於對連續的海量資料做標記。比如貼吧簽到,標記每天是否簽到,1天1標識位,則10年=10*365bit=456byte。
【Redis-String位操作】命令簡述:
命令 | 功能 | 引數 |
---|---|---|
SETBIT | 指定偏移量bit位置設定值 | key offset value【0=< offset< 2^32】 |
BITOP | 對一個或多個key執行邏輯操作,並將結果儲存到destkey | operation destkey key [key ...]【AND, OR, XOR, NOT】 |
GETBIT | 查詢指定偏移位置的bit值 | key offset |
BITCOUNT | 統計指定區間bit為1的數量 | key [start end]【@LBN】 |
BITFIELD | 操作多位元組位域 | key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP/SAT/FAIL] |
BITPOS | 查詢指定區間第一個被設定成1的bit位的位置 | key bit [start] [end]【@LBN】 |
【Redis-String位操作】命令詳細對比分析如下:
2、List
2.1、List應用場景及注意事項
2.1.1、List應用場景
- List可用於構建佇列(右進左出/先進先出)、棧(右進右出/先進後出);
- 儲存相關資料,比如文章的相關文章ID,可用於文章推薦;
- 高階使用:quicklist快速連結串列;
2.1.2、List注意事項
- 元素是String,按插入順序排序;
- 插入、彈出快,O(1);
- 索引慢(查詢),O(n);
- List查詢操作類似Java連結串列的get(int index),需要對連結串列遍歷,效能隨index的增大而降低;
- lindex的index可為負數,-1表示倒數第一個元素,-2倒數第二個;
- List的index引數存在越界問題; -List的start、stop引數不存在越界問題;
- 列表彈出最後一個元素後,結構自動被刪除,記憶體被回收;
- List左頭右尾(記憶:我國自古就有左為尊的說法,左才是頭);
2.2、List各命令對比分析
概述:
- List命令支援以下操作型別:新增元素、彈出元素、處理指定位置元素。
- List主命令L開頭(左側處理)、右側處理目錄R開頭、阻塞命令B開頭;
- List的超時timeout為0表示無限阻塞;
2.2.1、List新增元素
【核心命令】:LPUSH、RPUSH、LPUSHX、RPUSHX、RPOPLPUSH、BRPOPLPUSH;
注意:
- 【LPUSH / RPUSH】 支援批量新增元素;
- 【RPOPLPUSH】 拆分成2個命令理解:RPOP(src)+ LPUSH(dest);
- 【RPOPLPUSH】可作為安全佇列:ListA取出訊息放入“處理中的ListB”,處理完畢移除ListB;外掛監控ListB的超時情況;
【Redis-List新增元素操作】命令簡述:
命令 | 功能 | 引數 |
---|---|---|
LPUSH / RPUSH | (批量)新增元素 | key value [value ...] |
LPUSHX / RPUSHX | 向已存在的list中新增單個元素 | key value |
RPOPLPUSH | 彈出source尾壓入dest頭部 | source destination |
BRPOPLPUSH | 阻塞式彈出source壓入dest | source destination timeout |
【Redis-List新增元素操作】命令詳細對比分析如下:
2.2.2、List彈出元素
【核心命令】:LPOP、RPOP、BLPOP、BRPOP;
注意:
- 【BLPOP】為LPOP的阻塞版本,0表示無限阻塞;
- 彈出元素操作時間複雜度都是O(1);
【Redis-List彈出元素操作】命令簡述:
命令 | 功能 | 引數 |
---|---|---|
LPOP / RPOP | 彈出元素 | key |
BLPOP / BRPOP | 阻塞式彈出元素 | key [key ...] timeout |
【Redis-List彈出元素操作】命令詳細對比分析如下:
2.2.3、List處理指定位置元素
【核心命令】:LSET、LINDEX、LRANGE、LTRIM、LREM;
注意:
- 【ltrim】支援保留區間內的值,可實現定長連結串列;
- 【LRANGE、LTRIM】不會越界;
- List處理指定位置相關命令時間複雜度可記為O(N);
【Redis-List處理指定位置元素】命令簡述:
命令 | 功能 | 引數 |
---|---|---|
LSET | 指定位置設定元素 | key index value |
LINDEX | 查詢指定位置元素 | key index |
LRANGE | 查詢指定區間元素 | key start stop |
LTRIM | 保留指定區間元素 | key start stop |
LREM | 移除前/後count次的value元素 | key count value |
【Redis-List處理指定位置元素】命令詳細對比分析如下:
3、Set
3.1、Set應用場景及注意事項
3.1.1、Set應用場景
- 類似Java的HashSet,鍵值無序唯一,可用於去重;
- Set支援交集運算,可用於查詢QQ共同好友;
3.1.2、Set注意事項
- Set支援集合運算(差集、交集、並集);
- Set底層實現相當於特殊字典,value都是NULL;
- 集合最後一個元素移除後,結構自動刪除,記憶體被回收;
3.2、Set各命令對比分析
概述:
- Set命令支援以下操作型別:集合運算、增刪移動及統計;
- Set命令都是S開頭;
3.2.1、Set增刪移動及統計
【核心命令】:SADD(增)、SCADD(數量統計)、SISMEMBER(存在)、SMEMBERS(所有元素)、SREM(移除)、SMOVE(移動);
注意:
- Redis2.4+,SADD、SREM支援批量新增元素;
- 【SMEMBERS】將返回Set中所有元素,慎用,請使用SSCAN代替;
- 【SRANDMEMBER】返回count個隨機元素,支援count為負;SPOP返回並移除count個隨機元素,不支援count為負(越界異常);
【Redis-Set增刪移動及統計】命令簡述:
命令 | 功能 | 引數 |
---|---|---|
SADD | (批量)新增元素到Set中 | key member [member ...] |
SCARD | 統計Set中元素數量 | key |
SISMEMBER | 判斷指定元素是否存在於Set中 | key member |
SMEMBERS | 返回Set中的所有元素 | key |
SMOVE | 移動Set的指定元素到另一個集合 | source destination member |
SRANDMEMBER | 返回Set中count個隨機元素 | key [count] |
SPOP | 移除並返回Set中count個隨機元素 | key [count] |
SREM | 移除Set中指定的元素 | key member [member ...] |
SSCAN | 迭代Set | key cursor [MATCH pattern] [COUNT count] |
【Redis-Set增刪移動及統計】命令詳細對比分析如下:
3.2.2、Set集合運算(差集、交集、並集)
【核心命令】:差集SDIFF/SDIFFSTORE、交集SINTER/SINTERSTORE、並集SUNION/SUNIONSTORE;
注意:
- 主命令加STORE表示將對應的結果存入指定目標Set中;
- 對於“STORE”命令,如果destkey已存在,destkey的值將會被覆蓋;
- 交集的時間複雜度是(N*M),差集/並集的時間複雜度是O(N);
【Redis-Set集合運算】命令簡述:
命令 | 功能 | 引數 |
---|---|---|
SDIFF | 【差集】返回在第一個set中但不在其他set中的元素集合 | key [key ...] |
SDIFFSTORE | 【差集】將SDIFF結果存入destination | destination key [key ...] |
SINTER | 【交集】返回(多個)set集合的交集 | key [key ...] |
SINTERSTORE | 【交集】將多個set集合的交集存入dest | destination key [key ...] |
SUNION | 【並集】返回多個set的並集 | key [key ...] |
SUNIONSTORE | 【並集】將多個set集合的並集存入dest | destination key [key ...] |
【Redis-Set集合運算】命令詳細對比分析如下:
4、Hash
4.1、Hash應用場景及注意事項
4.1.1、Hash應用場景
- 記錄一個物件的多個屬性,如員工的姓名/生日/職級,文章的點贊數/閱讀數/收藏數;
4.1.2、Hash注意事項
- 類似Java的HashMap,陣列+連結串列,結構是<rediskey , <hashkey1, hashvalue1>>;
- 字典key、value都只能是字串(數字在redis裡面是以 sds 字串形式存在);
- 使用漸進式rehash策略:高效能,不堵塞服務;而HashMap的rehash是一次性hash,很耗時;
- 【優點】支援按需存取指定欄位;
- 【缺點】hash結構儲存消耗高於單個字串;
4.2、Hash各命令對比分析
概述:
- Hash命令支援以下操作型別:新增、查詢、統計、修改、刪除(增刪改查及統計);
4.2.1、Hash新增、查詢元素
【核心命令】:HSET、HSETNX、HMSET;HGET、HMGET、HGETALL;
注意:
- 【HSET】field存在則覆蓋;HSETNX:field不存在才賦值;
- 【HMSET、HMGET】支援批量操作;
【Redis-Hash新增、查詢元素】命令簡述:
命令 | 功能 | 引數 |
---|---|---|
HSET | 設定hash中指定欄位的值 | key field value |
HSETNX | field不存在才設定hash中指定field的值 | key field value |
HMSET | 批量設定hash值 | key field value [field value ...] |
HGET | 查詢hash中指定欄位的值 | key field |
HMGET | 批量查詢指定field的value | key field [field ...] |
HGETALL | 查詢所有field-value列表 | key |
【Redis-Hash新增、查詢元素】命令詳細對比分析如下:
4.2.2、Hash統計、修改、刪除
【核心命令】:HKEYS、HVALS、HLEN;HDEL、HEXISTS、HSTRLEN;HINCRBY、HINCRBYFLOAT;HSCAN;
注意:
- 支援查詢Hash中所有field、所有value;
- 【HVALS】不是HVALUES;
- 【HINCRBY】支援增加Hash中指定field的值(點贊數/閱讀數/收藏數);
【Redis-Hash統計、修改、刪除】命令簡述:
命令 | 功能 | 引數 |
---|---|---|
HKEYS | 查詢所有field列表 | key |
HVALS | 查詢所有value列表 | key |
HLEN | 查詢hash的field數量 | key |
HDEL | 移除hash中指定field欄位 | key field [field ...] |
HEXISTS | 判斷hash中是否存在指定field | key field |
HSTRLEN | 查詢hash中filed關聯的value字串的長度 | key field |
HINCRBY | 增加hash中指定field的值 | key field increment |
HINCRBYFLOAT | 增加hash中指定field的值 | key field increment |
HSCAN | 基於遊標迭代hashes | key cursor [MATCH pattern] [COUNT count] |
【Redis-Hash統計、修改、刪除】命令詳細對比分析如下:
5、後記
《玩轉Redis-Redis基礎資料結構及核心命令》至此結束,後續將繼續分享Redis其他資料結構及核心命令。
祝君好運!
Life is all about choices!
將來的你一定會感激現在拼命的自己!
【CSDN】【GitHub】【OSCHINA】【掘金】【微信公眾號】