Redis 作為一款高性能的開源內存數據庫,憑借其豐富多樣的數據結構和出色的性能,在緩存、會話存儲、實時分析等眾多場景中得到了廣泛應用。下面將詳細介紹 Redis 主要的數據結構,包括它們的類型、具體用法和適用場景。
1、字符串(String)
字符串是 Redis 中最基礎也最常用的數據結構,它可以存儲字符串、整數和浮點數等多種類型的數據,最大能存儲 512MB 的數據。
具體用法
字符串的常用命令豐富多樣。SET key value命令用于設置指定鍵的值,例如SET username "zhangsan",就將鍵 “username” 的值設置為 “zhangsan”。GET key則用于獲取指定鍵的值,執行GET username會返回 “zhangsan”。INCR key可對存儲整數的鍵進行自增操作,若鍵 “count” 的值為 5,執行INCR count后,其值變為 6。DECR key用于自減操作,INCRBY key increment能按指定增量增加,DECRBY key decrement可按指定減量減少。APPEND key value可以向字符串末尾追加內容,比如對鍵 “message” 的值 “Hello” 執行APPEND message " World",其值就變為 “Hello World”。
使用場景
在緩存場景中,字符串可用于存儲用戶信息、商品詳情等,減輕數據庫壓力。例如將商品的基本信息緩存起來,當用戶查詢時直接從 Redis 獲取,提高響應速度。在計數器方面,像網站的訪問量統計、視頻的播放次數統計等,都可以通過INCR等命令輕松實現。此外,還可用于存儲會話信息,如用戶登錄后的會話 ID 對應的用戶數據。
2、哈希(Hash)
哈希數據結構類似于 Java 中的 HashMap,適合存儲對象類型的數據,它由字段和對應的字段值組成,每個哈希可以存儲多達 2^32 - 1 個鍵值對。
具體用法
HSET key field value用于為哈希表中的字段設置值,例如HSET user:1 name "zhangsan" age 25,就為鍵 “user:1” 的哈希表設置了 “name” 字段值為 “zhangsan”,“age” 字段值為 25。HGET key field獲取指定哈希表中字段的值,HGET user:1 name會返回 “zhangsan”。HGETALL key能獲取哈希表中所有的字段和值,執行后會返回 “name”“zhangsan”“age”“25” 等內容。HDEL key field用于刪除哈希表中的指定字段,HEXISTS key field可判斷字段是否存在,HKEYS key返回哈希表中所有字段,HVALS key返回所有字段值。
使用場景
哈希非常適合存儲對象數據,如用戶信息包含姓名、年齡、地址等多個屬性,商品信息包含名稱、價格、庫存等,使用哈希存儲可以方便地對單個屬性進行操作,而無需修改整個對象。例如更新用戶的年齡,只需使用HSET user:1 age 26即可,操作高效且靈活。
3、列表(List)
Redis 的列表是一種有序的字符串集合,它允許在頭部和尾部進行元素的插入和刪除操作,列表中的元素可以重復,最多能存儲 2^32 - 1 個元素。
具體用法
LPUSH key value1 value2 ...用于向列表頭部添加一個或多個元素,LPUSH fruits "apple" "banana"會在列表 “fruits” 頭部依次添加 “apple” 和 “banana”,此時列表為 ["banana", "apple"]。RPUSH key value1 value2 ...則向列表尾部添加元素。LPOP key移除并返回列表頭部的元素,RPOP key移除并返回列表尾部的元素。LRANGE key start stop用于獲取列表中指定范圍的元素,LRANGE fruits 0 1會返回列表 “fruits” 中從索引 0 到 1 的元素。LLEN key獲取列表的長度,LREM key count value刪除列表中指定數量的指定值元素。
使用場景
消息隊列是列表的典型應用場景之一,通過LPUSH向隊列中添加消息,RPOP從隊列中取出消息,實現簡單的消息傳遞。在排行榜方面,可以存儲用戶的積分等數據,結合LRANGE命令獲取排名靠前的用戶。此外,還可用于存儲用戶的最近瀏覽記錄,通過LPUSH不斷添加新記錄,并用LTRIM命令限制列表長度,只保留最近的幾條記錄。
4、集合(Set)
集合是一個無序的字符串集合,集合中的元素具有唯一性,不能重復,最多可存儲 2^32 - 1 個元素。
具體用法
SADD key member1 member2 ...用于向集合中添加一個或多個元素,SADD tags "java" "python" "redis"就向集合 “tags” 中添加了 “java”“python”“redis” 三個元素。SMEMBERS key返回集合中的所有元素。SISMEMBER key member判斷元素是否在集合中,SISMEMBER tags "java"會返回 1,表示存在。SREM key member1 member2 ...刪除集合中的指定元素,SCARD key獲取集合的元素個數。集合還支持交集、并集、差集操作,SINTER key1 key2返回兩個集合的交集,SUNION key1 key2返回并集,SDIFF key1 key2返回差集。
使用場景
集合適合用于存儲需要去重的數據,如用戶的興趣標簽,確保每個標簽只出現一次。在社交場景中,可用于存儲用戶的好友列表,通過交集操作可以輕松找到兩個用戶的共同好友,例如SINTER user:1:friends user:2:friends就能得到用戶 1 和用戶 2 的共同好友。此外,還可用于實現抽獎功能,通過SRANDMEMBER key count隨機獲取集合中的元素作為中獎用戶。
5、有序集合(Sorted Set)
有序集合與集合類似,元素具有唯一性,但它為每個元素關聯了一個分數(score),并通過分數對元素進行排序,最多可存儲 2^32 - 1 個元素。
具體用法
ZADD key score1 member1 score2 member2 ...用于向有序集合中添加一個或多個元素及其分數,ZADD ranking 90 "zhangsan" 85 "lisi"向有序集合 “ranking” 中添加了 “zhangsan”(分數 90)和 “lisi”(分數 85)。ZRANGE key start stop [WITHSCORES]按照分數從小到大的順序返回指定范圍的元素,加上WITHSCORES會同時返回分數,ZRANGE ranking 0 1 WITHSCORES會返回 “lisi” 85、“zhangsan” 90。ZREVRANGE key start stop [WITHSCORES]則按照分數從大到小的順序返回元素。ZSCORE key member獲取指定元素的分數,ZINCRBY key increment member為元素的分數增加指定值,ZREM key member1 member2 ...刪除有序集合中的指定元素。
使用場景
有序集合在排行榜場景中應用廣泛,如游戲中的玩家積分排行榜、電商平臺的商品銷量排行榜等,通過ZRANGE或ZREVRANGE可以快速獲取排名靠前或靠后的用戶或商品。在延遲任務方面,可將任務的執行時間作為分數,通過ZRANGEBYSCORE命令獲取到了執行時間的任務進行處理。此外,還可用于實現范圍查詢,例如查詢分數在某個區間內的元素。
6、Bitmap(位圖)
Bitmap 是一種特殊的字符串,它通過位來存儲數據,每個位只能是 0 或 1,適合進行位級別的操作,能高效地利用存儲空間。
具體用法
SETBIT key offset value用于設置指定偏移量的位的值,SETBIT user:login:20231001 5 1表示用戶 ID 為 5 的用戶在 2023 年 10 月 1 日登錄過(將偏移量 5 的位設置為 1)。GETBIT key offset獲取指定偏移量的位的值,GETBIT user:login:20231001 5會返回 1。BITCOUNT key [start end]統計指定范圍內值為 1 的位的數量,BITCOUNT user:login:20231001可統計該日的登錄用戶數。BITOP operation destkey key1 key2 ...對多個 Bitmap 執行位運算(AND、OR、XOR 等),例如BITOP AND user:login:both user:login:20231001 user:login:20231002可得到兩天都登錄的用戶。
使用場景
Bitmap 非常適合用于存儲布爾型數據,如用戶的登錄狀態(每天一個 Bitmap,位的偏移量代表用戶 ID,值為 1 表示登錄),通過BITCOUNT可以快速統計每天的登錄人數,通過位運算可以統計連續多天登錄的用戶等。此外,還可用于實現用戶標簽的存儲,每個標簽對應一個 Bitmap,通過位運算可以快速篩選出具有特定組合標簽的用戶。
7、HyperLogLog
HyperLogLog 是一種用于基數統計的數據結構,它能夠以極小的空間代價估算出一個集合中不同元素的數量(基數),誤差率較低,通常在 1% 左右。
具體用法
PFADD key element1 element2 ...向 HyperLogLog 中添加元素,PFADD unique:visitors "user1" "user2" "user3"向 “unique:visitors” 中添加了三個用戶。PFCOUNT key用于獲取 HyperLogLog 估算的基數,PFCOUNT unique:visitors會返回 3(估算值)。PFMERGE destkey sourcekey1 sourcekey2 ...將多個 HyperLogLog 合并到一個新的 HyperLogLog 中,PFMERGE unique:visitors:week unique:visitors:day1 unique:visitors:day2 ...可得到一周的獨立訪客估算數。
使用場景
HyperLogLog 主要用于獨立用戶數統計、頁面 UV(獨立訪客)統計等場景。例如統計一個網站每天的獨立訪客數,無需存儲每個訪客的信息,只需通過PFADD添加訪客標識,PFCOUNT獲取估算的獨立訪客數,大大節省了存儲空間,尤其適合數據量大的場景。
8、Geospatial(地理空間)
Geospatial 是 Redis 用于存儲和操作地理空間數據的數據結構,它可以存儲經緯度信息,并支持距離計算、范圍查詢等操作。
具體用法
GEOADD key longitude latitude member ...用于向地理空間集合中添加地理位置,GEOADD cities 116.403874 39.914885 "beijing" 121.473701 31.230416 "shanghai"向 “cities” 中添加了北京和上海的經緯度信息。GEODIST key member1 member2 [unit]計算兩個地理位置之間的距離,GEODIST cities beijing shanghai km會返回北京到上海的大致距離(單位為千米)。GEORADIUS key longitude latitude radius unit [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]根據指定的經緯度和半徑,查詢該范圍內的地理位置,例如GEORADIUS cities 116.403874 39.914885 100 km可查詢北京周邊 100 千米內的城市。
使用場景
Geospatial 在 LBS(基于位置的服務)場景中發揮著重要作用,如外賣平臺的附近商家查詢、打車軟件的附近司機查找等。通過GEORADIUS命令可以快速篩選出指定范圍內的地理位置,結合距離信息為用戶提供相關服務。
綜上所述,Redis 的每種數據結構都有其獨特的特點和適用場景,在實際開發中,應根據具體的業務需求選擇合適的數據結構,以充分發揮 Redis 的高性能優勢。