轉載請註明出處: 目錄 Redis 的五種數據結構 Redis 數據結構的內部編碼 1.String 1.1 常用命令 1.2 內部編碼 1.3 典型使用場景 2. Hash 2.1 常用命令及時間複雜度 2.2 內部編碼 3.列表 3.1 常用命令及時間複雜度 3.2 內部編碼 3.3 使用場景 ...
轉載請註明出處:
目錄 Redis 的五種數據結構 Redis 數據結構的內部編碼 1.String 1.1 常用命令 1.2 內部編碼 1.3 典型使用場景 2. Hash 2.1 常用命令及時間複雜度 2.2 內部編碼 3.列表 3.1 常用命令及時間複雜度 3.2 內部編碼 3.3 使用場景 4.集合 4.1 常用命令及時間複雜度 4.2 內部編碼 5.有序集合 5.1 常用命令 5.2 內部編碼 5.3 使用場景
Redis 的五種數據結構
Redis 數據結構的內部編碼
Redis這樣設計有兩個好處:
第一,可以改進內部編碼,而對外的數據結構和命令沒有影響,這樣一旦開發出更優秀的內部編碼,無需改動外部數據結構和命令。
第二,多種內部編碼實現可以在不同場景下發揮各自的優勢,例如ziplist比較節省記憶體,但是在列表元素比較多的情況下,性能會有所下降,這時候Redis會根據配置選項將列表類型的內部實現轉換為linkedlist。
1.String
1.1 常用命令
(1)設置值
set key value [ex seconds] [px milliseconds] [nx|xx]
set命令有幾個選項:
-
ex seconds:為鍵設置秒級過期時間。
-
px milliseconds:為鍵設置毫秒級過期時間。
-
nx:鍵必須不存在,才可以設置成功,用於添加。
-
xx:與nx相反,鍵必須存在,才可以設置成功,用於更新。
除了set選項,Redis還提供了setex和setnx兩個命令
(2)獲取值
get key
(3)批量設置值
mset key value [key value ...]
(4)批量獲取值
mget key [key ...]
(5)計數
incr key
incr命令用於對值做自增操作,返回結果分為三種情況:
-
值不是整數,返回錯誤。
-
值是整數,返回自增後的結果。
-
鍵不存在,按照值為0自增,返回結果為1。
除了incr命令,Redis提供了decr(自減)、incrby(自增指定數字)、decrby(自減指定數字)、incrbyfloat(自增浮點數);
(6)字元串長度
strlen key
1.2 內部編碼
字元串類型的內部編碼有3種:
-
int:8個位元組的長整型。
-
embstr:小於等於39個位元組的字元串。
-
raw:大於39個位元組的字元串。
Redis會根據當前值的類型和長度決定使用哪種內部編碼實現。
# 小於等於39個位元組的字元串:embstr
127.0.0.1:6379> set key "hello,world"
OK
127.0.0.1:6379> object encoding key
"embstr"
1.3 典型使用場景
1.緩存功能
Redis作為緩存層,MySQL作為存儲層,絕大部分請求的數據都是從Redis中獲取。由於Redis具有支撐高併發的特性,所以緩存通常能起到加速讀寫和降低後端壓力的作用
2.計數
3.共用Session
用Redis將用戶的Session進行集中管理,只要保證Redis是高可用和擴展性的,每次用戶更新或者查詢登錄信息都直接從Redis中集中獲取。
4.限速
限制介面不被頻繁訪問
2. Hash
2.1 常用命令及時間複雜度
2.2 內部編碼
哈希類型的內部編碼有兩種:
-
ziplist(壓縮列表)
-
hashtable(哈希表):當哈希類型無法滿足ziplist的條件時,Redis會使用hashtable作為哈希的內部實現,因為此時ziplist的讀寫效率會下降,而hashtable的讀寫時間複雜度為O(1)。
127.0.0.1:6379> hmset hashkey f1 v1 f2 v2
OK
127.0.0.1:6379> object encoding hashkey
"ziplist"
3.列表
3.1 常用命令及時間複雜度
3.2 內部編碼
列表類型的內部編碼有兩種。
-
ziplist(壓縮列表)
-
linkedlist(鏈表):當列表類型無法滿足ziplist的條件時,Redis會使用linkedlist作為列表的內部實現。
127.0.0.1:6379> rpush listkey e1 e2 e3 (integer) 3 127.0.0.1:6379> object encoding listkey "ziplist"
3.3 使用場景
1.消息隊列
Redis的lpush+brpop命令組合即可實現阻塞隊列,生產者客戶端使用lrpush從列表左側插入元素,多個消費者客戶端使用brpop命令阻塞式的“搶”列表尾部的元素,多個客戶端保證了消費的負載均衡和高可用性。
2.文章列表
每個用戶有屬於自己的文章列表,現需要分頁展示文章列表。此時可以考慮使用列表,因為列表不但是有序的,同時支持按照索引範圍獲取元素。
4.集合
4.1 常用命令及時間複雜度
集合(set)類型也是用來保存多個的字元串元素,但和列表類型不一樣的是,集合中不允許有重覆元素,並且集合中的元素是無序的,不能通過索引下標獲取元素。
Redis除了支持集合內的增刪改查,同時還支持多個集合取交集、並集、差集,合理地使用好集合類型,能在實際開發中解決很多實際問題。
SADD key member [member ...] //往集合key中存入元素,元素存在則忽略,若key不存在則新建
SREM key member [member ...] //從集合key中刪除元素
SMEMBERS key //獲取集合key中所有元素
SCARD key //獲取集合key的元素個數,scard的時間複雜度為O(1),它不會遍歷集合所有元素,而是直接用Redis內部的變數
SISMEMBER key member //判斷member元素是否存在於集合key中
SRANDMEMBER key [count] //從集合key中選出count個元素,元素不從key中刪除
SPOP key [count] //從集合key中選出count個元素,元素從key中刪除
Set 運算命令
SINTER key [key ...] //交集運算
SINTERSTORE destination key [key ..] //將交集結果存入新集合destination中
SUNION key [key ..] //並集運算
SUNIONSTORE destination key [key ...] //將並集結果存入新集合destination中
SDIFF key [key ...] //差集運算
SDIFFSTORE destination key [key ...] //將差集結果存入新集合destination中
4.2 內部編碼
集合類型的內部編碼有兩種:
-
hashtable(哈希表):當集合類型無法滿足intset的條件時,Redis會使用hashtable作為集合的內部實現。
127.0.0.1:6379> sadd setkey 1 2 3 4
(integer) 4
127.0.0.1:6379> object encoding setkey
"intset"
1. 微博點贊,收藏,標簽(給用戶添加標簽,給標簽添加用戶),計算用戶共同感興趣的標簽
2. 微博或微信中可能認識的人,共同好友,共同關註的話題等。
5.有序集合
5.1 常用命令
它保留了集合不能有重覆成員的特性,但不同的是,有序集合中的元素可以排序。但是它和列表使用索引下標作為 排序依據不同的是,它給每個元素設置一個分數(score)作為排序的依據。有序集合中的元素不能重覆,但是score可以重覆;有序集合提供了獲取指定分數和元素範圍查詢、計算成員排名等功能
ZADD key score member [[score member]…] //往有序集合key中加入帶分值元素
ZREM key member [member …] //從有序集合key中刪除元素
ZSCORE key member //返回有序集合key中元素member的分值
ZINCRBY key increment member //為有序集合key中元素member的分值加上increment
ZCARD key //返回有序集合key中元素個數
ZRANGE key start stop [WITHSCORES] //正序獲取有序集合key從start下標到stop下標的元素
ZREVRANGE key start stop [WITHSCORES] //倒序獲取有序集合key從start下標到stop下標的元素
ZUNIONSTORE destkey numkeys key [key ...] //並集計算
ZINTERSTORE destkey numkeys key [key …] //交集計算
5.2 內部編碼
有序集合類型的內部編碼有兩種:
-
ziplist(壓縮列表):當有序集合的元素個數小於zset-max-ziplist-entries配置(預設128個),同時每個元素的值都小於zset-max-ziplist-value配置(預設64位元組)時,Redis會用ziplist來作為有序集合的內部實現,ziplist 可以有效減少記憶體的使用。
-
skiplist(跳躍表):當ziplist條件不滿足時,有序集合會使用skiplist作為內部實現,因為此時ziplist的讀寫效率會下降。
127.0.0.1:6379> zadd zsetkey 50 e1 60 e2 30 e3
(integer) 3
127.0.0.1:6379> object encoding zsetkey
"ziplist"
5.3 使用場景
榜單排名,熱點排名