日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Redisbitmap位圖操作(圖解)
在平時開發(fā)過程中,經(jīng)常會有一些 bool 類型數(shù)據(jù)需要存取。比如記錄用戶一年內(nèi)簽到的次數(shù),簽了是 1,沒簽是 0。如果使用 key-value 來存儲,那么每個用戶都要記錄 365 次,當(dāng)用戶成百上億時,需要的存儲空間將非常巨大。為了解決這個問題,Redis 提供了位圖結(jié)構(gòu)。

位圖(bitmap)同樣屬于 string 數(shù)據(jù)類型。Redis 中一個字符串類型的值最多能存儲 512 MB 的內(nèi)容,每個字符串由多個字節(jié)組成,每個字節(jié)又由 8 個 Bit 位組成。位圖結(jié)構(gòu)正是使用“位”來實現(xiàn)存儲的,它通過將比特位設(shè)置為 0 或 1來達(dá)到數(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。最后會生成 11010101... 這樣的存儲結(jié)果,其中每天的記錄只占一位,一年就是 365 位,約為 46 個字節(jié)。如果只想統(tǒng)計用戶簽到的天數(shù),那么統(tǒng)計 1 的個數(shù)即可。

位圖操作的優(yōu)勢,相比于字符串而言,它不僅效率高,而且還非常的節(jié)省空間。

Redis  的位數(shù)組是自動擴展的,如果設(shè)置了某個偏移位置超出了現(xiàn)有的內(nèi)容范圍,位數(shù)組就會自動擴充。

下面設(shè)置一個名為 a 的 key,我們對這個 key 進行位圖操作,使得 a 的對應(yīng)的 value 變?yōu)椤癶e”。

首先我們分別獲取字符“h”和字符“e”的八位二進制碼,如下所示:

>>> bin(ord("h"))
'0b1101000'
>>> bin(ord("e"))
'0b1100101'

接下來,只要對需值為 1 的位進行操作即可。如下圖所示:

把 h 和 e 的二進制碼連接在一起,第一位的下標(biāo)是 0,依次遞增至 15,然后將數(shù)字為 1 的位置標(biāo)記出來,得到 1/2/4/9/10/13/15,我們把這組數(shù)字稱為位的“偏置數(shù)”,最后按照上述偏置數(shù)對字符 a 進行如下位圖操作。注意,key 的初始二進制位全部為 0。

C:\Users\Administrator>redis-cli
127.0.0.1:6379> SETBIT a 1 1
(integer) 0
127.0.0.1:6379> SETBIT a 2 1
(integer) 0
127.0.0.1:6379> SETBIT a 4 1
(integer) 0
127.0.0.1:6379> get hello
"h"
127.0.0.1:6379> SETBIT a 9 1
(integer) 0
127.0.0.1:6379> SETBIT a 10 1
(integer) 0
127.0.0.1:6379> SETBIT a 13 1
(integer) 0
127.0.0.1:6379> SETBIT a 15 1
(integer) 0
127.0.0.1:6379> get hello
"he"

從上述示例可以得出,位圖操作會自動對 key 進行擴容。

如果對應(yīng)位的字節(jié)是不可以被打印的,那么 Redis 會以該字符的十六進制數(shù)來表示它,如下所示:

127.0.0.1:6379> SETBIT b 0 1
(integer) 0
127.0.0.1:6379> SETBIT b 1 1
(integer) 0
127.0.0.1:6379> get b
"\xc0"

位圖常用命令

1) SETBIT命令

用來設(shè)置或者清除某一位上的值,其返回值是原來位上存儲的值。key 在初始狀態(tài)下所有的位都為 0 ,語法格式如下:

SETBIT key offset value

其中 offset 表示偏移量,從 0 開始。示例如下:

127.0.0.1:6379> SET user:1 a
OK
#設(shè)置偏移量為0
127.0.0.1:6379> SETBIT user:1 0 1
(integer) 0
#當(dāng)對應(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

當(dāng)偏移量 offset 比字符串的長度大,或者當(dāng) 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ù)類似,都可以使用負(fù)數(shù),比如 -1 表示倒數(shù)第一個位, -2 表示倒數(shù)第二個位。

在線練習(xí)工具:https://try.redis.io/

查看更多命令:https://redis.io/commands


網(wǎng)頁名稱:Redisbitmap位圖操作(圖解)
新聞來源:http://www.dlmjj.cn/article/dpohhds.html