在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何利用SpringBoot+Redis BitMap實現簽到與統計功能?

數據分析與開發 ? 來源:CSDN ? 2023-10-25 16:41 ? 次閱讀

引言

在各個項目中,我們都可能需要用到簽到和 統計功能。簽到后會給用戶一些禮品以此來吸引用戶持續在該平臺進行活躍。

簽到功能,我們可以通過Redis中的 BitMap功能來實現

一、Redis BitMap 基本用法

BitMap 基本語法、指令

簽到功能我們可以使用MySQL來完成,比如下表:

356e90ea-730f-11ee-939d-92fbcf53809c.png

用戶一次簽到,就是一條記錄,假如有1000萬用戶,平均每人每年簽到次數為10次,則這張表一年的數據量為 1億條

每簽到一次需要使用(8 + 8 + 1 + 1 + 3 + 1)共22 字節的內存,一個月則最多需要600多字節

這樣的壞處,占用內存太大了,極大的消耗內存空間!

我們可以根據 Redis中 提供的 BitMap 位圖功能來實現,每次簽到與未簽到用0 或1 來標識 ,一次存31個數字,只用了2字節 這樣我們就用極小的空間實現了簽到功能

BitMap 的操作指令:

SETBIT:向指定位置(offset)存入一個0或1

GETBIT:獲取指定位置(offset)的bit值

BITCOUNT:統計BitMap中值為1的bit位的數量

BITFIELD:操作(查詢、修改、自增)BitMap中bit數組中的指定位置(offset)的值

BITFIELD_RO:獲取BitMap中bit數組,并以十進制形式返回

BITOP:將多個BitMap的結果做位運算(與 、或、異或)

BITPOS:查找bit數組中指定范圍內第一個0或1出現的位置

使用 BitMap 完成功能實現

服務器Redis版本采用 6.2

進入redis查詢 SETBIT 命令

35858bb0-730f-11ee-939d-92fbcf53809c.png

新增key 進行存儲

358d90d0-730f-11ee-939d-92fbcf53809c.png

查詢 GETBIT命令

359bdae6-730f-11ee-939d-92fbcf53809c.png

查看指定坐標的簽到狀態

35a6d612-730f-11ee-939d-92fbcf53809c.png

查詢 BITFIELD

35b5189e-730f-11ee-939d-92fbcf53809c.png

無符號查詢

35be7f06-730f-11ee-939d-92fbcf53809c.png

BITPOS 查詢1 和 0 第一次出現的坐標

35cc7638-730f-11ee-939d-92fbcf53809c.png

二、SpringBoot 整合 Redis 實現簽到 功能

需求介紹

采用BitMap實現簽到功能

實現簽到接口,將當前用戶當天簽到信息保存到Redis中

思路分析:

我們可以把 年和月 作為BitMap的key,然后保存到一個BitMap中,每次簽到就到對應的位上把數字從0 變為1,只要是1,就代表是這一天簽到了,反之咋沒有簽到。

實現簽到接口,將當前用戶當天簽到信息保存至Redis中

35d70fb2-730f-11ee-939d-92fbcf53809c.png

提示:因為BitMap 底層是基于String數據結構,因此其操作都封裝在字符串操作中了。

35e1b368-730f-11ee-939d-92fbcf53809c.png

核心源碼

UserController

@PostMapping("sign")
publicResultsign(){
returnuserService.sign();
}

UserServiceImpl

publicResultsign(){
//1.獲取登錄用戶
LonguserId=UserHolder.getUser().getId();
//2.獲取日期
LocalDateTimenow=LocalDateTime.now();
//3.拼接key
StringkeySuffix=now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
Stringkey=RedisConstants.USER_SIGN_KEY+userId+keySuffix;
//4.獲取今天是本月的第幾天
intdayOfMonth=now.getDayOfMonth();
//5.寫入redissetbitkeyoffset1
stringRedisTemplate.opsForValue().setBit(key,dayOfMonth-1,true);
returnResult.ok();
}

接口進行測試

ApiFox進行測試

35ec24a6-730f-11ee-939d-92fbcf53809c.png

查看Redis 數據

35f0c25e-730f-11ee-939d-92fbcf53809c.png

三、SpringBoot 整合Redis 實現 簽到統計功能

問題一:什么叫做連續簽到天數?

從最后一次簽到開始向前統計,直到遇到第一次未簽到為止,計算總的簽到次數,就是連續簽到天數。

35fb3180-730f-11ee-939d-92fbcf53809c.png

邏輯分析:

獲得當前這個月的最后一次簽到數據,定義一個計數器,然后不停的向前統計,直到獲得第一個非0的數字即可,每得到一個非0的數字計數器+1,直到遍歷完所有的數據,就可以獲得當前月的簽到總天數了

問題二:如何得到本月到今天為止的所有簽到數據?

BITFIELDkeyGETu[dayOfMonth]0

假設今天是7號,那么我們就可以從當前月的第一天開始,獲得到當前這一天的位數,是7號,那么就是7位,去拿這段時間的數據,就能拿到所有的數據了,那么這7天里邊簽到了多少次呢?統計有多少個1即可。

問題三:如何從后向前遍歷每個Bit位?

注意:bitMap返回的數據是10進制,哪假如說返回一個數字8,那么我哪兒知道到底哪些是0,哪些是1呢?

我們只需要讓得到的10進制數字和1做與運算就可以了,因為1只有遇見1 才是1,其他數字都是0 ,我們把簽到結果和1進行與操作,每與一次,就把簽到結果向右移動一位,依次內推,我們就能完成逐個遍歷的效果了。

需求:

實現以下接口,統計當前截至當前時間在本月的連續天數

3601bcda-730f-11ee-939d-92fbcf53809c.png

有用戶有時間我們就可以組織出對應的key,此時就能找到這個用戶截止這天的所有簽到記錄,再根據這套算法,就能統計出來他連續簽到的次數了

核心源碼

UserController

@GetMapping("/signCount")
publicResultsignCount(){
returnuserService.signCount();
}

UserServiceImpl

publicResultsignCount(){
//1.獲取登錄用戶
LonguserId=UserHolder.getUser().getId();
//2.獲取日期
LocalDateTimenow=LocalDateTime.now();
//3.拼接key
StringkeySuffix=now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
Stringkey=RedisConstants.USER_SIGN_KEY+userId+keySuffix;
//4.獲取今天是本月的第幾天
intdayOfMonth=now.getDayOfMonth();
//5.獲取本月截至今天為止的所有的簽到記錄,返回的是一個十進制的數字BITFIELDsign202301GETu30
Listresult=stringRedisTemplate.opsForValue().bitField(
key,
BitFieldSubCommands.create()
.get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)).valueAt(0));
//沒有任務簽到結果
if(result==null||result.isEmpty()){
returnResult.ok(0);
}
Longnum=result.get(0);
if(num==null||num==0){
returnResult.ok(0);
}
//6.循環遍歷
intcount=0;
while(true){
//6.1讓這個數字與1做與運算,得到數字的最后一個bit位判斷這個數字是否為0
if((num&1)==0){
//如果為0,簽到結束
break;
}else{
count++;
}
num>>>=1;
}
returnResult.ok(count);
}

進行測試

3613f5f8-730f-11ee-939d-92fbcf53809c.png

查看 Redis 變量

3618637c-730f-11ee-939d-92fbcf53809c.png

從今天開始,往前查詢 連續簽到的天數,結果為2 測試無誤!

四、關于使用bitmap來解決緩存穿透的方案

回顧緩存穿透:

發起了一個數據庫不存在的,redis里邊也不存在的數據,通常你可以把他看成一個攻擊

解決方案:

判斷id<0

數據庫為空的話,向redis里邊把這個空數據緩存起來

第一種解決方案:遇到的問題是如果用戶訪問的是id不存在的數據,則此時就無法生效

第二種解決方案:遇到的問題是:如果是不同的id那就可以防止下次過來直擊數據

所以我們如何解決呢?

我們可以將數據庫的數據,所對應的id寫入到一個list集合中,當用戶過來訪問的時候,我們直接去判斷list中是否包含當前的要查詢的數據,如果說用戶要查詢的id數據并不在list集合中,則直接返回,如果list中包含對應查詢的id數據,則說明不是一次緩存穿透數據,則直接放行。

362735f0-730f-11ee-939d-92fbcf53809c.png

現在的問題是這個主鍵其實并沒有那么短,而是很長的一個 主鍵

哪怕你單獨去提取這個主鍵,但是在 11年左右,淘寶的商品總量就已經超過10億個

所以如果采用以上方案,這個list也會很大,所以我們可以使用bitmap來減少list的存儲空間

我們可以把list數據抽象成一個非常大的bitmap,我們不再使用list,而是將db中的id數據利用哈希思想,比如:

id 求余bitmap長度 :id % bitmap.size = 算出當前這個id對應應該落在bitmap的哪個索引上,然后將這個值從0變成1,然后當用戶來查詢數據時,此時已經沒有了list,讓用戶用他查詢的id去用相同的哈希算法, 算出來當前這個id應當落在bitmap的哪一位,然后判斷這一位是0,還是1,如果是0則表明這一位上的數據一定不存在,采用這種方式來處理,需要重點考慮一個事情,就是誤差率,所謂的誤差率就是指當發生哈希沖突的時候,產生的誤差。

3638de72-730f-11ee-939d-92fbcf53809c.png

圖片

小結

以上就是對 微服務 Spring Boot 整合 Redis BitMap 實現 簽到與統計 的簡單介紹,簽到功能是很常用的,在項目中,是一個不錯的亮點,統計功能也是各大系統中比較重要的功能,簽到完成后,去統計本月的連續 簽到記錄,來給予獎勵,可大大增加用戶對系統的活躍度 技術改變世界!!!






審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • MySQL
    +關注

    關注

    1

    文章

    831

    瀏覽量

    26763
  • 邏輯分析
    +關注

    關注

    0

    文章

    14

    瀏覽量

    7994
  • Redis
    +關注

    關注

    0

    文章

    379

    瀏覽量

    10967

原文標題:SpringBoot+Redis BitMap 實現簽到與統計功能

文章出處:【微信號:DBDevs,微信公眾號:數據分析與開發】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    Redis實戰篇-16.用戶簽到-實現簽到功能

    Redis
    電子學習
    發布于 :2023年01月07日 16:50:46

    Redis有序集合詳細步驟

    利用Redis Sorted Set實現排行榜功能
    發表于 05-21 14:09

    基于SpringBoot mybatis方式的增刪改查實現

    SpringBoot mybatis方式實現增刪改查
    發表于 06-18 16:56

    在 Java 中利用 redis 實現一個分布式鎖服務

    在 Java 中利用 redis 實現一個分布式鎖服務
    發表于 07-05 13:14

    Spring boot中Redis的使用

    【本人禿頂程序員】springboot專輯:Spring boot中Redis的使用
    發表于 03-27 11:42

    淺析Redis的5種基本數據類型

    多余的話不多說,今天給大家帶來的是 Redis 中的四種特殊的數據結構 bitmap,hyperLogLog,bloomFilter,GeoHash 。這四種數據結構其實有點類似于算法層面了,比如 GeoHash 其實就是一個 zset,
    的頭像 發表于 05-05 23:44 ?2743次閱讀
    淺析<b class='flag-5'>Redis</b>的5種基本數據類型

    Springboot+redis操作多種實現

    一、Jedis,Redisson,Lettuce三者的區別共同點:都提供了基于Redis操作的Java API,只是封裝程度,具體實現稍有不同。 不同點: 1.1、Jedis 是Redis的Java
    的頭像 發表于 09-22 10:48 ?1883次閱讀
    <b class='flag-5'>Springboot+redis</b>操作多種<b class='flag-5'>實現</b>

    SpringBoot實現多線程

    SpringBoot實現多線程
    的頭像 發表于 01-12 16:59 ?1900次閱讀
    <b class='flag-5'>SpringBoot</b><b class='flag-5'>實現</b>多線程

    SpringBoot+Redis實現點贊功能的緩存和定時持久化(附源碼)

    用戶對瀏覽內容進行【點贊/取贊】,并發送【點贊/取贊】請求到后端,這些信息先存入Redis中緩存,再每隔兩小時將Redis中的內容直接寫入數據庫持久化存儲。
    的頭像 發表于 02-09 16:38 ?4673次閱讀

    Redis實現限流的三種方式分享

    當然,限流有許多種實現的方式,Redis具有很強大的功能,我用Redis實踐了三種的實現方式,可以較為簡單的
    的頭像 發表于 02-22 09:52 ?1138次閱讀

    基于SpringBoot+Redis的轉盤抽獎

    基于SpringBoot+Redis等技術實現轉盤抽獎活動項目,含前端、后臺及數據庫文件
    的頭像 發表于 02-28 14:24 ?1624次閱讀
    基于<b class='flag-5'>SpringBoot+Redis</b>的轉盤抽獎

    如何在SpringBoot中解決Redis的緩存穿透等問題

    今天給大家介紹一下如何在SpringBoot中解決Redis的緩存穿透、緩存擊穿、緩存雪崩的問題。
    的頭像 發表于 04-28 11:35 ?778次閱讀

    如何用Springboot整合Redis

    本篇文件我們來介紹如何用Springboot整合Redis。 1、Docker 安裝 Redis 1.1 下載鏡像 docker pull redis: 6 . 2 . 6 1.2 創
    的頭像 發表于 10-08 14:56 ?636次閱讀
    如何用<b class='flag-5'>Springboot</b>整合<b class='flag-5'>Redis</b>

    SpringBoot AOP + Redis 延時雙刪功能實戰

    注意:要知道經常修改的數據表不適合使用Redis,因為雙刪策略執行的結果是把Redis中保存的那條數據刪除了,以后的查詢就都會去查詢數據庫。所以Redis使用的是讀遠遠大于改的數據緩存。
    的頭像 發表于 10-13 16:08 ?687次閱讀
    <b class='flag-5'>SpringBoot</b> AOP + <b class='flag-5'>Redis</b> 延時雙刪<b class='flag-5'>功能</b>實戰

    一個注解搞定SpringBoot接口防刷

    技術要點:springboot的基本知識,redis基本操作,
    的頭像 發表于 11-28 10:46 ?439次閱讀
    主站蜘蛛池模板: 日本一道高清不卡免费 | 全色网站 | 伊人成伊人成综合网2222 | 久久久黄色片 | 欧美人与牲动交xxxxbbbb | 天天操天天干天天舔 | 午夜一区二区三区 | 久久人人视频 | 四虎免费久久影院 | 毛片录像 | 久优草 | 午夜免费福利片 | freesex性| 亚洲精品一卡2卡3卡三卡四卡 | 亚洲婷婷六月 | 亚洲四虎 | 未满十八18周岁禁止免费国产 | 日本免费一区二区三区视频 | 黄黄的网站在线观看 | 黑人40厘米全进去xxxx猛交 | 亚洲三级成人 | 色综合天天色 | 中文字幕在线天堂 | 亚洲大尺度视频 | 五月婷婷丁香综合网 | 天堂精品在线 | 国产精品你懂得 | 色秀视频免费网站在线观看 | 成人欧美一区二区三区黑人3p | 老司机亚洲精品影院在线观看 | 免费一级欧美在线观看视频片 | www.久色| 欧美精品一区二区三区在线播放 | 尻美女视频| 99香蕉国产 | 日韩精品卡4卡5卡6卡7卡 | 在线视频图片小说 | 亚洲影院手机版777点击进入影院 | 欧美亚洲综合另类成人 | 亚洲精品精品一区 | 婷婷日日夜夜 |