Redis 數據結構

  1、Redis簡介
  Redis是一款基於key-value的高性能NoSQL數據庫,開源免費,遵照BSD協議。支持string(字符串) 、 hash(哈希) 、list(列表) 、 set(集合) 、 zset(有序集合)等數據結構,除此以外還提供了鍵過時、發佈訂閱、Lua腳本、事務、流水線(Pipeline)、持久化和主從複製等功能,並經過 Redis 哨兵(Sentinel)和 Redis Cluster(集羣)自動分區提供了高可用性。可用於數據庫、緩存和消息隊列等多種場景。
  2、數據結構
  Redis 是一個key-value數據庫,即數據存儲是以一個惟一的 key 對應一個 value,value 有 5 種基礎數據結構: string (字符串)、 hash (哈希) 、 list (列表)、 set (集合)和 zset (有序集合)。
  一、string(字符串)
  string 的值能夠是字符串(簡單的、以及json、xml格式的)、數字,甚至是二進制數據(圖片、音頻、視頻), 最大能存儲512MB。Redis 的字符串是動態的,是能夠修改的,當字符串長度小於 1M 時,擴容都是加倍現有的空間,若是超過 1M,擴容時一次只會多擴 1M 的空間。
  相關命令
  (1)設置值與獲取值
  set key value 設置指定 key 的值
  get key 獲取指定 key 的值
  批量設置與獲取
  mset key value [key value ...] 同時設置一個或多個 key-value 對。
  msetlen key value [key value ...] 同時設置一個或多個 key-value 對,當且僅當全部給定 key 都不存在。
  mget key1 [key2..] 獲取全部(一個或多個)給定 key 的值。html

  從 Redis 2.6.12 開始 set 命令支持一些選項修改其行爲:
  ·ex seconds:設置 key 秒級過時時間。
  ·px milliseconds:設置 key 毫秒級過時時間。
  ·nx:只有 key 不存在時,才能夠設置成功。
  ·xx:只有 key 存在時,才能夠設置成功。
  用法:set key value [ex seconds] [px milliseconds] [nx|xx]
  同時redis也有相關命令實現以上行爲:
  setex key seconds value 將值 value 關聯到 key ,並將 key 的過時時間設爲 seconds (以秒爲單位)。
  psetex key milliseconds value 這個命令和 SETEX 命令類似,但它以毫秒爲單位設置 key 的生存時間,而不是像 SETEX 命令那樣,以秒爲單位。
  setnx key value 只有在 key 不存在時設置 key 的值。
  因爲以上三個命令可使用 set 命令選項替代,因此可能會被廢棄,並最終被刪除。
  (2)自增自減
  incr key 將 key 中儲存的數字值增一。
  decr key 將 key 中儲存的數字值減一。
  incrby key increment 將 key 所儲存的值加上給定的增量值(increment)。
  decrby key decrement key 所儲存的值減去給定的減量值(decrement) 。
  若是 key 不存在,那麼 key 的值會先被初始化爲 0 ,而後再執行操做。
  若是值包含錯誤的類型,或字符串類型的值不能表示爲數字,那麼返回一個錯誤。
  以上操做的值僅限於 64 位有符號整數。
  incrbyfloat key increment 將 key 所儲存的值加上給定的浮點增量值(increment) 。
  (3)其餘命令
  strlen key 返回 key 所儲存的字符串值的長度(實際是字節長度)。
  getset key value 將給定 key 的值設爲 value ,並返回 key 的舊值(old value)。
  append key value 若是 key 已經存在而且是一個字符串, APPEND 命令將 value 追加到 key 原來的值的末尾。
  setrange key offset value 用 value 參數覆寫給定 key 所儲存的字符串值,從偏移量 offset 開始。
  getrange key start end 返回 key 中字符串值的子字符。
  內部編碼
  int:8個字節的長整型。
  embstr:小於等於44個字節的字符串。
  raw:大於44個字節的字符串。
  應用場景
  緩存(例如能夠將用戶信息序列化成json字符串存儲)、鎖(set nx、setnx)、計數器(incr、incrby、decr、decrby)等
  二、hash (哈希)
  hash 的值自己又是一個鍵值對結構,以下圖所示,這樣的結構特別適合用於存儲對象。git


  相關命令
  (1)設置與獲取
  hset key field value 將哈希表 key 中的字段 field 的值設爲 value 。
  hget key field 獲取存儲在哈希表中指定字段的值
  hmset key field1 value1 [field2 value2 ] 同時將多個 field-value (域-值)對設置到哈希表 key 中。
  hmget key field1 [field2] 獲取全部給定字段的值
  hgetall key 獲取在哈希表中指定 key 的全部字段和值
  hsetnx key field value 只有在字段 field 不存在時,設置哈希表字段的值。
  使用hgetall時,若是哈希元素個數比較多,會存在阻塞Redis的可能。這時可使用hscan命令,該命令會漸進式遍歷哈希結構
  hscan key cursor [MATCH pattern] [COUNT count] 迭代哈希表中的鍵值對。
  若是要獲取hash 表中因此的字段或值,可使用以下命令:
  hkeys key 獲取全部哈希表中的字段
  hvals key 獲取哈希表中全部值
  (2)自增
  hincrby key field increment 爲哈希表 key 中的指定字段的整數值加上增量 increment 。
  hincrbyfloat key field increment 爲哈希表 key 中的指定字段的浮點數值加上增量 increment 。
  (3)其餘命令
  hlen key 獲取哈希表中字段的數量
  hexists key field 查看哈希表 key 中,指定的字段是否存在。
  hdel key field2 [field2] 刪除一個或多個哈希表字段
  當 hash 移除了最後一個元素以後,該數據結構自動被刪除,內存被回收。
  內部編碼
  ·ziplist(壓縮列表):一塊連續的內存空間,元素之間沒有任何冗餘空隙,比較節省內存。
  當哈希類型元素個數小於hash-max-ziplist-entries配置(默認512個),且全部值都小於hash-max-ziplist-value配置(默認64字節)時使用。
  ·hashtable(哈希表):相對ziplist佔用了更多的內存,但它的讀寫時間複雜度爲O(1)。
  應用場景
  hash 結構也能夠用來存儲用戶信息,不一樣於 string 結構每次都須要序列化和反序列化(存在必定開銷),hash 能夠對每一個字段進行單獨操做,可是 hash 結構使用 hashtable 編碼時會消耗更多內存,請根據實際狀況取捨。
  三、list (列表)
  list 列表是簡單的字符串列表,按照插入順序排序,每個字符串就是一個元素,元素能夠重複。你能夠從兩端對列表進行插入和彈出操做,還能夠根據索引獲取元素或者指定範圍內的元素。存儲結構以下圖所示redis

  相關命令
  (1)添加元素
  lpush key value1 [value2] 從列表左邊添加一個或多個元素
  rpush key value1 [value2] 從列表右邊添加一個或多個元素
  lpushx key value 從列表左邊添加一個或多個元素,列表不存在時操做無效
  rpushx key value 從列表右邊添加一個或多個元素,列表不存在時操做無效
  linsert key before|after pivot value 在列表中指定元素前或者後插入元素
  (2)修改元素
  lset key index value 經過索引設置列表元素的值
  (3)查找元素
  lindex key index 經過索引獲取列表中的元素
  lrange key start stop 獲取列表指定範圍內的元素
  llen key 獲取列表長度
  (4)刪除元素
  lpop key 移出並獲取列表左邊第一個元素
  rpop key 移出並獲取列表右邊第一個元素
  blpop key1 [key2 ] timeout 移出並獲取列表左邊第一個元素, 若是列表沒有元素會阻塞列表直到等待超時(s)或發現可彈出元素爲止。
  brpop key1 [key2 ] timeout 移出並獲取列表右邊第一個元素, 若是列表沒有元素會阻塞列表直到等待超時或發現可彈出元素爲止。
  rpoplpush source destination 移除列表的右邊第一個元素,並將該元素添加到另外一個列表的左邊並返回
  brpoplpush source destination timeout 移除列表的右邊第一個元素,並將該元素添加到另外一個列表的左邊並返回; 若是列表沒有元素會阻塞列表直到等待超時或發現可彈出元素爲止。
  lrem key count value 根據參數 count 的值,移除列表中與參數 value 相等的元素
  ltrim key start stop 對一個列表進行修剪(trim),就是說,讓列表只保留指定區間內的元素,不在指定區間以內的元素都將被刪除。
  補充:
  blpop和brpop是lpop和rpop的阻塞版本,若是列表爲空時,它會等待timeout後返回,若是timeout=0,客戶端會被一直阻塞直到有新的元素添加進來。列表不爲空時客戶端會當即返回。
  lrem命令根據count的不一樣有三種狀況:
  ·count>0,從左到右,刪除count個 value 元素。
  ·count<0,從右到左,刪除count絕對值個 value 元素。
  ·count=0,刪除全部與 value 相同的元素。
  當列表彈出了最後一個元素以後,該數據結構自動被刪除,內存被回收。
  內部編碼
  ·ziplist(壓縮列表):當列表的元素個數小於list-max-ziplist-entries配置(默認512個) , 同時列表中每一個元素的值都小於list-max-ziplist-value配置時(默認64字節) 時使用該編碼。
  ·linkedlist(鏈表):普通的雙向鏈表,帶有prev和next指針,佔用了更多的內存,獲取某個節點的前置節點和後置節點的複雜度都是O(1)。
  ·quicklist(快速列表):Redis 3.2 版本提供,結合了 ziplist 和 linkedlist 二者的優點,以後 list 都採用該編碼。
  應用場景
  普通隊列(lpush+rpop)、消息隊列(lpush+brpop)、分頁(lrange)等。
  四、set (集合)
  set 是一種無序的集合,而且不容許有重複元素。支持多個集合取交集、並集、差集。結構以下算法

  相關命令
  (1)添加
  sadd key member1 [member2] 向集合添加一個或多個元素,返回添加成功的個數
  (2)刪除
  spop key 刪除並返回集合中的一個隨機元素,Redis從3.2版本開始支持[count]參數
  srem key member1 [member2] 刪除集合中一個或多個元素
  smove source destination member 將 member 元素從 source 集合移動到 destination 集合
  當集合中最後一個元素刪除以後,數據結構自動刪除,內存被回收。
  (3)獲取、查找
  scard key 獲取集合的元素個數
  smembers key 返回集合中的全部元素
  srandmember key [count] 返回集合中一個或多個隨機數
  sismember key member 判斷 member 元素是不是集合 key 的元素
  sscan key cursor [MATCH pattern] [COUNT count] 迭代集合中的元素
  (4)差集、並集、交集
  sdiff key1 [key2] 返回給定全部集合的差集
  sunion key1 [key2] 返回全部給定集合的並集
  sinter key1 [key2] 返回給定全部集合的交集
  sdiffstore destination key1 [key2] 返回給定全部集合的差集並存儲在 destination 中sinter
  sunionstore destination key1 [key2] 全部給定集合的並集存儲在 destination 集合中
  sinterstore destination key1 [key2] 返回給定全部集合的交集並存儲在 destination 中
  內部編碼
  ·intset(整數集合): 一個整數集合, 佔用內存較少,只能存儲整數類型的數據。當集合中的元素都是整數且元素個數小於set-maxintset-entries配置(默認512個) 時使用。
  ·hashtable(哈希表):當 intset 編碼沒法知足時使用。
  應用場景
  打標籤、投票、抽獎、社交(例如共同的好友、微博共同的關注)等。
  五、zset (有序集合)
  zset 和 set 不一樣的是每一個元素都會關聯一個double類型的分數(score)。redis正是經過分數來爲集合中的元素進行排序。有序集合的元素一樣不容許重複,但分數(score)卻能夠重複。結構以下數據庫

  相關命令
  (1)添加、自增
  zadd key score1 member1 [score2 member2] 向有序集合添加一個或多個元素,或者更新已存在元素的分數。被成功添加的新元素的數量,不包括那些被更新的、已經存在的元素。
  從 Redis 3.0.2開始,zadd命令能夠添加以下選項:
  ·nx: 元素不存在時才能設置成功。
  ·xx: 元素存在時才能設置成功。
  ·ch: 返回發生變化元素的數量(包括新添加的和被更新的元素)
  ·incr: 對 score 作增長, 等同於 zincrby 命令。
  zincrby key increment member 有序集合中對指定元素的分數加上增量 increment
  從 Redis 2.4 版本開始, zadd 命令每次能夠添加多個元素
  (2)統計數量
  zcard key 獲取有序集合的元素數量
  zcount key min max 計算在有序集合中指定區間分數的元素數量
  zlexcount key min max 在有序集合中計算指定字典區間內元素數量
  zlexcount命令說明:
  元素名稱前須要加 [ 符號做爲開頭, [ 符號與元素之間不能有空格
  可使用 - 和 + 表示得分最小值和最大值
  min 和 max 不能反, max 放前面 min放後面會致使返回結果爲0
  計算數量時,參數 min 和 max 的位置也計算在內。
  (3)查找
  zscore key member 返回有序集中指定元素的分數值
  zrangebylex key min max [LIMIT offset count] 經過字典區間返回有序集合的元素
  zrank key member 返回有序集合中指定元素的索引
  zrevrank key member 返回有序集合(按分數從高到低排序時)中指定元素的索引
  zrange key start stop [WITHSCORES] 經過索引區間返回有序集合成指定區間內的元素
  zrevrange key start stop [WITHSCORES] 經過索引區間返回有序集合成指定區間內的元素,分數從高到底
  zrangebyscore key min max [WITHSCORES] [LIMIT offset count] 經過分數返回有序集合指定區間內的元素
  zrevrangebyscore key max min [WITHSCORES] [LIMIT offset count] 經過分數返回有序集合指定區間內的元素,分數從高到低排序
  參數說明:
  默認狀況下,min和max區間的取值使用閉區間(小於等於或大於等於),你也能夠經過給參數前增長「(」符號來使用可選的開區間(小於或大於)。min和max也能夠是-inf和+inf,表明無限小和無限大。
  [LIMIT offset count]:offset表明查找的起始位置,count表明返回的元素個數json

  zscan key cursor [MATCH pattern] [COUNT count] 迭代有序集合中的元素(包括元素成員和元素分值)
  首次迭代 設置 cursor 爲0,再次迭代時以上次返回的遊標爲參數
  (4)刪除
  zrem key member [member ...] 刪除有序集合中的一個或多個元素
  zremrangebylex key min max 刪除有序集合中給定的字典區間的全部元素
  zremrangebyrank key start stop 刪除有序集合中給定的索引區間的全部元素
  zremrangebyscore key min max 刪除有序集合中給定的分數區間的全部元素
  zset 中最後一個元素被刪除後,數據結構自動刪除,內存被回收。
  (5)交集
  zunionstore destination numkeys key [key ...] 計算給定的一個或多個有序集的並集,並存儲在新的 key 中
  zinsterstore destination numkeys key [key ...] 計算給定的一個或多個有序集的交集並將結果集存儲在新的有序集合 key 中
  內部編碼
  ·ziplist(壓縮列表):當有序集合的元素個數小於zset-max-ziplistentries配置(默認128個) , 同時每一個元素的值都小於zset-max-ziplist-value配置(默認64字節) 時。
  ·skiplist(跳躍表): 當 ziplist 編碼沒法知足時使用。
  應用場景
  排行榜、時間軸、商品推薦等。
  其餘數據結構
  Redis 除了上面五種基礎結構外,還有Bitmaps,HyperLogLog、GEO、Stream四種數據結構。
  六、Bitmaps
  Bitmaps 實際上不是一種數據結構,它就是字符串,可是它能夠對字符串的位進行操做。能夠把Bitmaps 當成一個位數組來看待,以字母a爲例,它的ASCII碼是98,對應的二進制是01100001,Bitmaps 的結構以下:數組

  相關命令
  setbit key offset value 對 key 所儲存的字符串值,設置或清除指定偏移量上的位(bit)
  gitbit key offset 對 key 所儲存的字符串值,獲取指定偏移量上的位(bit)。
  bitcount key [start][end] 計算指定範圍內,被設置爲 1 的比特位的數量。
  bitpos key bit [start] [end] 返回位圖中第一個值爲 bit(0或1) 的二進制位的位置。
  bitop operation destkey key [key …] 對一個或多個保存二進制位的字符串 key 進行位元操做,並將結果保存到 destkey 上
  operation 能夠是 and、 or、 not、 xor這四種操做中的任意一種:
  bitop and destkey key [key ...] ,對一個或多個 key 求邏輯並,並將結果保存到 destkey 。
  bitop or destkey key [key ...] ,對一個或多個 key 求邏輯或,並將結果保存到 destkey 。
  bitop xor destkey key [key ...] ,對一個或多個 key 求邏輯異或,並將結果保存到 destkey 。
  bitop not destkey key ,對給定 key 求邏輯非,並將結果保存到 destkey 。
  除了 not 操做以外,其餘操做均可以接受一個或多個 key 做爲輸入。  緩存

  bitfield key [get type offset] [set type offset value] [incrby type offset increment] [overflow wrap|sat|fail]數據結構

  該命令詳情請查看:
       https://redis.io/commands/bitfield
  或http://www.redis.cn/commands/bitfield.html
  應用場景
  經過數據結構咱們發現 bitmaps 適用於存儲 bool 行爲的數據,好比統計用戶一年的登陸天數,使用 setbit 命令記錄登陸(好比用戶a第一天登陸了 setbit a 0 1),使用 bitcount 命令統計數量(bitcount a 0 364)。時間越久用戶越多,節省存儲空間的效果就越明顯。
  七、HyperLogLog
  HyperLogLog 是 Redis 2.8.9 添加的數據結構,它是一種用來作基數統計的算法,可使用固定且不多的內存(每一個 HyperLogLog 結構須要12K字節再加上key自己的幾個字節)來存儲集合的惟一元素。可是它統計的結果並非一個精確值,而是一個帶有 0.81% 標準錯誤(standard error)的近似值。HyperLogLog 具備去重功能。
  相關命令
  pfadd key element [element ...] 添加指定元素到 HyperLogLog 中。
  pfcount key [key ...] 返回給定 HyperLogLog 的基數估算值。
  pfmerge destkey sourcekey [sourcekey ...] 將多個 HyperLogLog 合併爲一個 HyperLogLog
  題外話:命令的開頭 pf 是 HyperLogLog 數據結構發明人 Philippe Flajolet 的首字母縮寫。
  應用場景
  統計某個網站或某個頁面的UV(只統計總數,不須要絕對準確,也不用知道是誰訪問的)。
  八、GEO
  Redis 3.2 提供了GEO(地理信息定位) 功能,它的底層實現是zset。
  相關命令
  geoadd key longitude latitude member [longitude latitude member ...] 將指定的地理空間位置(緯度、經度、名稱)添加到指定的key中
  有效的經度介於 -180 度至 180 度之間。
  有效的緯度介於 -85.05112878 度至 85.05112878 度之間。
  geopos key member [member ...] 從key裏返回全部給定位置元素的位置(經度和緯度)
  geodist key member1 member2 [unit] 返回兩個給定位置之間的距離。
  參數unit:
  m 表示單位爲米(默認)。
  km 表示單位爲公里。
  mi 表示單位爲英里。
  ft 表示單位爲英尺。
  georadius key longitude latitude radius m|km|ft|mi [withcoord] [withdist]
  [withhash] [COUNT count] [asc|desc] [store key] [storedist key]
  以給定的經緯度爲中心, 返回鍵包含的位置元素當中, 與中心的距離不超過給定最大距離的全部位置元素。
  可選參數:
  ithcoord: 返回結果中包含經緯度。
  withdist: 返回結果中包含離中心節點位置的距離。
  withhash: 返回結果中包含geohash, 有關geohash後面介紹。
  COUNT count: 指定返回結果的數量。
  asc|desc: 返回結果按照離中心節點的距離作升序或者降序。
  store key: 將返回結果的地理位置信息保存到指定鍵。
  storedist key: 將返回結果離中心節點的距離保存到指定鍵。
  georadiusbymember key member radiusm|km|ft|mi [withcoord] [withdist]
  [withhash] [COUNT count] [asc|desc] [store key] [storedist key]
  同上,只不過他是以指定的成員爲中心。
  geohash key member [member …] 返回一個或多個位置元素的 geohash 表示。
  九、Stream
  Stream 是 Redis 5.0 添加的數據結構,它是一個新的強大的支持多播的可持久化的消息隊列,借鑑了 Kafka 的設計。咱們前面說到 List 結構,它也能夠作消息隊列,但只支持點對點模式。Redis 有一個單獨模塊 PubSub(發佈訂閱) 支持消息多播,可是它不能持久化。Stream 不只能夠持久化,還支持消息分組、ACK(應答)等功能。因爲本人沒有使用過該數據結構,更多內容請參考:https://redis.io/topics/streams-introhttp://www.redis.cn/topics/streams-intro.htmlapp

  到這裏 Redis 的數據結構就介紹完了,更多使用請參考

  https://redis.io

  http://www.redis.cn

相關文章
相關標籤/搜索