您好,登錄后才能下訂單哦!
本篇內容介紹了“bitmap的相關命令有哪些”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
1.使用場景
用戶上線次數統計、統計活躍用戶,簽到,點贊等具有標識性功能
2.原理
就是通過一個bit位來表示某個元素對應的值或者狀態,其中的key就是對應元素本身,是bit不是byte,1byte=8bit,優點凸顯,就是賊雞兒省空間
空間占用、以及第一次分配空間需要的時間
在一臺2010MacBook Pro上,offset為2^32-1(分配512MB)需要~300ms,offset為2^30-1(分配128MB)需要~80ms,offset為2^28-1(分配32MB)需要~30ms,offset為2^26-1(分配8MB)需要8ms。<來自官方文檔>
大概的空間占用計算公式是:($offset/8/1024/1024)MB)
說起來bitmap不能算為一種新數據類型,只是set的擴展
3.命令
命令 | 作用 |
setbit | 設置Bitmap的值 |
getbit | 獲取Bitmap的值 |
bitcount | 獲取指定范圍內值為1的個數 |
destkey | 對Bitmap做操作,可以是and(交集),or(并集),not(非集)或者xor(異或) |
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 作為輸入 |
BITPOS | BITPOS key bit [start][end] 返回字符串里面第一個被設置為 1 或者 0 的bit位。 |
BITFIELD | BITFIELD key [GET type offset][SET type offset value][INCRBY type offset increment][OVERFLOW WRAP|SAT|FAIL] |
溢出控制
用戶可以通過 OVERFLOW 命令以及以下展示的三個參數, 指定 BITFIELD 命令在執行自增或者自減操作時, 碰上向上溢出(overflow)或者向下溢出(underflow)情況時的行為:
WRAP :使用回繞(wrap around)方法處理有符號整數和無符號整數的溢出情況。對于無符號整數來說, 回繞就像使用數值本身與能夠被儲存的最大無符號整數執行取模計算, 這也是 C 語言的標準行為。對于有符號整數來說, 上溢將導致數字重新從最小的負數開始計算, 而下溢將導致數字重新從最大的正數開始計算。比如說, 如果我們對一個值為 127 的 i8 整數執行加一操作, 那么將得到結果 -128 。
SAT :使用飽和計算(saturation arithmetic)方法處理溢出, 也即是說, 下溢計算的結果為最小的整數值, 而上溢計算的結果為最大的整數值。舉個例子, 如果我們對一個值為 120 的 i8 整數執行加 10 計算, 那么命令的結果將為 i8 類型所能儲存的最大整數值 127 。與此相反, 如果一個針對 i8 值的計算造成了下溢, 那么這個 i8 值將被設置為 -127 。
FAIL :在這一模式下, 命令將拒絕執行那些會導致上溢或者下溢情況出現的計算, 并向用戶返回空值表示計算未被執行。
需要注意的是, OVERFLOW 子命令只會對緊隨著它之后被執行的 INCRBY 命令產生效果, 這一效果將一直持續到與它一同被執行的下一個 OVERFLOW 命令為止。在默認情況下, INCRBY 命令使用 WRAP 方式來處理溢出計算。
4.優點
省空間
5.缺點
暫無,雖然一個標識位只能記錄一個用戶,那也夠用了畢竟你沒有2^32-1的數據量
6.實現場景點贊
新增redis方法setbit
//bitmap/** * Sets the bit at {@code offset} in value stored at {@code key}. * * @param key must not be {@literal null}. * @param offset * @param value * @since 1.5 * @see <a href="http://redis.io/commands/setbit">Redis Documentation: SETBIT</a> */Boolean setBit(K key, long offset, boolean value);/** setbit* */public Boolean setBitMap(String key,long commentDatailId,boolean value){return redisTemplate.opsForValue().setBit(key,commentDatailId,value);}
在命令中value是標識1或0的,也就是true/false對應值
key:設置的key,比如日活,簽到,就用時間+id,那標識點贊未點贊就用信息id即可
offset:即所占標識位,一看就想起來偏移量
value:設置0/1
Boolean :返回0或1來標識是否
boolean flag = redisService.setBitMap(userIdStr,commentDetailId,true);
以前的邏輯不變set之前判斷是否存在
if(redisService.getBitMap(userIdStr,commentDetailId)){ redisService.setBitMap(userIdStr,commentDetailId,true);}else{ redisService.setBitMap(userIdStr,commentDetailId,false);}
問題:如果我的id很大或者是uuid開始呢?
正常的id是不會的,但uuid有可能,如果是uuid可以使用uuid減去初始位來進行放置
實現場景大數據量黑名單
此業務適合大數據量業務存儲的占用空間問題,而且基于redis速度不用擔心
日活統計
bitop and time moday thurday
1.節約空間,統計一億人每天的登錄情況,用一億bit,約1200WByte,約10M的字符就能表示(因為bitop命令的返回值是保存到 time中的字符串的長度(以字節byte為單位),和輸入 key 中最長的字符串長度相等。即1億除以8bit=1250萬Byte);
2.計算方便
性能:
??如果你的 bitmap 數據非常大,那么可以考慮使用以下兩種方法:
● 將一個大的 bitmap 分散到不同的 key 中,作為小的 bitmap 來處理。使用 Lua 腳本可以很方便地完成這一工作。
● 使用 BITCOUNT 的 start 和 end 參數,每次只對所需的部分位進行計算,將位的累積工作(accumulating)放到客戶端進行,并且對結果進行緩存 (caching)。
何時使用:
??如果活躍用戶在百萬級別,使用Redis BitMap很劃算。
??如果活躍用戶很少,而用戶id都是10位以上的int。那就很浪費內存了,還不如使用set集合,然后求交集就可以了。
“bitmap的相關命令有哪些”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。