# 常見Redis數據結構詳解
## 一、Redis數據結構概述
Redis(Remote Dictionary Server)是一個開源的、基于內存的鍵值存儲系統,它支持多種數據結構,這使得Redis不僅僅是一個簡單的鍵值存儲,而是一個功能豐富的數據結構服務器。Redis的數據結構設計是其核心優勢之一,每種數據結構都針對特定場景進行了優化,提供了高效的操作性能。
### 1.1 Redis數據結構的重要性
Redis之所以在眾多NoSQL數據庫中脫穎而出,很大程度上得益于其豐富的數據結構支持:
- **性能卓越**:內存存儲+高效數據結構實現,使Redis能達到極高的吞吐量
- **操作原子性**:所有單個命令都是原子操作,無需擔心并發問題
- **多功能性**:不同數據結構支持不同業務場景,從緩存到消息隊列都能勝任
- **擴展性**:通過組合基本數據結構,可以構建更復雜的數據模型
### 1.2 Redis數據模型特點
Redis的數據模型具有以下顯著特點:
1. **鍵值存儲**:所有數據都通過唯一的key訪問
2. **類型豐富**:value支持多種數據結構類型
3. **單線程模型**:命令順序執行,避免鎖競爭
4. **持久化支持**:可將內存數據保存到磁盤
5. **過期機制**:支持設置鍵的生存時間
## 二、String(字符串)
### 2.1 基本概念
String是Redis最基本的數據類型,可以存儲任何形式的數據,包括文本、序列化的對象或二進制數據。一個String類型的值最大能存儲512MB的內容。
**主要特性**:
- 二進制安全,可以包含任何數據
- 支持豐富的操作命令
- 常用于緩存、計數器等場景
### 2.2 常用命令
```redis
SET key value [EX seconds] [PX milliseconds] [NX|XX]
GET key
INCR key
DECR key
APPEND key value
STRLEN key
GETRANGE key start end
SETRANGE key offset value
MSET key1 value1 [key2 value2 ...]
MGET key1 [key2 ...]
緩存系統:存儲熱點數據
SET user:1001 "{name:'John', age:25}"
GET user:1001
計數器:實現原子遞增/遞減
INCR article:1001:views
DECR inventory:product1001
分布式鎖:利用SETNX實現
SETNX lock:order123 true
EXPIRE lock:order123 30
位操作:實現位圖功能
SETBIT user:1001:login 5 1
GETBIT user:1001:login 5
Redis的String類型在底層通過簡單動態字符串(SDS, Simple Dynamic String)實現,相比C字符串有以下優勢:
Redis的List是一個雙向鏈表結構,可以高效地在兩端進行插入和刪除操作,最大長度為2^32-1個元素。
主要特性: - 插入和刪除操作高效 - 支持范圍查詢 - 可用于實現多種數據結構
LPUSH key value1 [value2 ...]
RPUSH key value1 [value2 ...]
LPOP key
RPOP key
LRANGE key start stop
LLEN key
LINDEX key index
LINSERT key BEFORE|AFTER pivot value
LREM key count value
LTRIM key start stop
消息隊列:實現簡單的生產者消費者模型
# 生產者
LPUSH queue task1
# 消費者
RPOP queue
最新消息排行:如朋友圈時間線
LPUSH user:1001:timeline "New post"
LRANGE user:1001:timeline 0 9
歷史記錄:存儲用戶最近瀏覽
LPUSH history:user1001 item123
LTRIM history:user1001 0 49
棧/隊列:通過不同命令組合實現
# 棧 (LPUSH+LPOP)
# 隊列 (LPUSH+RPOP)
Redis的List在底層有兩種實現方式:
壓縮列表(ziplist):當元素數量較少且元素較小時使用,是一塊連續的內存空間
雙向鏈表(linkedlist):元素較多時使用
Redis 3.2后引入quicklist,結合了ziplist和linkedlist的優點,是默認實現。
Redis的Hash是一個string類型的field和value的映射表,特別適合存儲對象。
主要特性: - 適合存儲對象 - 可以單獨操作字段 - 高效存儲和訪問
HSET key field value
HGET key field
HDEL key field1 [field2 ...]
HEXISTS key field
HGETALL key
HKEYS key
HVALS key
HINCRBY key field increment
HLEN key
HMSET key field1 value1 [field2 value2 ...]
HMGET key field1 [field2 ...]
對象存儲:存儲用戶信息等結構化數據
HSET user:1001 name "John" age 25 email "john@example.com"
HGET user:1001 name
商品屬性:存儲商品的不同屬性
HMSET product:1001 name "Phone" price 599 stock 100
HINCRBY product:1001 stock -1
配置管理:存儲系統配置項
HSET config:system timeout 30 max_connections 1000
HGETALL config:system
計數器組合:多個相關計數器
HINCRBY article:1001 stats views 1
HINCRBY article:1001 stats likes 1
Redis的Hash類型有兩種底層實現:
ziplist:當哈希元素較少且元素較小時使用
hashtable:元素較多時使用
Redis會根據以下配置自動切換實現: - hash-max-ziplist-entries (默認512) - hash-max-ziplist-value (默認64字節)
Redis的Set是string類型的無序集合,通過哈希表實現,不允許重復元素。
主要特性: - 元素唯一性 - 支持集合運算 - 高效的成員檢查 - 無序存儲
SADD key member1 [member2 ...]
SREM key member1 [member2 ...]
SMEMBERS key
SCARD key
SISMEMBER key member
SRANDMEMBER key [count]
SPOP key [count]
SINTER key1 [key2 ...]
SUNION key1 [key2 ...]
SDIFF key1 [key2 ...]
標簽系統:給對象打標簽
SADD article:1001:tags tech redis database
SADD tag:redis:articles 1001
好友關系:存儲共同好友
SADD user:1001:friends 1002 1003
SADD user:1002:friends 1001 1003
SINTER user:1001:friends user:1002:friends
唯一計數器:統計獨立IP
SADD website:visitors 192.168.1.1
SCARD website:visitors
隨機元素:抽獎系統
SADD lottery:users user1 user2 user3
SRANDMEMBER lottery:users 1
Redis的Set底層有兩種實現:
intset:當集合中所有元素都是整數且元素數量較少時使用
hashtable:默認實現
轉換條件由以下配置控制: - set-max-intset-entries (默認512)
Sorted Set是Redis中最復雜也最強大的數據結構之一,它在Set的基礎上為每個元素關聯了一個分數(score),使得元素可以按分數排序。
主要特性: - 元素唯一 - 按分數排序 - 支持范圍查詢 - 高效的元素排名查詢
ZADD key [NX|XX] [CH] [INCR] score1 member1 [score2 member2 ...]
ZREM key member [member ...]
ZRANGE key start stop [WITHSCORES]
ZREVRANGE key start stop [WITHSCORES]
ZRANK key member
ZREVRANK key member
ZSCORE key member
ZCOUNT key min max
ZCARD key
ZINCRBY key increment member
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
排行榜系統:游戲積分排行
ZADD leaderboard 1000 player1 2000 player2
ZREVRANGE leaderboard 0 9 WITHSCORES
帶權重的隊列:優先級任務隊列
ZADD tasks 1 "task1" 3 "urgent_task" 2 "task2"
ZRANGE tasks 0 0 WITHSCORES
范圍查詢:時間線數據
ZADD user:1001:posts 1625097600 "post1" 1625184000 "post2"
ZRANGEBYSCORE user:1001:posts 1625097600 1625184000
延遲隊列:使用時間戳作為score
ZADD delay_queue <future_timestamp> "task_data"
# 定期查詢到期任務
ZRANGEBYSCORE delay_queue 0 <current_timestamp>
Sorted Set底層使用兩種數據結構組合實現:
跳躍表(skiplist):
字典(hashtable):
同時,當元素較少時,Redis會使用ziplist來節省內存,由以下配置控制: - zset-max-ziplist-entries (默認128) - zset-max-ziplist-value (默認64字節)
除了五種基本數據結構外,Redis還支持一些特殊的數據結構:
本質:實際上是String類型的擴展,提供位級別操作
常用命令:
SETBIT key offset value
GETBIT key offset
BITCOUNT key [start end]
BITOP operation destkey key [key ...]
BITPOS key bit [start] [end]
應用場景: - 用戶簽到記錄 - 活躍用戶統計 - 布隆過濾器實現
示例:
# 記錄用戶1001第5天簽到
SETBIT user:1001:sign 5 1
# 統計本月簽到次數
BITCOUNT user:1001:sign 0 30
本質:用于基數統計的概率算法
常用命令:
PFADD key element [element ...]
PFCOUNT key [key ...]
PFMERGE destkey sourcekey [sourcekey ...]
特點: - 極小的空間計算極大基數 - 標準誤差0.81% - 不存儲實際元素
應用場景: - 網站UV統計 - 大規模去重計數
示例:
PFADD visitors 192.168.1.1 192.168.1.2
PFCOUNT visitors
本質:基于Sorted Set實現的地理位置功能
常用命令:
GEOADD key longitude latitude member [longitude latitude member ...]
GEODIST key member1 member2 [unit]
GEOPOS key member [member ...]
GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC]
GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC]
應用場景: - 附近的人 - 地理位置查詢 - 距離計算
示例:
GEOADD cities 116.405285 39.904989 "Beijing"
GEOADD cities 121.474490 31.230416 "Shanghai"
GEODIST cities Beijing Shanghai km
引入版本:Redis 5.0
本質:類似日志的數據結構,用于實現消息隊列
常用命令:
XADD key [NOMKSTREAM] [MAXLEN|MINID [=|~] threshold [LIMIT count]] *|ID field value [field value ...]
XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...]
XRANGE key start end [COUNT count]
XREVRANGE key end start [COUNT count]
XGROUP CREATE key groupname ID|$ [MKSTREAM]
XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key ...] ID [ID ...]
特點: - 消息持久化 - 消費者組支持 - 消息回溯 - 阻塞讀取
應用場景: - 消息隊列 - 事件溯源 - 日志收集
示例:
# 生產者
XADD mystream * sensor-id 1234 temperature 19.8
# 消費者
XREAD BLOCK 0 STREAMS mystream $
數據特征:
操作模式:
性能需求:
內存效率:
| 數據結構 | 時間復雜度 | 主要優勢 | 典型應用場景 |
|---|---|---|---|
| String | O(1) | 簡單鍵值、位操作 | 緩存、計數器 |
| List | 頭尾操作O(1) | 順序性、雙端操作 | 隊列、時間線 |
| Hash | O(1) | 結構化數據存儲 | 對象存儲、配置 |
| Set | O(1) | 唯一性、集合運算 | 標簽、好友關系 |
| Sorted Set | O(logN) | 排序、范圍查詢 | 排行榜、優先級隊列 |
| Bitmap | O(1) | 位操作、節省空間 | 簽到、特征標記 |
| HyperLogLog | O(1) | 基數統計、極小空間 | UV統計 |
| Geo | O(logN) | 地理位置查詢 | 附近的人 |
| Stream | O(1)添加 O(N)讀取 | 消息持久化、消費者組 | 消息隊列 |
String:
List:
Hash:
Set:
Sorted Set:
Bitmap:
HyperLogLog:
Geo:
Stream:
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。