Redis 知多少 (二)---Redis 基本資料型別及常用應用場景

0Robert0發表於2020-05-18

一、字串(String)

  1. 型別介紹
    字串型別是Redis中最基本的資料型別,它能儲存任何形式的字串,包括二進位制資料。你可以用其儲存使用者的任何資料、JSON化的物件甚至是一張圖片。一個字串型別鍵允許儲存的資料的最大容量是512MB。

    字串型別是其他4種資料型別的基礎,其他資料型別和字串型別的差別從某種角度來說只是組織字串的形式不同。

  2. 字串常用命令

    序號 命令及描述
    1 SET key value 設定指定 key 的值
    2 GET key 獲取指定 key 的值。
    3 GETRANGE key start end 返回 key 中字串值的子字元
    4 MGET key1 [key2..] 獲取所有(一個或多個)給定 key 的值。
    5 STRLEN key 返回 key 所儲存的字串值的長度。
    6 MSET key value [key value …] 同時設定一個或多個 key-value 對。
    7 INCR key 將 key 中儲存的數字值增一。
    8 INCRBY key increment 將 key 所儲存的值加上給定的增量值(increment) 。
    9 INCRBYFLOAT key increment 將 key 所儲存的值加上給定的浮點增量值(increment) 。
    10 DECR key 將 key 中儲存的數字值減一。
    11 DECRBY key decrement key 所儲存的值減去給定的減量值(decrement) 。
    12 APPEND key value 如果 key 已經存在並且是一個字串, APPEND 命令將 value 追加到 key 原來的值的末尾。
  3. 應用場景

    • 用於快取;比如快取動態生成的頁面;快取熱資料;快取計算複雜的結果資料;快取json化的物件;快取base_64的編碼的圖片等;

      一般我們快取資料的時候都會有這麼兩個步驟:
      1、獲取資料時,先去讀Redis,如果沒有資料,讀取資料庫,然後將資料寫入到Redis。
      2、插入資料後,同時寫入Redis。

    • 計數器/id分發器;比如記錄網站每日PV;記錄關注、被關注的人數;記錄閱讀量;記錄點讚的數量;記錄某個檔案的下載數量;記錄視訊、音訊被播放的次數;記錄產品銷量;記錄資料庫的主鍵id等

      在開發中經常會遇到計數的功能,這時我們可以使用INCR 、DECR 、INCRBY、DECRBY等Redis 命令對資料進行增減;需要注意的是Redis的自增是有範圍的,它的範圍是 - 2^63-1 ~ 2^63-1,超過了這個值,Redis 會報錯。

    • 限時服務;比如簡訊、郵箱驗證需要的驗證碼;限制使用者每分鐘訪問的次數;限時優惠活動等;

      一般在登入、註冊、找回密碼等功能都會通過手機、郵箱獲取驗證碼登入,我們要保證前後端的驗證碼一致,且不會被懂行的人越過前端驗證,可以快取到Redis中,並設定相應的過期時間;有些爬蟲很噁心,會不考慮你網站的情況下瘋狂獲取你網站的資料,基本相當於弱一些的DDOS,為了防止這種情況,避免網站卡頓,影響其他使用者,可以使用Redis可以對鍵值設定過期時間

    • 共享session

      如果我們專案裡採用了session,那我們做伺服器叢集的時候,隨著使用者訪問到不同的伺服器,就會在每個從伺服器上都各自儲存自己的session,那麼當使用者第一次請求被分發給A伺服器,第二次被分發給B伺服器的時候,session資訊會由於不共享而導致使用者需要重新登入或者其他一些操作,我們不得不考慮第三應用來儲存session。通過我們用關係型資料庫或Redis等非關係型資料庫來共享session。又因為關係型資料庫儲存和讀取效能遠遠無法跟Redis等非關係型資料庫,所以Redis是最好的選擇。

    • 分散式鎖

      使用setnx實現分散式鎖。例如,我們在專案中有時會加一些定時任務在後臺跑功能,為了保證定時任務的高可用,往往會同時部署多個具備相同功能的定時任務,但是業務上只希望其中的某一臺服務執行定時任務,當定時任務的時間點觸發時,多個服務同時競爭一個鎖,獲取到鎖的執行定時任務,沒獲取到的放棄執行定時任務。

二、雜湊(Hash)

  1. 型別介紹
    Redis是採用字典結構以鍵值對的形式儲存資料的,而Hash的鍵值也是一種字典結構,其儲存了欄位和欄位值的對映,但欄位值只能是字串,不支援其他資料型別,換句話說,雜湊型別不能巢狀其他的資料型別。

    注意:
    Redis 中每個 Hash 可以儲存 2^32 - 1 個鍵值對(40多億)。
    Redis Hash 超時時間只能設定在 Hash key 上,不能單獨對Hash裡面的鍵值對設定過期時間。
    Redis的其他資料型別同樣不支援資料型別巢狀。比如集合型別的每個元素都只能是字串,不能是另一個集合或雜湊表等。

  2. 常用命令

    序號 命令及描述
    1 [HDEL key field2 [field2..]] 刪除一個或多個雜湊表欄位
    2 [HEXISTS key field] 檢視雜湊表 key 中,指定的欄位是否存在。
    3 [HGET key field] 獲取儲存在雜湊表中指定欄位的值
    4 [HGETALL key] 獲取在雜湊表中指定 key 的所有欄位和值
    5 [HINCRBY key field increment] 為雜湊表 key 中的指定欄位的整數值加上增量 increment
    6 [HINCRBYFLOAT key field increment] 為雜湊表 key 中的指定欄位的浮點數值加上增量 increment 。
    7 [HKEYS key] 獲取所有雜湊表中的欄位
    8 [HLEN key] 獲取雜湊表中欄位的數量
    9 [HMGET key field1 [field2]] 獲取所有給定欄位的值
    10 [HMSET key field1 value1 [field2 value2 ]] 同時將多個 field-value (域-值)對設定到雜湊表 key 中。
    11 [HSET key field value] 將雜湊表 key 中的欄位 field 的值設為 value 。
    12 [HSETNX key field value] 只有在欄位 field 不存在時,設定雜湊表欄位的值。
    13 [HVALS key] 獲取雜湊表中所有值
    14 HSCAN key cursor [MATCH pattern] [COUNT count] 迭代雜湊表中的鍵值對。
  3. 應用場景

    • 快取物件

      Hash特別適合用於儲存物件,而且取資料的時候時間複雜度為 O(1)。

    • 購物車

      以使用者id為key,商品id為field,商品數量為value;通過HINCRBY增減商品數量;通過HDEL移除商品;通過HLEN 獲取商品的總量;通過HGETALL 全選商品;通過HGET 、HMGET 獲取一個或者多個選中的商品;
      給Redis鍵值命名時最好能見名知意,例如:shoppingcart_user:id=>commodity:id=>商品數量

    • id分發器

      專案中總有些關聯表,在插入時必須先獲得A表的主鍵id才能插入B表的資料;亦或者批量插入時需要提前給每一條資料設定主鍵id;這時當我們把資料庫表名作為hash的field,把主鍵id設為value, 再配合HINCRBY命令就可以在插入資料時,提前獲得主鍵id

三、列表(List)

  1. 型別介紹
    Redis列表是簡單的字串列表,按照插入順序排序。你可以新增一個元素導列表的頭部(左邊)或者尾部(右邊)。列表型別內部是使用雙向連結串列(double linked list)實現的,所以向列表兩端新增元素的時間複雜度為0(1),獲取越接近兩端的元素速度就越快。不過使用連結串列的代價是通過索引訪問元素比較慢。
    注意:
    每個列表最多可以儲存 2^32 - 1 個元素(40多億)

  2. 常用命令

    序號 命令及描述
    1 [BLPOP key1 [key2 ] timeout] 移出並獲取列表的第一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止。
    2 [BRPOP key1 [key2 ] timeout] 移出並獲取列表的最後一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止。
    3 [BRPOPLPUSH source destination timeout] 從列表中彈出一個值,將彈出的元素插入到另外一個列表中並返回它; 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止。
    4 [LINDEX key index] 通過索引獲取列表中的元素
    5 [LINSERT key BEFORE|AFTER pivot value]在列表的元素前或者後插入元素
    6 [LLEN key] 獲取列表長度
    7 [LPOP key] 移出並獲取列表的第一個元素
    8 [LPUSH key value1 [value2]] 將一個或多個值插入到列表頭部
    9 [LPUSHX key value] 將一個或多個值插入到已存在的列表頭部
    10 [LRANGE key start stop] 獲取列表指定範圍內的元素
    11 [LREM key count value] 移除列表元素
    12 [LSET key index value] 通過索引設定列表元素的值
    13 [LTRIM key start stop] 對一個列表進行修剪(trim),就是說,讓列表只保留指定區間內的元素,不在指定區間之內的元素都將被刪除。
    14 [RPOP key] 移除並獲取列表最後一個元素
    15 [RPOPLPUSH source destination] 移除列表的最後一個元素,並將該元素新增到另一個列表並返回
    16 [RPUSH key value1 [value2]] 在列表中新增一個或多個值
    17 [RPUSHX key value] 為已存在的列表新增值
  3. 應用場景

    • 排行榜

      雖然list能夠實現排行榜,但是侷限的地方在於list不能實現微博熱搜排行榜或者百度搜尋熱點排行榜那種實時動態變化的排行榜,只能實現那種經過計算後存到list中的排行榜,比如學生成績排行榜。實現排行榜要點在於使用list型別的lrange命令,該可以分頁檢視佇列中的資料。

    • 最新文章、訊息等

      list型別的lpush命令和lrange命令能實現最新列表的功能,每次通過lpush命令往列表裡插入新的元素,然後通過lrange命令讀取最新的元素列表,如朋友圈的點贊列表、評論列表。但是,並不是所有的最新列表都能用list型別實現,因為對於頻繁更新的列表,list型別的分頁可能導致列表元素重複或漏掉。

    • 任務佇列

      list型別的lpop和rpush(或者反過來,lpush和rpop)能實現佇列的功能。

    • 優先順序佇列

      list型別的lpush和brpop可以通過阻塞佇列實現不同佇列的優先順序,例如專案中需要給新使用者發郵件;使用者訂閱文章欄目後,每次更新文章也需要給使用者發郵件;

四、集合(Set)

  1. 型別介紹
    集合的概念高中的數學課就學習過。而Redis集合是string的無序集合。集合成員是唯一的,即集合中不能出現重複的資料。一個集合型別可以儲存至多2^32-1個字串。
  2. 常用命令
    序號 命令及描述
    1 [SADD key member1 [member2]] 向集合新增一個或多個成員
    2 [SCARD key] 獲取集合的成員數
    3 [SDIFF key1 [key2]] 返回給定所有集合的差集
    4 [SDIFFSTORE destination key1 [key2]] 返回給定所有集合的差集並儲存在 destination 中
    5 [SINTER key1 [key2]] 返回給定所有集合的交集
    6 [SINTERSTORE destination key1 [key2]] 返回給定所有集合的交集並儲存在 destination 中
    7 [SISMEMBER key member] 判斷 member 元素是否是集合 key 的成員
    8 [SMEMBERS key]返回集合中的所有成員
    9 [SMOVE source destination member] 將 member 元素從 source 集合移動到 destination 集合
    10 [SPOP key] 移除並返回集合中的一個隨機元素
    11 [SRANDMEMBER key [count]] 返回集合中一個或多個隨機數
    12 [SREM key member1 [member2]] 移除集合中一個或多個成員
    13 [SUNION key1 [key2]] 返回所有給定集合的並集
    14 [SUNIONSTORE destination key1 [key2]] 所有給定集合的並集儲存在 destination 集合中
    15 [SSCAN key cursor [MATCH pattern] [COUNT count]]迭代集合中的元素
  3. 應用場景
    1. 好友/共同好友/可能認識的人/關注/粉絲

      SINTER 命令可以獲得A和B兩個使用者的共同好友
      SISMEMBER 命令可以判斷A是否是B的好友
      SCARD 命令可以獲取好友數量
      關注時,SMOVE 命令可以將B從A的粉絲集合轉移到A的好友集合
      SDIFF 命令可以獲取A和B可能認識的人

    2. 黑名單/白名單

      經常有業務出於安全性方面的考慮,需要設定使用者黑名單、ip黑名單、裝置黑名單等,set型別適合儲存這些黑名單資料,SISMEMBER 命令可用於判斷使用者、ip、裝置是否處於黑名單之中。

    3. 隨機展示

      通常,首頁的展示區域有限,但是又不能總是展示固定的內容,一種做法是先確定一批需要展示的內容,再從中隨機獲取。

    4. 抽獎

      點選參與抽獎的時候,將對應使用者加到抽獎集合中,通過SMEMBERS 抽獎活動ID 獲取參與人數,通過SRANDMEMBER 抽獎活動ID或SPOP 抽獎活動ID 進行抽獎。 這樣的設計比用程式方便多,但是如果獎品比較多,又或者需要自定義不同獎品的權重就需要自己設計抽獎程式了。

    5. 標籤

      比如我們在CSDN釋出部落格是需要選擇文章標籤的,然後給一篇部落格打上標籤之後,就可以通過標籤進行分類展示、進行搜尋

    6. 統計網站每日的UV

      利用集合元素的唯一性,可以記錄訪問網站的所有獨立 IP,用於統計UV

五、有序集合(sorted set)

  1. 型別介紹
    有序集合在集合型別的基礎上有序集合型別為集合中的每個元素都關聯了一個分數,這使得我們不僅可以完成插入、刪除和判斷元素是否存在等集合型別支援的操作,還能夠獲得分數最高(或最低)的前N個元素、獲得指定分數範圍內的元素等與分數有關的操作。雖然集合中每個元素都是不同的,但是它們的分數卻可以相同。
    有序集合是通過雜湊表實現的,所以新增,刪除,查詢的複雜度都是O(1)。 集合中最大的成員數為 2^32 - 1 (4294967295, 每個集合可儲存40多億個成員)。

  2. 常用命令

    序號 命令及描述
    1 [ZADD key score1 member1 [score2 member2]] 向有序集合新增一個或多個成員,或者更新已存在成員的分數
    2 [ZCARD key] 獲取有序集合的成員數
    3 [ZCOUNT key min max] 計算在有序集合中指定區間分數的成員數
    4 [ZINCRBY key increment member] 有序集合中對指定成員的分數加上增量 increment
    5 [ZINTERSTORE destination numkeys key [key …]] 計算給定的一個或多個有序集的交集並將結果集儲存在新的有序集合 key 中
    6 [ZLEXCOUNT key min max] 在有序集合中計算指定字典區間內成員數量
    7 [ZRANGE key start stop [WITHSCORES]] 通過索引區間返回有序集合成指定區間內的成員
    8 [ZRANGEBYLEX key min max [LIMIT offset count]] 通過字典區間返回有序集合的成員
    9 [ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT]] 通過分數返回有序集合指定區間內的成員
    10 [ZRANK key member] 返回有序集合中指定成員的索引
    11 [ZREM key member [member …]] 移除有序集合中的一個或多個成員
    12 [ZREMRANGEBYLEX key min max] 移除有序集合中給定的字典區間的所有成員
    13 [ZREMRANGEBYRANK key start stop] 移除有序集合中給定的排名區間的所有成員
    14 [ZREMRANGEBYSCORE key min max] 移除有序集合中給定的分數區間的所有成員
    15 [ZREVRANGE key start stop [WITHSCORES]] 返回有序集中指定區間內的成員,通過索引,分數從高到底
    16 [ZREVRANGEBYSCORE key max min [WITHSCORES]] 返回有序集中指定分數區間內的成員,分數從高到低排序
    17 [ZREVRANK key member] 返回有序集合中指定成員的排名,有序整合員按分數值遞減(從大到小)排序
    18 [ZSCORE key member] 返回有序集中,成員的分數值
    19 [ZUNIONSTORE destination numkeys key [key …]] 計算給定的一個或多個有序集的並集,並儲存在新的 key 中
    20 [ZSCAN key cursor [MATCH pattern] [COUNT count]] 迭代有序集合中的元素(包括元素成員和元素分值)
  3. 應用場景

    1. 排行榜

      帶有權重的排行榜,比如一個遊戲的使用者得分排行榜
      根據好友的“親密度”排序顯示好友列表
      根據文章的閱讀量或點贊量對文章列表排序

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章