Redis 提供了豐富的資料型別,每種資料型別都有其獨特的儲存結構和操作方法,可以滿足不同的業務場景需求。下面詳細介紹 Redis 支援的主要資料型別及其底層實現,並結合具體的應用場景說明其使用。
1. 字串(String)
介紹:
- Redis 中最基本的鍵值對型別,鍵和值都可以是字串,值的最大限制為 512MB。
String
型別是 Redis 最常用的資料型別,它支援簡單的GET
、SET
操作,以及自增、自減、字串拼接等操作。
典型應用場景:
- 快取資料:儲存使用者登入狀態、Token、配置資訊等。
- 計數器:透過
INCR
、DECR
實現簡單的計數器,比如網站訪問量、點贊數等。 - 分散式鎖:結合
SETNX
命令,可以用字串來實現簡單的分散式鎖。
底層原理:
- Redis 底層對字串使用的是簡單動態字串(SDS),它不僅是 C 字串的封裝,還加入了長度屬性和空間預留等最佳化策略。SDS 支援二進位制安全,可以儲存文字和二進位制資料。
2. 雜湊(Hash)
介紹:
- 雜湊是一個鍵值對集合,適合儲存物件。每個鍵可以有多個欄位,每個欄位都有一個值。
- 操作包括
HSET
、HGET
、HDEL
等。
典型應用場景:
- 儲存使用者資訊:如使用者 ID 作為鍵,使用者的屬性(姓名、年齡、性別等)作為欄位,避免將整個使用者物件序列化成字串。
- 配置項管理:儲存配置項,方便根據欄位名快速訪問和更新某個配置。
底層原理:
- 雜湊使用了兩種底層資料結構:小資料量時使用壓縮列表(ziplist),大資料量時使用雜湊表(hashtable)。壓縮列表可以節省記憶體,但隨著雜湊表的增長會自動轉換為雜湊表,保證查詢效率。
3. 列表(List)
介紹:
- 列表是一個雙向連結串列,可以從頭部或尾部插入、刪除元素,常用命令包括
LPUSH
、RPUSH
、LPOP
、RPOP
等。 - Redis 支援阻塞操作,如
BLPOP
、BRPOP
,在沒有元素時可以阻塞等待。
典型應用場景:
- 訊息佇列:列表可以作為簡單的訊息佇列,用
LPUSH
將訊息放入佇列,用RPOP
或BRPOP
彈出訊息。 - 任務排程:非同步任務分發系統中,可以將任務放入佇列中,由多個消費者去消費。
底層原理:
- 列表採用雙向連結串列(quicklist)實現。對於較短的列表,Redis 會使用壓縮列表(ziplist)來節省記憶體;對於較長的列表,則會採用真正的雙向連結串列來平衡操作的時間複雜度。
4. 集合(Set)
介紹:
- 集合是無序的、唯一的元素集合,提供類似於數學集合的操作,支援交集、並集、差集等。
- 常用操作包括
SADD
、SREM
、SISMEMBER
、SMEMBERS
、SINTER
等。
典型應用場景:
- 標籤系統:如將使用者標籤儲存為集合,每個集合代表一個使用者群體,方便進行集合運算,如找出同時擁有某兩個標籤的使用者。
- 去重功能:在某些場景下(如熱門搜尋詞、訪問日誌的去重),可以透過集合的唯一性特性來避免重複資料。
底層原理:
- 小集合時使用整數集合(intset),大集合時使用雜湊表(hashtable)實現。透過雜湊表的快速查詢特性,可以實現 O(1) 的時間複雜度來判斷元素是否存在。
5. 有序集合(Sorted Set)
介紹:
- 有序集合類似於集合,但每個元素關聯一個分數,集合中的元素會按分數排序。支援的操作包括
ZADD
、ZRANGE
、ZREM
、ZREVRANGE
、ZCOUNT
等。
典型應用場景:
- 排行榜:比如遊戲中的積分榜,按使用者分數進行排名。可以透過
ZADD
新增玩家及其分數,透過ZRANGE
獲取排名。 - 延遲任務:透過分數設定任務執行的時間,按時間從集合中取出需要執行的任務。
底層原理:
- 有序集合底層使用的是跳錶(Skiplist)和雜湊表相結合的資料結構,跳錶使得有序集合支援快速的範圍查詢和插入操作(時間複雜度 O(logN)),而雜湊表保證元素的快速定位。
6. 點陣圖(Bitmaps)
介紹:
- 點陣圖實際上是字串型別的擴充套件,可以把字串看作一系列連續的二進位制位,可以對這些二進位制位進行位操作。支援的命令有
SETBIT
、GETBIT
、BITCOUNT
、BITOP
等。
典型應用場景:
- 使用者簽到系統:用點陣圖儲存使用者的簽到記錄,每天對應一個 bit,0 表示未簽到,1 表示已簽到。
- 活躍使用者統計:透過點陣圖儲存某一時間段內使用者是否活躍,快速統計某天有多少活躍使用者。
底層原理:
- 點陣圖的底層儲存是 Redis 的字串結構,但位操作是直接針對每個二進位制位,因此能夠在非常緊湊的儲存空間內實現高效的操作,適合海量資料場景。
7. HyperLogLog
介紹:
- HyperLogLog 是一種用於基數統計的演算法,可以用於估算一個集合中不重複元素的個數,且佔用的記憶體空間非常小。
- 常用命令有
PFADD
、PFCOUNT
。
典型應用場景:
- 獨立訪客統計:在網站分析中統計獨立訪客(UV),只需為每個訪客 ID 新增到 HyperLogLog 中,快速得到不重複使用者數。
- 大規模資料去重計數:用於估算大規模資料中的去重個數,如點選、請求、訪問量等。
底層原理:
- HyperLogLog 是一種基數估計演算法,透過雜湊分佈將資料對映到位向量中,透過統計不同字首的最大長度來估算基數,其優點是佔用記憶體極小,缺點是隻能進行估算,存在一定誤差。
8. 地理空間(Geospatial)
介紹:
- Redis 支援儲存地理位置資料,並基於這些資料進行範圍查詢和距離計算。常用命令包括
GEOADD
、GEODIST
、GEORADIUS
、GEOHASH
等。
典型應用場景:
- LBS 應用:比如叫車應用中,儲存司機和乘客的地理位置,根據位置計算距離,匹配最近的車輛。
- 附近商家搜尋:使用者輸入位置後,查詢附近的商家,並根據距離排序返回。
底層原理:
- Redis 的地理空間資料是基於有序集合實現的,使用
GEOHASH
演算法將地理座標編碼為 64 位的整數,存入有序集合中。透過對這些編碼的範圍查詢,可以實現快速的空間檢索。
9. 流(Streams)
介紹:
Stream
是 Redis 5.0 引入的一種新的資料型別,支援訊息佇列的功能,類似於 Kafka 或者 RabbitMQ,支援消費組、訊息持久化和自動應答等特性。常用命令包括XADD
、XREAD
、XGROUP
、XACK
等。
典型應用場景:
- 訊息系統:透過流資料型別,多個消費者可以從同一個佇列中消費資料,實現訊息分發和處理。
- 日誌系統:可以將日誌資訊儲存在 Redis 的流中,實現持久化和實時消費。
底層原理:
- Stream 是基於壓縮列表和連結串列的結合體,資料結構複雜度較高,可以高效儲存大量的流式資料。透過內部維護的 ID 進行排序和管理,使得它適合處理有序的、持續生成的資料流。
總結
Redis 提供的多種資料型別,不僅豐富了其在不同業務場景下的適用性,還能透過記憶體友好的資料結構和高效的演算法來保證效能。在選擇 Redis 資料型別時,通常需要根據業務需求來匹配合適的資料結構,從而最大限度地提升系統效能和資源利用率。