Redis的Bitmap、HyperLogLog和Geo

weixin_39477597發表於2020-12-16

一、點陣圖

1. 相關介紹:

  • 點陣圖的最小單位是位元(bit),每個bit的取值只能是0或1。
  • 點陣圖不是特殊的資料結構,它的內容其實就是普通的字串,也就是byte陣列。我們可以使用普通的get/set方法直接獲取和設定整個點陣圖的內容,也可以使用點陣圖操作getbit/setbit等將byte陣列看成“位陣列“來處理。
  • redis的位陣列是自動擴充套件的,如果設定了某個偏移位置超出了現有的內容範圍,就會自動將位陣列進行零擴充。

2. 基本使用:

a. setbit 和 getbit

  • setbit key offset value:給點陣圖指定索引設定值,返回該偏移量之前對應的值
  • getbit key offset:獲取點陣圖指定索引值

具體演示如下圖:

這樣設定之後 s對應的點陣圖就如下圖所示:

b. bitcount、bitpos

  • bitcount 用來統計指定位置範圍內1的個數,bitpos用來查詢指定範圍內出現的第一個0或1
  • bitcount key [start end]:獲取點陣圖指定範圍(start到end,單位位元組,如果不指定就是獲取全部)位值為1的個數
  • bitpos key targetbit [start] [end]:計算點陣圖指定範圍(start到end,單位為位元組,如果不指定就是獲取全部)第一個偏移量對應的值等於targetBit的位置

注意:start 和end引數是位元組索引,也就是說指定的位範圍必須是8的倍數,而不能任意指定

具體演示如下圖:

c. bitop

  • bitop op destkey key [key ....]:做多個bitmap的and(交集)、or(並集)、not(非)、xor(異或)操作將結果儲存在destkey中。

具體演示如下圖:

d. bitfield

bitfield有三個指令,分別是get,set,incrby,它們都可以對指定位片段進行讀寫,但是最多隻能處理64個連續的位,如果超過64位,就得使用多個子指定,bitfield可以一次執行多個子指令。

  • bitfield key get unum start:從第(start+1)位開始取num位,u代表是無符號數
  • bitfield key get inum start:從第(start+1)位開始取num位,i代表是有符號數

具體演示如下圖:

所謂有符號數是指獲取的位陣列中第一位是符號位,剩下的才是值。如果第一位是1那就是負數。無符號位表示非負數,沒有符號位,獲取的位陣列全部都是值,有符號數最多可以獲取64位,無符號數只能獲取63位(因為redis協議中的integer是有符號數,最大64位,不能傳遞64位無符號值)。

e. incrby

用來指定範圍內的位進行自增操作,如果增加了正數,會出現上溢位,如果增加的數負數,會出現下溢位。redis預設處理是折返,如果出現了溢位就將溢位的符號位丟掉。如果是8位無符號位數255,加1就會溢位會全部變零。如果8位有符號數127,加1就會變成-128。

具體演示如下圖:

bitfield 指令提供了溢位策略子指令overflow 使用者可以選擇語出行為,預設是折返(wrap),還可以選擇失敗(fail),——報錯不執行,以及飽和截斷(sat)——超過了範圍就停留在最大或最小值。overflow 指令隻影響接下來的第一條指令,這條指令執行完後溢位策略會變成預設值折返(wrap)。

 飽和截斷(sat)

失敗不執行(fail)

二、HyperLogLog

1.基本介紹:

  • 基於HyperLogLog演算法:極小空間完成獨立數量統計
  • 本質還是字串

2. 使用方法

  • padd key element [element...]:向 hyperloglog 新增元素
  • pfcoutn key [key...]:計算 hyperloglog 的獨立總數
  • prmerge destkey sourcekey [sourceke...]:合併多個hyperloglog

具體演示如下圖:

三、Geo 

1.簡單介紹

  • Geo(地理資訊定位):儲存經緯度,計算兩地距離範圍計算等。
  • 在使用Redis 進行Geo查詢時,我們要時刻想到它的內部結構實際上 只是一個zset(skiplist),通過zset的score排序就可以得到座標附近的其他元素,通過score還原成座標值就可以得到元素的原始座標。
  • 在redis裡面,經緯度使用52位的整數編碼,放進了zset裡面,zset的value是元素的key,score 是GeoHash的52位整數值,zet的score雖然是浮點數,但是對於52位的整數值,它可以無損儲存。

2.基本用法

  • geo key longitude latitude member (member可以多個):新增地理資訊
  • geopos key member [member...]:獲取地理位置資訊
  • geodist key member1 member2 [unit]:獲取兩個地理位置的距離 unit:m(米)、km(千米)、mi(英里)、ft(尺)
  • 獲取指定位置範圍內的地址位置資訊集合命令:

georadius key longitude latitude radiusm|km|ft|mi [withcoord] [withdist] [withhash] [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]

withcoord:返回結果中包含經緯度

withdist:返回結果中包含距離中心節點位置

withhash:返回結果中包含geohash

COUNT count:指定返回結果的數量

asc|desc:將返回結果按照距離中心節點的距離做升序或者降序

store key:將返回結果的地理位置資訊儲存到指定鍵

storedist key:將返回結果距離中心節點的距離儲存指定鍵

具體演示如下圖:

3.相關說明:

  • since 3.2+ :在redis的3.2以後的版本才提供的功能
  • type geoKey = zset
  • 沒有刪除API:zrem key member 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相關文章