Redis應用-位圖

系列文章數組

咱們都知道8bit = 1b = 2^{-10}kb,bitmap就是經過最小的單位bit來進行0或者1的設置,表示某個元素對應的值或者狀態。 一個bit的值,或者是0,或者是1;也就是說一個bit能存儲的最多信息是2。微信

位圖並非一種特殊的數據結構,其實本質上是二進制字符串,也能夠看作是 byte 數組。可使用普通的 get/set 直接獲取和設置整個位圖的內容,也可使用位圖操做 getbit/setbit 等將 byte 數組當作「位數組」來處理。數據結構

位圖的優點:

  1. 基於最小的單位bit進行存儲,因此很是省空間。
  2. 設置時候時間複雜度O(1)、讀取時候時間複雜度O(n),操做是很是快的
  3. 二進制數據的存儲,進行相關計算的時候很是快
  4. 方便擴容

通常能夠在以下場景使用:

  1. 用戶簽到
  2. 用戶在線狀態
  3. 統計活躍用戶
  4. 各類狀態值

經常使用命令

SETBIT

對 key 所儲存的字符串值,設置或清除指定偏移量上的位(bit)。 SETBIT key offset value offset 參數必須大於或等於 0 ,小於 2^32 (bit 映射被限制在 512 MB 以內)。異步

GETBIT

對 key 所儲存的字符串值,獲取指定偏移量上的位(bit)。 GETBIT key offset分佈式

BITCOUNT

計算給定字符串中,被設置爲 1 的比特位的數量。 BITCOUNT keypost

BITPOS

返回位圖中第一個值爲 bit 的二進制位的位置。 BITPOS key bit [start] [end]性能

BITOP

對一個或多個保存二進制位的字符串 key 進行位元操做,並將結果保存到 destkey 上。 BITOP operation destkey key [key …] operation 能夠是 AND 、 OR 、 NOT 、 XOR 這四種操做中的任意一種 BITOP AND destkey key [key ...] ,對一個或多個 key 求邏輯並,並將結果保存到 destkey 。code

BITFIELD

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

適用於各種統計應用

記錄用戶的簽到,每日在線狀況等,能夠將當天或者當天的偏移量對應的bit位設置爲1便可,使用BITCOUNT能夠輕鬆統計簽到次數。隊列

還有一種使用比較多的狀況,就是設置各種狀態值,例如商城的設置:是否能夠評價訂單,是否展現售罄商品,是否正常營業等狀態值可使用bitmap來存儲

在性能方面,如前面提到的簽到,即便運行 10 年,佔用的空間也只是每一個用戶 10*365 比特位(bit),也便是每一個用戶 456 字節。對於這種大小的數據來講, BITCOUNT key [start] [end] 的處理速度就像 GET key 和 INCR key 這種 O(1) 複雜度的操做同樣快。

固然若是你的 bitmap 數據很是大,那麼能夠考慮使用如下兩種方法:

  • 將一個大的 bitmap 分散到不一樣的 key 中,做爲小的 bitmap 來處理。使用 Lua 腳本能夠很方便地完成這一工做。
  • 使用 BITCOUNT key [start] [end] 的 start 和 end 參數,每次只對所需的部分位進行計算,而後在進行累加。

延伸閱讀

本文亦在微信公衆號【小道資訊】發佈,歡迎掃碼關注!

相關文章
相關標籤/搜索