這篇文章主要介紹“如何使用redis的bit位操作”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“如何使用redis的bit位操作”文章能幫助大家解決問題。
成都創(chuàng)新互聯(lián)-專業(yè)網站定制、快速模板網站建設、高性價比安居網站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式安居網站制作公司更省心,省錢,快速模板網站建設找我們,業(yè)務覆蓋安居地區(qū)。費用合理售后完善,十多年實體公司更值得信賴。
本文redis試驗代碼基于如下環(huán)境:
操作系統(tǒng):Mac OS 64位
版本:Redis 5.0.7 64 bit
運行模式:standalone mode
redis位操作
reids位操作也叫位數組操作、bitmap,它提供了SETBIT、GETBIT、BITCOUNT、BITTOP四個命令用于操作二進制位數組。
先來看一波基本操作示例
SETBIT
語法:SETBIT key offset value
即:命令 key 偏移量 0/1
setbit命令用于寫入位數組指定偏移量的二進制位設置值,偏移量從0開始計數,且只允許寫入1或者0,如果寫入非0和1的值則寫入失?。?/p>
GETBIT
語法:GETBIT key offset
即:命令 key 偏移量
gitbit命令用于獲取位數組指定偏移量上的二進制值:
BITCOUNT
語法:BITCOUNT key
即:命令 key
bitcount命令用于獲取指定key的位數組中值為1的二進制位的數量,之前我們寫入了偏移量0的值為1,偏移量10 的值為1,偏移量8的值為0:
BITOP
語法:BITOP operation destkey key [key...]
即:命令 操作 結果目標key key1 key2 ...
bitop命令可以對多個位數組的key進行and(按位與)、or(按位或)、xor(按位異或)運算,并將運算結果設置到destkey中:
底層數據結構分析
SDS是redis中的一種數據結構,叫做簡單動態(tài)字符串(Simple Dynamic String),并且它是一種二進制安全的,在大多數的情況下redis中的字符串都用SDS來存儲。
SDS的數據結構:
struct sdshdr { #記錄buff數組中已使用字節(jié)的數量 #也是SDS所保存字符串的長度 int len; #記錄buff數組中未使用字節(jié)的數量 int free; #字節(jié)數組,字符串就存儲在這個數組里 char buff[]; }
數據存儲示例:
圖片來源《redis設計與實現(xiàn)》
SDS的優(yōu)點:
鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術社區(qū)
時間復雜度為O(1)
杜絕緩沖區(qū)溢出
減少修改字符串長度時候所需的內存重分配次數
二進制安全的API操作
兼容部分C字符串函數
關于SDS的詳細介紹請大家參閱《redis設計與實現(xiàn)》一文。
redis中的位數組采用的是String字符串數據格式來存儲,而字符串對象使用的正是上文說的SDS簡單動態(tài)字符串數據結構。
圖片來源《redis設計與實現(xiàn)》
大家都知道的是一個字節(jié)用的是8個二進制位來存儲的,也就是8個0或者1,即一個字節(jié)可以存儲十進制0~127的數字,也即包含了所有的數字、英文大小寫字母以及標點符號。
1Byte=8bit
1KB=1024Byte
1MB=1024KB
1GB=1024MB
位數組在redis存儲世界里,每一個字節(jié)也是8位,初始都是:
0 0 0 0 0 0 0 0
而位操作就是在對應的offset偏移量上設置0或者1,比如將第3位設置為1,即:
0 0 0 0 1 0 0 0 #對應redis操作即: setbit key 3 1
在此基礎上,如果要在偏移量為13的位置設置1,即:
setbit key 13 1 #對應redis中的存儲為: 0 0 1 0 | 0 0 0 0 | 0 0 0 0 | 1 0 0 0
時間復雜度
GETBIT命令時間復雜度O(1)
STEBIT命令時間復雜度O(1)
BITCOUNT命令時間復雜度O(n)
BITOP命令時間復雜度O(n)、O(n2)
我們來看GETBIT以及SETBIT命令的時間復雜度為什么是O(1),當我們執(zhí)行一個SETBIT key 10086 1的值的時候,reids的計算方式如下:
獲取到要寫入位數組中的哪個字節(jié):10086÷8=1260,需要寫入到位數組的下標1260的字節(jié)
獲取要寫入到這個字節(jié)的第幾位:10086 mod 8 = 6,需要寫入到這個字節(jié)的下標為6即第7位上去。
通過這兩種計算方式大家可以清晰的看到,位操作的GETBIT和SETBIT都是常量計算,因此它的時間復雜度為O(1)。
而BITCOUNT命令需要對整個位數組的所有元素進行遍歷算出值為1的有多少個,當然redis對于大數據了的bit執(zhí)行bitcount命令會有一整套復雜的優(yōu)化的算法,但是核心思路還是這個意思,無非是減少部分遍歷查詢次數。比如以128位為一次遍歷,那么他的遍歷次數就是所有的位數除以128。
BITTOP命令則是根據不同的操作有不同的執(zhí)行方式。比如AND操作,則需要查看位值為1的即可。
存儲空間計算
根據上面的介紹,相信大家已經知道了基于redis的位數組數據結構存儲的數據占用內存大小是怎么計算的了。比如有100億的數據,那么它需要的字節(jié)數組:
1000000000÷8÷1024÷1024≈119.21MB
也就是存儲10億的數據只需要119MB左右的內存空間,這對于現(xiàn)在動輒16G、32G集群版的redis,完全沒有問題。
需要注意的是,如果你的數據量不大,那就不要把起始偏移量搞的很大,這樣也是占空間的,比如我們只需要存儲幾百條數據,但是其中的偏移量卻很大,這就會造成了很大的內存空間浪費。
應用場景
實際項目開發(fā)中有很多業(yè)務都適合采用redis的bit來實現(xiàn)。
用戶簽到場景
每天的日期字符串作為一個key,用戶Id作為offset,統(tǒng)計每天用戶的簽到情況,總的用戶簽到數
活躍用戶數統(tǒng)計
用戶日活、月活、留存率等均可以用redis位數組來存儲,還是以每天的日期作為key,用戶活躍了就寫入offset為用戶id的位值1。
同理月活也是如此。
用戶是否在線以及總在線人數統(tǒng)計
同樣是使用一個位數組,用戶的id映射偏移量,在線標識為1,下線標識為0。即可實現(xiàn)用戶上下線查詢和總在線人數的統(tǒng)計
APP內用戶的全局消息提示小紅點
現(xiàn)在大多數的APP里都有站內信的功能,當有消息的時候,則提示一個小紅點,代表用戶有新的消息。
關于“如何使用redis的bit位操作”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識,可以關注創(chuàng)新互聯(lián)行業(yè)資訊頻道,小編每天都會為大家更新不同的知識點。