溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

常見Redis數據結構有哪些

發布時間:2021-12-06 10:06:30 來源:億速云 閱讀:248 作者:iii 欄目:關系型數據庫
# 常見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 ...]

2.3 應用場景

  1. 緩存系統:存儲熱點數據

    SET user:1001 "{name:'John', age:25}"
    GET user:1001
    
  2. 計數器:實現原子遞增/遞減

    INCR article:1001:views
    DECR inventory:product1001
    
  3. 分布式鎖:利用SETNX實現

    SETNX lock:order123 true
    EXPIRE lock:order123 30
    
  4. 位操作:實現位圖功能

    SETBIT user:1001:login 5 1
    GETBIT user:1001:login 5
    

2.4 內部實現

Redis的String類型在底層通過簡單動態字符串(SDS, Simple Dynamic String)實現,相比C字符串有以下優勢:

  1. O(1)時間復雜度獲取字符串長度
  2. 杜絕緩沖區溢出
  3. 減少修改字符串時帶來的內存重分配次數
  4. 二進制安全
  5. 兼容部分C字符串函數

三、List(列表)

3.1 基本概念

Redis的List是一個雙向鏈表結構,可以高效地在兩端進行插入和刪除操作,最大長度為2^32-1個元素。

主要特性: - 插入和刪除操作高效 - 支持范圍查詢 - 可用于實現多種數據結構

3.2 常用命令

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

3.3 應用場景

  1. 消息隊列:實現簡單的生產者消費者模型

    # 生產者
    LPUSH queue task1
    # 消費者
    RPOP queue
    
  2. 最新消息排行:如朋友圈時間線

    LPUSH user:1001:timeline "New post"
    LRANGE user:1001:timeline 0 9
    
  3. 歷史記錄:存儲用戶最近瀏覽

    LPUSH history:user1001 item123
    LTRIM history:user1001 0 49
    
  4. 棧/隊列:通過不同命令組合實現

    # 棧 (LPUSH+LPOP)
    # 隊列 (LPUSH+RPOP)
    

3.4 內部實現

Redis的List在底層有兩種實現方式:

  1. 壓縮列表(ziplist):當元素數量較少且元素較小時使用,是一塊連續的內存空間

    • 節省內存
    • 適合小列表
    • 插入刪除需要重新分配內存
  2. 雙向鏈表(linkedlist):元素較多時使用

    • 內存不連續
    • 插入刪除效率高
    • 需要額外存儲前后指針

Redis 3.2后引入quicklist,結合了ziplist和linkedlist的優點,是默認實現。

四、Hash(哈希表)

4.1 基本概念

Redis的Hash是一個string類型的field和value的映射表,特別適合存儲對象。

主要特性: - 適合存儲對象 - 可以單獨操作字段 - 高效存儲和訪問

4.2 常用命令

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 ...]

4.3 應用場景

  1. 對象存儲:存儲用戶信息等結構化數據

    HSET user:1001 name "John" age 25 email "john@example.com"
    HGET user:1001 name
    
  2. 商品屬性:存儲商品的不同屬性

    HMSET product:1001 name "Phone" price 599 stock 100
    HINCRBY product:1001 stock -1
    
  3. 配置管理:存儲系統配置項

    HSET config:system timeout 30 max_connections 1000
    HGETALL config:system
    
  4. 計數器組合:多個相關計數器

    HINCRBY article:1001 stats views 1
    HINCRBY article:1001 stats likes 1
    

4.4 內部實現

Redis的Hash類型有兩種底層實現:

  1. ziplist:當哈希元素較少且元素較小時使用

    • 所有鍵值對連續存儲
    • 節省內存
    • 查詢效率相對較低
  2. hashtable:元素較多時使用

    • 使用字典實現
    • 查詢效率高
    • 需要額外內存存儲指針

Redis會根據以下配置自動切換實現: - hash-max-ziplist-entries (默認512) - hash-max-ziplist-value (默認64字節)

五、Set(集合)

5.1 基本概念

Redis的Set是string類型的無序集合,通過哈希表實現,不允許重復元素。

主要特性: - 元素唯一性 - 支持集合運算 - 高效的成員檢查 - 無序存儲

5.2 常用命令

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 ...]

5.3 應用場景

  1. 標簽系統:給對象打標簽

    SADD article:1001:tags tech redis database
    SADD tag:redis:articles 1001
    
  2. 好友關系:存儲共同好友

    SADD user:1001:friends 1002 1003
    SADD user:1002:friends 1001 1003
    SINTER user:1001:friends user:1002:friends
    
  3. 唯一計數器:統計獨立IP

    SADD website:visitors 192.168.1.1
    SCARD website:visitors
    
  4. 隨機元素:抽獎系統

    SADD lottery:users user1 user2 user3
    SRANDMEMBER lottery:users 1
    

5.4 內部實現

Redis的Set底層有兩種實現:

  1. intset:當集合中所有元素都是整數且元素數量較少時使用

    • 有序數組存儲
    • 二分查找
    • 節省內存
  2. hashtable:默認實現

    • 字典實現,value為NULL
    • O(1)時間復雜度操作
    • 需要更多內存

轉換條件由以下配置控制: - set-max-intset-entries (默認512)

六、Sorted Set(有序集合)

6.1 基本概念

Sorted Set是Redis中最復雜也最強大的數據結構之一,它在Set的基礎上為每個元素關聯了一個分數(score),使得元素可以按分數排序。

主要特性: - 元素唯一 - 按分數排序 - 支持范圍查詢 - 高效的元素排名查詢

6.2 常用命令

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]

6.3 應用場景

  1. 排行榜系統:游戲積分排行

    ZADD leaderboard 1000 player1 2000 player2
    ZREVRANGE leaderboard 0 9 WITHSCORES
    
  2. 帶權重的隊列:優先級任務隊列

    ZADD tasks 1 "task1" 3 "urgent_task" 2 "task2"
    ZRANGE tasks 0 0 WITHSCORES
    
  3. 范圍查詢:時間線數據

    ZADD user:1001:posts 1625097600 "post1" 1625184000 "post2"
    ZRANGEBYSCORE user:1001:posts 1625097600 1625184000
    
  4. 延遲隊列:使用時間戳作為score

    ZADD delay_queue <future_timestamp> "task_data"
    # 定期查詢到期任務
    ZRANGEBYSCORE delay_queue 0 <current_timestamp>
    

6.4 內部實現

Sorted Set底層使用兩種數據結構組合實現:

  1. 跳躍表(skiplist)

    • 支持平均O(logN)復雜度的插入、刪除和查找
    • 支持范圍操作
    • 存儲元素和score的映射關系
  2. 字典(hashtable)

    • 存儲member到score的映射
    • 保證O(1)復雜度的member查詢

同時,當元素較少時,Redis會使用ziplist來節省內存,由以下配置控制: - zset-max-ziplist-entries (默認128) - zset-max-ziplist-value (默認64字節)

七、其他數據結構

除了五種基本數據結構外,Redis還支持一些特殊的數據結構:

7.1 Bitmaps(位圖)

本質:實際上是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

7.2 HyperLogLog

本質:用于基數統計的概率算法

常用命令

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

7.3 Geospatial(地理空間)

本質:基于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

7.4 Streams(流)

引入版本: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 $

八、數據結構選擇指南

8.1 選擇數據結構的考慮因素

  1. 數據特征

    • 是否需要唯一性
    • 是否需要排序
    • 是否需要范圍查詢
  2. 操作模式

    • 主要操作類型(讀/寫/更新)
    • 是否需要原子操作
    • 是否頻繁修改
  3. 性能需求

    • 預期QPS
    • 響應時間要求
    • 并發訪問量
  4. 內存效率

    • 數據量大小
    • 是否需要壓縮存儲
    • 內存優化需求

8.2 數據結構對比表

數據結構 時間復雜度 主要優勢 典型應用場景
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)讀取 消息持久化、消費者組 消息隊列

8.3 最佳實踐建議

  1. String

    • 存儲簡單鍵值對
    • 需要原子遞增時
    • 二進制數據存儲
  2. List

    • 需要保持插入順序時
    • 實現簡單隊列或棧
    • 固定長度的歷史記錄
  3. Hash

    • 存儲對象屬性
    • 需要單獨訪問字段時
    • 減少鍵數量節省內存
  4. Set

    • 需要保證元素唯一性
    • 需要集合運算時
    • 隨機獲取元素
  5. Sorted Set

    • 需要按分數排序時
    • 需要范圍查詢
    • 優先級隊列實現
  6. Bitmap

    • 布爾型大數據量標記
    • 節省空間的二進制標記
    • 位運算場景
  7. HyperLogLog

    • 大數據量去重計數
    • 允許一定誤差的統計場景
  8. Geo

    • 地理位置相關應用
    • 距離計算和范圍查詢
  9. Stream

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女