您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“Redis中的bitmap是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Redis中的bitmap是什么”吧!
Redis 的位圖(bitmap)是由多個(gè)二進(jìn)制位組成的數(shù)組,數(shù)組中的每個(gè)二進(jìn)制位都有與之對應(yīng)的偏移量(從 0 開始),通過這些偏移量可以對位圖中指定的一個(gè)或多個(gè)二進(jìn)制位進(jìn)行操作。
實(shí)際上,位圖并不是 Redis 提供的一種新的數(shù)據(jù)類型,它是字符串類型的擴(kuò)展。所以位圖的命令可以直接使用在字符串類型的鍵上,位圖命令操作的鍵也可以被字符串類型命令操作。
比如,現(xiàn)有一個(gè)字符串鍵 foo:
redis> set foo bar
1 個(gè)字節(jié)由 8 個(gè)二進(jìn)制位組成,所以 foo 鍵的二進(jìn)制形式就是:
通過 SETBIT 命令,可以為位圖指定偏移量上的二進(jìn)制位設(shè)置值,offset 必須大于等于 0,value 只能是 0 或 1。此命令的時(shí)間復(fù)雜度是 O(1)。
SETBIT key offset value
SETBIT 命令在對二進(jìn)制位進(jìn)行設(shè)置之后,將返回二進(jìn)制位被設(shè)置之前的舊值作為結(jié)果。
假設(shè)現(xiàn)在想把 bar 變?yōu)?aar,只需如下兩步操作:
redis> setbit foo 6 0 (integer) 1 redis> setbit foo 7 1 (integer) 0 redis> get foo"aar"
當(dāng)執(zhí)行 SETBIT 命令嘗試對一個(gè)位圖進(jìn)行設(shè)置的時(shí)候,如果位圖不存在,或者位圖當(dāng)前的大小無法滿足,Redis 將對被設(shè)置的位圖進(jìn)行擴(kuò)展,并將所有未被設(shè)置的二進(jìn)制位的值初始化為 0。比如:
redis> setbit far 10 1
由于 far 并不存在,所以 Redis 會(huì)將 0~9 的二進(jìn)制位設(shè)置為 0,因?yàn)?Redis 對位圖的擴(kuò)展操作是以字節(jié)為單位進(jìn)行的,所以實(shí)際上 far 一共有 16 個(gè)二進(jìn)制位,并不是 10 個(gè),且 11~15 的二進(jìn)制位也是 0。
基于這種情況,當(dāng)指定的二進(jìn)制位偏移量過大時(shí),Redis 需要一次性分配完所有內(nèi)存,這可能會(huì)造成 Redis 服務(wù)器阻塞。比如存儲(chǔ)用戶的性別,1 代表男性,0 代表女性,使用 ID 作為二進(jìn)制偏移量,如果 ID 從 10000000001 開始的,就需要將用戶 ID 減去 10000000000 再進(jìn)行存儲(chǔ),否則會(huì)造成內(nèi)存浪費(fèi)。
使用 GETBIT 命令可以獲取位圖指定偏移量上的二進(jìn)制位的值。此命令的時(shí)間復(fù)雜度是 O(1)。
GETBIT key offset
如果輸入的偏移量超過了位圖目前擁有的最大偏移量,將返回 0 作為結(jié)果。
通過 BITCOUNT 命令可以統(tǒng)計(jì)位圖中值為 1 的二進(jìn)制位數(shù)量。此命令的時(shí)間復(fù)雜度是 O(n)。
BITCOUNT key [start end]
在默認(rèn)情況下,BITCOUNT 命令對位圖包含的所有字節(jié)中的二進(jìn)制位進(jìn)行統(tǒng)計(jì),也可以通過可選的 start 參數(shù)和 end 參數(shù),讓 BITCOUNT 只對指定字節(jié)范圍內(nèi)的二進(jìn)制位進(jìn)行統(tǒng)計(jì)(不是二進(jìn)制偏移量)。比如,希望統(tǒng)計(jì) ar 兩個(gè)字節(jié)中值為 1 的二進(jìn)制數(shù)量:
redis> bitcount foo 1 2 (integer) 7
start 和 end 參數(shù)也支持使用負(fù)數(shù)索引,下方的用法與上方的等效:
redis> bitcount foo -2 -1 (integer) 7
通過執(zhí)行 BITPOS 命令,在位圖中查找第一個(gè)被設(shè)置為指定值的二進(jìn)制位,并返回這個(gè)二進(jìn)制位的偏移量。
BITPOS key value [start end]
BITPOS 也接受可選的 start 參數(shù)和 end 參數(shù),讓 BITPOS 命令只在指定字節(jié)范圍內(nèi)的二進(jìn)制位中進(jìn)行查找。
redis> get foo"aar"redis> bitpos foo 1 (integer) 1 redis> bitpos foo 0 (integer) 0 redis> bitpos foo 0 1 2 (integer) 8 redis> bitpos foo 1 1 2 (integer) 9 redis> bitpos foo 1 -1 -1 (integer) 17
針對邊界的處理:
當(dāng)嘗試對一個(gè)不存在的位圖或者一個(gè)所有位都被設(shè)置成了 0 的位圖中查找值為 1 的二進(jìn)制位時(shí),BITPOS 命令將返回 -1 作為結(jié)果。
如果在一個(gè)所有位都被設(shè)置成 1 的位圖中查找值為 0 的二進(jìn)制位,那么 BITPOS 命令將返回位圖最大偏移量加上 1 作為結(jié)果
通過 BITOP 命令,對一個(gè)或多個(gè)位圖執(zhí)行指定的二進(jìn)制位運(yùn)算,并將運(yùn)算結(jié)果存儲(chǔ)到指定的鍵中。
BITOP operation destkey key [key ...]
operation 參數(shù)的值可以是 AND、OR、XOR、NOT 中的任意一個(gè),這 4 個(gè)值分別對應(yīng)邏輯并、邏輯或、邏輯異或和邏輯非 4 種運(yùn)算,其中 AND、OR、XOR 這 3 種運(yùn)算允許用戶使用任意數(shù)量的位圖作為輸入,而 NOT 運(yùn)算只允許使用一個(gè)位圖作為輸入。BITOP 命令在將計(jì)算結(jié)果存儲(chǔ)到指定鍵中之后,會(huì)返回被存儲(chǔ)位圖的字節(jié)長度。
當(dāng) BITOP 命令在對兩個(gè)長度不同的位圖執(zhí)行運(yùn)算時(shí),會(huì)將長度較短的那個(gè)位圖中不存在的二進(jìn)制位的值看作 0。
redis> set foo1 bar OK redis> set foo2 aar OK redis> bitop or res foo1 foo2 (integer) 3 redis> get res"car"
注意:BITOP 可能是一個(gè)緩慢的命令,它的時(shí)間復(fù)雜度是 O(N),在處理長字符串時(shí)應(yīng)注意一下效率問題。
用用戶 ID 作為偏移量,若用戶做了某種行為則通過 SETBIT 將二進(jìn)制位設(shè)置為 1,通過 GETBIT 判斷用戶是否做了某種行為,通過 BITCOUNT 可以知道有多少用戶執(zhí)行了行為。
可以使用 SETBIT 和 BITCOUNT 來實(shí)現(xiàn),以用戶 ID 作為 key ,假設(shè)今天是上線統(tǒng)計(jì)功能開放的第一天,ID 為 1 的用戶上線后就通過 SETBIT 1 0 1。當(dāng)要計(jì)算此用戶的總共以來的上線次數(shù)時(shí),使用 BITCOUNT 命令就可以得出的結(jié)果。
使用這種方式存儲(chǔ)數(shù)據(jù),即使 10 年后,1個(gè)用戶就只占用幾百字節(jié)的內(nèi)存,它的處理速度依然很快。如果 bitmap 數(shù)據(jù)比較大,建議將 bitmap 拆分成多個(gè)小的 bitmap 分別進(jìn)行處理。
到此,相信大家對“Redis中的bitmap是什么”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。