redis有序集合性能 列表、集合、有序集合


1.1 列表

  列表(list)類型是用來存儲多個字符串,元素從左到右組成一個有序的集合.列表中的每個字符串被稱為元素(element),一個列表最多可以存儲(2的32次方)-1個元素.在redis中,可以對列表兩端插入(push)和彈出(pop),還可以獲取指定范圍的元素列表、獲取指定所有下標的元素等.

  列表類型有兩個特點:

    ①列表中的元素是有序的,這就意味着可以通過索引下標獲取某個元素或者某個范圍內的元素列表.

    ②列表中的元素可以是重復的.

1.1.1 命令 

  1) 插入命令

    (1) 從右邊插入元素.  rpush key value [value...]

    (2) 從左邊插入元素.  lpush key value [value....]  使用方法與rpush一樣,從左側插入.
  

  2) 查詢命令

    (1) 查詢指定范圍內的元素列表  lrange key start end  

    lrange操作會獲取列表指定索引范圍所有的元素.索引下標有兩個特點:第一,索引下標從左到右分別是0到N-1,但是從右到左分別是-1到-N.第二,lrange中的end選項包含了自身.

    (2) 獲取列表指定索引下的元素  lindex key index

    (3) 獲取列表長度  llen key

  3) 刪除命令  

    (1) 從列表左側或右側彈出元素.  lpop key  rpop key  將列表最左側與右側的元素彈出來.

    (2) 刪除指定元素  lrem key count value

     lrem命令會從列表中找到等於value的元素進行刪除,根據count的不同分為三種:

      count>0,從列表中刪除指定數量(count)的元素.

      count<0,從列表中刪除count絕對值數量的元素.

      count=0,刪除所有.

    (3) 按照索引范圍修剪列表  ltrim key start end

  4)修改命令

    修改指定索引下標的元素:  lset key index value

  5) 阻塞操作  

    阻塞式彈出:   blpop key [key...] timeout  brpop key [key...] timeout

    blpop與brpop命令是lpop和rpop命令的阻塞版本,他除了彈出方向不同,使用方法基本相同,所以下面以brpop命令進行說明,

    brpop命令包含兩個參數:

    1)列表為空:如果timeout等於3,那么客戶端等到三秒后返回,如果timeout=0,那么客戶端將一直阻塞,直到彈出成功.

    2)列表不為空:客戶端會立刻返回.

  在使用阻塞彈出命令時,有兩點需要注意.

  第一點:如果是多個鍵,那么會從左到右遍歷鍵,一旦有一個鍵能彈出元素客戶端就會立刻返回.
  第二點:如果多個客戶端同時對一個鍵進行操作,那么最先執行命令的客戶端可以獲取到值.

1.1.2 內部編碼

  列表類型的內部編碼有兩種:  編碼名 編碼描述

  ziplist(壓縮列表)  當列表的元素個數大於list-max-ziplist-entries配置(默認為512個),同時列表中每個元素的長度小於list-max-ziplist-value配置(默認為64字節).

  linkedlist(鏈表)  當列表的長度或值得大小不滿足ziplist的要求,redis會采用linkedlist為列表的內部實現編碼.

1.1.3 使用場景

  消息隊列:redis的lpush-brpop命令組合即可實現阻塞隊列,生產者客戶端使用lpush命令向列表插入元素.消費者客戶端使用brpop命令阻塞式的"搶"列表中的尾部元素.多個客戶端保證消息的負載均衡與可用性.

文章列表:每個用戶都有屬於自己的文章列表.此時可以考慮使用列表,因為列表不但是有序的,同時支持使用lrange按照索引范圍獲取多個元素.

開發提示:列表的使用場景有很多如: lpush+lpop=Stack(棧)、lpush+rpop=queue(隊列)、lpush+brpop=message queue、lpush+ltrim=Capped Collection(有限集合)

1.2 集合  

  集合(set)類型也是用來保存多個的字符串元素,但和列表不同的是:它的元素是無序且不可重復的,不能通過索引獲取元素.如下圖,集合user:1:follows中包含着"his"、"it"、"sports"、"music"四個元素,一個集合最多可以存儲(2的32次方-1)個元素.

 

1.2.1 命令 

  1) 集合內操作

    (1) 添加元素  sadd key value [value...]  返回結果為添加成功的元素數量.

    (2) 刪除元素  srem key value [value...]  返回結果為刪除成功的元素數量.

    (3) 獲取元素個數  scard key

    (4) 判斷元素是否在集合中  sismember key value

    (5) 隨機從集合中返回指定個數元素  srandmember key [count]  [count]是可選參數,如果不寫默認為:1.

    (6) 從集合中隨機彈出元素  spop key  spop操作可以從集合中隨機彈出一個元素.

    (7) 獲取集合的所有元素  smembers key  獲取集合所有元素,且返回結果是無序的.

  2) 集合間操作

    (1) 求多個集合的交集  sinter key [key...]

    (2) 求多個集合的並集  sunion key [key...]

    (3) 求多個集合的差集  sdiff key [key...]

    (4) 將交集、並集、差集的結果保存.

      sinterstore storeKey key [key...]
      sunionstore storeKey key [key...]
      sdiffstore storeKey key [key...]

    集合間的運算在元素比較多的情況下會比較耗時,所以redis提供了上面三個命令(原命令+store)將集合間交集、並集、差集的結果保存到storeKey中,例如將user:1:follows和user:2:follows兩個集合之間的交集結果保存到user:1_2:follows中.

1.2.2 內部編碼

  集合類型的內部編碼有兩種:

  編碼名            編碼描述

  intset(整數集合)    當集合中的元素全是整數,且長度不超過set-max-intset-entries(默認為512個)時,redis會選用intset作為內部編碼.

  hashtable(哈希表)   當集合無法滿足intset的條件時,redis會使用hashtable作為內部編碼.

1.2.3 使用場景

  集合類型比較典型的使用場景是標簽(tag).例如一個用戶可能對音樂感興趣,另一個用戶對新聞感興趣,這些想去點就是標簽.有了這些數據就可以獲得喜歡同一個標簽的人,以及用戶的共同喜好的標簽,這些數據對於用戶體驗來說比較重要.

1.3 有序集合

  有序集合相對於哈希、列表、集合來說會有一點陌生,但既然叫有序集合.那么它和集合必然是有着聯系,它保留了集合不能重復元素的特性.但不同的是,有序集合是可排序的.但是他和列表使用索引下標進行排序依據不同的是,它給每個元素設置一個分數(score)作為排序的依據.

列表、集合、有序結合的異同點

1.3.1 命令 

  1)集合內

    (1) 添加成員  zadd key score member [score member ...]

      有關zadd命令有兩點需要注意:  Redis 3.2為zadd命令添加了nx、xx、ch、incr四個選項:

        nx:member必須不存在,才可以設置成功,用於添加.

        xx:member必須存在,才可以設置成功,用於添加.

        ch:返回此次操作后,有序結合元素和分數發生變化的個數.

        incr: 對score進行添加操作,相當於后面介紹的zincrby.

      有序集合相比集合提供了排序字段,但是也產生了代價,zadd的時間復雜度是O(log(n)),sadd的時間復雜度為O(1).

    (2) 獲取成員個數  zcard key

    (3) 獲取某個成員的分數  zscore key member

    (4) 獲取成員排名  zrank key member  zrevrank key member

    (5) 刪除成員  zrem key member [member...]  

    (6) 增加成員分數  zincrby key score member

    (7) 獲取制定范圍的元素  zrange key start end [withscores]  zrevrange key start end [withscores]

      有序集合是按照分值排名的,zrange是由低到高返回,zrevrange反之,查詢全部:zrange user:ranking 0 -1,加上withscores參數顯示分數.

    (8) 返回指定分數范圍的成員  zrangebyscore key min max [withscores] [limit offset count]  zrevrangebyscore key min max [withscores] [limit offset count]

    (9) 返回指定分數范圍成員個數  zcount key min max

    (10) 刪除指定排名內的升序元素  zremrangebyrank key start end

    (11) 刪除指定分數范圍的成員  zremrangebyscore key min max

  2) 集合間的操作

    (1) 交集  zinterstore storeKey keyNum key [key ...] [weights weight [weight...]] [aggregate sum|min|max]  參數說明:

      storeKey:交集計算結果保存到這個鍵下.

      keyNum:需要做交集的鍵的個數.

      key[key ...]:需要做交集的鍵.

      weights weight [weight...]:每個鍵的權重,在做交集計算時,每個鍵中的每個member的分值會和這個權重相乘,每個鍵的權重默認為1.

      aggregate sum|min|sum:計算成員交集后,分值可以按照sum(和)、min(最小值)、max(最大值)做匯總.默認值為sum.

    (2) 並集  zunionstore storeKey keyNum key [key...] [weights weight [weight...]] [aggregate sum|min|max]  該命令的所有參數和zinterstore是一致的,只不過做的是並集計算.

1.3.2 內部編碼 

  編碼名稱        編碼描述

  ziplist(壓縮列表)    當有序集合的元素小於zset-max-ziplist-entries配置(默認是128個),同時每個元素的值都小於zset-max-ziplist-value(默認是64字節)時,Redis會用ziplist來作為有序集合的內部編碼實現,ziplist可以有效的減少內存的使用

  skiplist(跳躍表)      當ziplist的條件不滿足時,有序集合將使用skiplist作為內部編碼的實現,來解決此時ziplist造成的讀寫效率下降的問題.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM