Redis--位圖BitMap

1、BitMap是什麼html

經過一個bit位來表示某個元素對應的值或者狀態,其中的key就是對應元素自己,value對應0或1,咱們知道8個bit能夠組成一個Byte,因此bitmap自己會極大的節省儲存空間。python

 

2、Redis中的BitMapredis

Redis從2.2.0版本開始新增了setbit、getbit、bitcount等幾個bitmap相關命令。雖然是新命令,可是並無新增新的數據類型,由於setbit等命令只不過是在set上的擴展。服務器

 

Redis的bitmap讓咱們能夠實時的進行統計,而且極其節省空間。在模擬1億2千8百萬用戶的模擬環境下,在一臺MacBookPro上,典型的統計如「日用戶數」(dailyunique users) 的時間消耗小於50ms, 佔用16MB內存。spa

 

Bitmap是一串連續的2進制數字(0或1),每一位所在的位置爲偏移(offset),在bitmap上可執行AND,OR,XOR以及其它位操做。設計

 

3、Redis中的命令code

一、setbithtm

  語法:setbit key offset valueblog

  描述:內存

    對key所儲存的字符串值,設置或清除指定偏移量上的位(bit)。

    位的設置或清除取決於 value 參數,能夠是 0 也能夠是 1 。

    當 key 不存在時,自動生成一個新的字符串值。

    字符串會進行伸展(grown)以確保它能夠將 value 保存在指定的偏移量上。當字符串值進行伸展時,空白位置以 0 填充。

  注意:

    offset 參數必須大於或等於 0 ,小於 2^32 (bit 映射被限制在 512 MB 以內)。

    由於 Redis 字符串的大小被限制在 512 兆(megabytes)之內, 因此用戶可以使用的最大偏移量爲 2^29-1(536870911) , 若是你須要使用比這更大的空間, 請使用多個 key。

    當生成一個很長的字符串時, Redis 須要分配內存空間, 該操做有時候可能會形成服務器阻塞(block)。 在2010年出產的Macbook Pro上, 設置偏移量爲 536870911(512MB 內存分配)將耗費約 300 毫秒, 設置偏移量爲 134217728(128MB 內存分配)將耗費約 80 毫秒, 設置偏移量 33554432(32MB 內存分配)將耗費約 30 毫秒, 設置偏移量爲 8388608(8MB 內存分配)將耗費約 8 毫秒。

 

二、getbit

  語法:getbit key offset

  描述:

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

    當 offset 比字符串值的長度大,或者 key 不存在時,返回 0

三、bitcount

  語法:bitcount key [start] [end]

  返回值:被設置爲 1 的位的數量

  描述:

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

    通常狀況下,給定的整個字符串都會被進行計數,經過指定額外的 start 或 end 參數,可讓計數只在特定的位上進行。

    start 和 end 參數的設置和 GETRANGE key start end 命令相似,均可以使用負數值: 好比 -1表示最後一個字節, -2 表示倒數第二個字節,以此類推。

    不存在的 key 被當成是空字符串來處理,所以對一個不存在的 key 進行 BITCOUNT 操做,結果爲 0 。

四、bitpos

五、bitop

  語法:bitop operation destkey key [key ...]

    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 做爲輸入。    

  返回值:保存到 destkey 的字符串的長度,和輸入 key 中最長的字符串長度相等

  描述:

    對一個或多個保存二進制位的字符串 key 進行位元操做,並將結果保存到 destkey 上。

  注意:處理不一樣長度的字符串

    當 BITOP 處理不一樣長度的字符串時,較短的那個字符串所缺乏的部分會被看做 0 。

    空的 key 也被看做是包含 0 的字符串序列。

  

六、bitfield

 

4、應用場景

一、位圖計數統計

位圖計數統計的是bitmap中值爲1的位的個數。位圖計數的效率很高,例如,一個bitmap包含10億個位,90%的位都置爲1,在一臺MacBook Pro上對其作位圖計數須要21.1ms。

例子:日活躍用戶

爲了統計今日登陸的用戶數,咱們創建了一個bitmap,每一位標識一個用戶ID。當某個用戶訪問咱們的網頁或執行了某個操做,就在bitmap中把標識此用戶的位置爲1。

每次用戶登陸時會執行一次redis.setbit(daily_active_users, user_id, 1)。將bitmap中對應位置的位置爲1,時間複雜度是O(1)。統計bitmap結果顯示有今天有9個用戶登陸。Bitmap的key是daily_active_users,它的值是1011110100100101。

由於日活躍用戶天天都變化,因此須要天天建立一個新的bitmap。咱們簡單地把日期添加到key後面,實現了這個功能。例如要統計某一天有多少個用戶訪問,能夠把這個bitmap的key設計爲daily_active_users:2019-03-27。當用戶訪問進來,咱們只是簡單地在bitmap中把標識這個用戶的位置爲1,時間複雜度是O(1)。

 

備註:

Redis原生指令參考 http://redisdoc.com/index.html
Redis python客戶端 方法參考 http://redis-py.readthedocs.io/en/latest/#indices-and-tables

相關文章
相關標籤/搜索