Redis中Bitmap的使用示例
在日常開發(fā)過程中,經(jīng)常會有一些 bool 類型數(shù)據(jù)需要存取。比如記錄用戶一年內(nèi)簽到的次數(shù),簽了是 1,沒簽是 0。如果使用 key-value 來存儲,那么每個用戶都要記錄 365 次,當用戶成百上億時,需要的存儲空間將非常巨大。解決這個問題,可以使用redis中的位圖。
位圖(bitmap)同樣屬于 string 數(shù)據(jù)類型。Redis 中一個字符串類型的值最多能存儲 512 MB 的內(nèi)容,每個字符串由多個字節(jié)組成,每個字節(jié)又由 8 個 Bit 位組成。位圖結(jié)構(gòu)正是使用“位”來實現(xiàn)存儲的,它通過將比特位設(shè)置為 0 或 1來達到數(shù)據(jù)存取的目的,這大大增加了 value 存儲數(shù)量,它存儲上限為2^32。
位圖本質(zhì)上就是一個普通的字節(jié)串,也就是 bytes 數(shù)組。您可以使用getbit/setbit命令來處理這個位數(shù)組,位圖的結(jié)構(gòu)如下所示:
位圖適用于一些特定的應(yīng)用場景,比如用戶簽到次數(shù)、或者登錄次數(shù)等。上圖是表示一位用戶 10 天內(nèi)來網(wǎng)站的簽到次數(shù),1 代表簽到,0 代表未簽到,這樣可以很輕松地統(tǒng)計出用戶的活躍程度。相比于直接使用字符串而言,位圖中的每一條記錄僅占用一個 bit 位,從而大大降低了內(nèi)存空間使用率。
Redis 官方也做了一個實驗,他們模擬了一個擁有 1 億 2 千 8 百萬用戶的系統(tǒng),然后使用 Redis 的位圖來統(tǒng)計“日均用戶數(shù)量”,最終所用時間的約為 50ms,且僅僅占用 16 MB內(nèi)存。
位圖應(yīng)用原理
某網(wǎng)站要統(tǒng)計一個用戶一年的簽到記錄,若用 sring 類型存儲,則需要 365 個鍵值對。若使用位圖存儲,用戶簽到就存 1,否則存 0。最后會生成 00010101… 這樣的存儲結(jié)果,其中每天的記錄只占一位,一年就是 365 位,約為 46 個字節(jié)。如果只想統(tǒng)計用戶簽到的天數(shù),那么統(tǒng)計 1 的個數(shù)即可。
位圖操作的優(yōu)勢,相比于字符串而言,它不僅效率高,而且還非常的節(jié)省空間。
Redis 的位數(shù)組是自動擴展的,如果設(shè)置了某個偏移位置超出了現(xiàn)有的內(nèi)容范圍,位數(shù)組就會自動擴充。
位圖常用命令
1) SETBIT命令
用來設(shè)置或者清除某一位上的值,其返回值是原來位上存儲的值。key 在初始狀態(tài)下所有的位都為 0 ,示例如下:
SETBIT key offset value
其中 offset 表示偏移量,從 0 開始。示例如下:
127.0.0.1:6379> SET user:1 a OK #設(shè)置偏移量offset為0 127.0.0.1:6379> SETBIT user:1 0 1 (integer) 0 #當對應(yīng)位的字符是不可打印字符,redis會以16進制形式顯示 127.0.0.1:6379> GET user:1 "\xe1"
2) GETBIT命令
用來獲取某一位上的值。示例如下:
127.0.0.1:6379> GETBIT user:1 0 (integer) 1
當偏移量 offset 比字符串的長度大,或者當 key 不存在時,返回 0。
redis> EXISTS bits (integer) 0 redis> GETBIT bits 100000 (integer) 0
3) BITCOUNT命令
統(tǒng)計指定位區(qū)間上,值為 1 的個數(shù)。語法格式如下:
BITCOUNT key [start end]
示例如下:
127.0.0.1:6379> BITCOUNT user:1 (integer) 8
通過指定的 start 和 end 參數(shù),可以讓計數(shù)只在特定的字節(jié)上進行。start 和 end 參數(shù)和 GETRANGE 命令的參數(shù)類似,都可以使用負數(shù),比如 -1 表示倒數(shù)第一個位, -2 表示倒數(shù)第二個位。.
4)Redis Bitop 命令
對一個或多個保存二進制位的字符串 key 進行位元操作,并將結(jié)果保存到 destkey 上
語法:operation 可以是 AND 、 OR 、 NOT 、 XOR 這四種操作中的任意一種:
- BITOP AND destkey key [key …] ,對一個或多個 key 求邏輯并,并將結(jié)果保存到 destkey 。
- BITOP OR destkey key [key …] ,對一個或多個 key 求邏輯或,并將結(jié)果保存到 - destkey 。
- BITOP XOR destkey key [key …] ,對一個或多個 key 求邏輯異或,并將結(jié)果保存到 destkey 。
- BITOP NOT destkey key ,對給定 key 求邏輯非,并將結(jié)果保存到 destkey 。
除了 NOT 操作之外,其他操作都可以接受一個或多個 key 作為輸入。
場景
統(tǒng)計當日活躍用戶
每日活躍統(tǒng)計創(chuàng)建一個bitmap鍵,當用戶活躍了根據(jù)用戶id的偏移量來設(shè)置
對應(yīng)的位為1
用戶簽到
每個用戶創(chuàng)建一個位圖的鍵,以某一天為基礎(chǔ),之后的天數(shù)距離這一天的天數(shù)為偏移量,
如果用戶點擊了簽到,則設(shè)置對用的偏移位為1。
到此這篇關(guān)于Redis中Bitmap的使用示例的文章就介紹到這了,更多相關(guān)Redis Bitmap內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Redis中Bloom filter布隆過濾器的學(xué)習(xí)
布隆過濾器是一個非常長的二進制向量和一系列隨機哈希函數(shù)的組合,可用于檢索一個元素是否存在,本文就詳細的介紹一下Bloom filter布隆過濾器,具有一定的參考價值,感興趣的可以了解一下2022-12-12Caffeine實現(xiàn)類似redis的動態(tài)過期時間設(shè)置示例
這篇文章主要為大家介紹了Caffeine實現(xiàn)類似redis的動態(tài)過期時間示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08redislive監(jiān)控redis服務(wù)的圖文教程_動力節(jié)點Java 學(xué)院整理
這篇文章主要介紹了redislive監(jiān)控redis服務(wù)的圖文教程_動力節(jié)點Java 學(xué)院整理,需要的朋友可以參考下2017-08-08Redis 安裝 redistimeseries.so(時間序列數(shù)據(jù)類型)的配置步驟
這篇文章主要介紹了Redis 安裝 redistimeseries.so(時間序列數(shù)據(jù)類型)詳細教程,配置步驟需要先下載redistimeseries.so 文件,文中介紹了啟動失敗問題排查,需要的朋友可以參考下2024-01-01Redis不是一直號稱單線程效率也很高嗎,為什么又采用多線程了?
這篇文章主要介紹了Redis不是一直號稱單線程效率也很高嗎,為什么又采用多線程了的相關(guān)資料,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03