国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

微服務—Redis實用篇-黑馬頭條項目用戶簽到功能(使用bitmap實現(xiàn))與UV統(tǒng)計

這篇具有很好參考價值的文章主要介紹了微服務—Redis實用篇-黑馬頭條項目用戶簽到功能(使用bitmap實現(xiàn))與UV統(tǒng)計。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

微服務—Redis實用篇-黑馬頭條項目用戶簽到功能(使用bitmap實現(xiàn))與UV統(tǒng)計

1、用戶簽到

1.1、用戶簽到-BitMap功能演示

我們針對簽到功能完全可以通過mysql來完成,比如說以下這張表

微服務—Redis實用篇-黑馬頭條項目用戶簽到功能(使用bitmap實現(xiàn))與UV統(tǒng)計

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

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

我們?nèi)绾文軌蚝喕稽c呢?其實可以考慮小時候一個挺常見的方案,就是小時候,咱們準備一張小小的卡片,你只要簽到就打上一個勾,我最后判斷你是否簽到,其實只需要到小卡片上看一看就知道了

我們可以采用類似這樣的方案來實現(xiàn)我們的簽到需求。

我們按月來統(tǒng)計用戶簽到信息,簽到記錄為1,未簽到則記錄為0.

把每一個bit位對應當月的每一天,形成了映射關系。用0和1標示業(yè)務狀態(tài),這種思路就稱為位圖(BitMap)。這樣我們就用極小的空間,來實現(xiàn)了大量數(shù)據(jù)的表示

Redis中是利用string類型數(shù)據(jù)結構實現(xiàn)BitMap,因此最大上限是512M,轉換為bit則是 2^32個bit位。

微服務—Redis實用篇-黑馬頭條項目用戶簽到功能(使用bitmap實現(xiàn))與UV統(tǒng)計

BitMap的操作命令有:

  • SETBIT:向指定位置(offset)存入一個0或1
  • GETBIT :獲取指定位置(offset)的bit值
  • BITCOUNT :統(tǒng)計BitMap中值為1的bit位的數(shù)量
  • BITFIELD :操作(查詢、修改、自增)BitMap中bit數(shù)組中的指定位置(offset)的值
  • BITFIELD_RO :獲取BitMap中bit數(shù)組,并以十進制形式返回
  • BITOP :將多個BitMap的結果做位運算(與 、或、異或)
  • BITPOS :查找bit數(shù)組中指定范圍內(nèi)第一個0或1出現(xiàn)的位置
1.2 、用戶簽到-實現(xiàn)簽到功能

需求:實現(xiàn)簽到接口,將當前用戶當天簽到信息保存到Redis中

思路:我們可以把年和月作為bitMap的key,然后保存到一個bitMap中,每次簽到就到對應的位上把數(shù)字從0變成1,只要對應是1,就表明說明這一天已經(jīng)簽到了,反之則沒有簽到。

我們通過接口文檔發(fā)現(xiàn),此接口并沒有傳遞任何的參數(shù),沒有參數(shù)怎么確實是哪一天簽到呢?這個很容易,可以通過后臺代碼直接獲取即可,然后到對應的地址上去修改bitMap。

微服務—Redis實用篇-黑馬頭條項目用戶簽到功能(使用bitmap實現(xiàn))與UV統(tǒng)計

代碼

UserController

 @PostMapping("/sign")
 public Result sign(){
    return userService.sign();
 }

UserServiceImpl

@Override
public Result sign() {
    // 1.獲取當前登錄用戶
    Long userId = UserHolder.getUser().getId();
    // 2.獲取日期
    LocalDateTime now = LocalDateTime.now();
    // 3.拼接key
    String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
    String key = USER_SIGN_KEY + userId + keySuffix;
    // 4.獲取今天是本月的第幾天
    int dayOfMonth = now.getDayOfMonth();
    // 5.寫入Redis SETBIT key offset 1
    stringRedisTemplate.opsForValue().setBit(key, dayOfMonth - 1, true);
    return Result.ok();
}
1.3 用戶簽到-簽到統(tǒng)計

**問題1:**什么叫做連續(xù)簽到天數(shù)?
從最后一次簽到開始向前統(tǒng)計,直到遇到第一次未簽到為止,計算總的簽到次數(shù),就是連續(xù)簽到天數(shù)。

微服務—Redis實用篇-黑馬頭條項目用戶簽到功能(使用bitmap實現(xiàn))與UV統(tǒng)計

Java邏輯代碼:獲得當前這個月的最后一次簽到數(shù)據(jù),定義一個計數(shù)器,然后不停的向前統(tǒng)計,直到獲得第一個非0的數(shù)字即可,每得到一個非0的數(shù)字計數(shù)器+1,直到遍歷完所有的數(shù)據(jù),就可以獲得當前月的簽到總天數(shù)了

**問題2:**如何得到本月到今天為止的所有簽到數(shù)據(jù)?

BITFIELD key GET u[dayOfMonth] 0

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

問題3:如何從后向前遍歷每個bit位?

注意:bitMap返回的數(shù)據(jù)是10進制,哪假如說返回一個數(shù)字8,那么我哪兒知道到底哪些是0,哪些是1呢?我們只需要讓得到的10進制數(shù)字和1做與運算就可以了,因為1只有遇見1 才是1,其他數(shù)字都是0 ,我們把簽到結果和1進行與操作,每與一次,就把簽到結果向右移動一位,依次內(nèi)推,我們就能完成逐個遍歷的效果了。

需求:實現(xiàn)下面接口,統(tǒng)計當前用戶截止當前時間在本月的連續(xù)簽到天數(shù)

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

微服務—Redis實用篇-黑馬頭條項目用戶簽到功能(使用bitmap實現(xiàn))與UV統(tǒng)計

代碼

UserController

@GetMapping("/sign/count")
public Result signCount(){
    return userService.signCount();
}

UserServiceImpl

@Override
public Result signCount() {
    // 1.獲取當前登錄用戶
    Long userId = UserHolder.getUser().getId();
    // 2.獲取日期
    LocalDateTime now = LocalDateTime.now();
    // 3.拼接key
    String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
    String key = USER_SIGN_KEY + userId + keySuffix;
    // 4.獲取今天是本月的第幾天
    int dayOfMonth = now.getDayOfMonth();
    // 5.獲取本月截止今天為止的所有的簽到記錄,返回的是一個十進制的數(shù)字 BITFIELD sign:5:202203 GET u14 0
    List<Long> result = stringRedisTemplate.opsForValue().bitField(
            key,
            BitFieldSubCommands.create()
                    .get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)).valueAt(0)
    );
    if (result == null || result.isEmpty()) {
        // 沒有任何簽到結果
        return Result.ok(0);
    }
    Long num = result.get(0);
    if (num == null || num == 0) {
        return Result.ok(0);
    }
    // 6.循環(huán)遍歷
    int count = 0;
    while (true) {
        // 6.1.讓這個數(shù)字與1做與運算,得到數(shù)字的最后一個bit位  // 判斷這個bit位是否為0
        if ((num & 1) == 0) {
            // 如果為0,說明未簽到,結束
            break;
        }else {
            // 如果不為0,說明已簽到,計數(shù)器+1
            count++;
        }
        // 把數(shù)字右移一位,拋棄最后一個bit位,繼續(xù)下一個bit位
        num >>>= 1;
    }
    return Result.ok(count);
}
1.4 額外加餐-關于使用bitmap來解決緩存穿透的方案

回顧緩存穿透

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

解決方案:

  • 判斷id<0

  • 如果數(shù)據(jù)庫是空,那么就可以直接往redis里邊把這個空數(shù)據(jù)緩存起來

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

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

所以我們?nèi)绾谓鉀Q呢?

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

微服務—Redis實用篇-黑馬頭條項目用戶簽到功能(使用bitmap實現(xiàn))與UV統(tǒng)計

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

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

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

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

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

微服務—Redis實用篇-黑馬頭條項目用戶簽到功能(使用bitmap實現(xiàn))與UV統(tǒng)計

2、UV統(tǒng)計

2.1 、UV統(tǒng)計-HyperLogLog

首先我們搞懂兩個概念:

  • UV:全稱Unique Visitor,也叫獨立訪客量,是指通過互聯(lián)網(wǎng)訪問、瀏覽這個網(wǎng)頁的自然人。1天內(nèi)同一個用戶多次訪問該網(wǎng)站,只記錄1次。
  • PV:全稱Page View,也叫頁面訪問量或點擊量,用戶每訪問網(wǎng)站的一個頁面,記錄1次PV,用戶多次打開頁面,則記錄多次PV。往往用來衡量網(wǎng)站的流量。

通常來說UV會比PV大很多,所以衡量同一個網(wǎng)站的訪問量,我們需要綜合考慮很多因素,所以我們只是單純的把這兩個值作為一個參考值

UV統(tǒng)計在服務端做會比較麻煩,因為要判斷該用戶是否已經(jīng)統(tǒng)計過了,需要將統(tǒng)計過的用戶信息保存。但是如果每個訪問的用戶都保存到Redis中,數(shù)據(jù)量會非常恐怖,那怎么處理呢?

Hyperloglog(HLL)是從Loglog算法派生的概率算法,用于確定非常大的集合的基數(shù),而不需要存儲其所有值。相關算法原理大家可以參考:https://juejin.cn/post/6844903785744056333#heading-0
Redis中的HLL是基于string結構實現(xiàn)的,單個HLL的內(nèi)存永遠小于16kb內(nèi)存占用低的令人發(fā)指!作為代價,其測量結果是概率性的,有小于0.81%的誤差。不過對于UV統(tǒng)計來說,這完全可以忽略。

微服務—Redis實用篇-黑馬頭條項目用戶簽到功能(使用bitmap實現(xiàn))與UV統(tǒng)計

2.2 UV統(tǒng)計-測試百萬數(shù)據(jù)的統(tǒng)計

測試思路:我們直接利用單元測試,向HyperLogLog中添加100萬條數(shù)據(jù),看看內(nèi)存占用和統(tǒng)計效果如何

微服務—Redis實用篇-黑馬頭條項目用戶簽到功能(使用bitmap實現(xiàn))與UV統(tǒng)計

經(jīng)過測試:我們會發(fā)生他的誤差是在允許范圍內(nèi),并且內(nèi)存占用極小文章來源地址http://www.zghlxwxcb.cn/news/detail-451414.html

到了這里,關于微服務—Redis實用篇-黑馬頭條項目用戶簽到功能(使用bitmap實現(xiàn))與UV統(tǒng)計的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 黑馬頭條 SpringBoot+SpringCloud+ Nacos等企業(yè)級微服務架構項目

    黑馬頭條 SpringBoot+SpringCloud+ Nacos等企業(yè)級微服務架構項目

    各位爺,完整項目gitee如下,求star heima-leadnews-master: 《黑馬頭條》項目采用的是SpringBoot+springcloud當下最流行的微服務為項目架構,配合spring cloud alibaba nacos作為項目的注冊和配置中心。新課程采用快速開發(fā)的模式,主要解決真實企業(yè)開發(fā)的一些應用場景。詳情請看博客:htt

    2024年02月08日
    瀏覽(27)
  • 新黑馬頭條項目經(jīng)驗(黑馬)

    新黑馬頭條項目經(jīng)驗(黑馬)

    ? ? (1)簡介 Swagger 是一個規(guī)范和完整的框架,用于生成、描述、調(diào)用和可視化 RESTful 風格的 Web 服務(API Documentation Design Tools for Teams | Swagger)。 它的主要作用是: 使得前后端分離開發(fā)更加方便,有利于團隊協(xié)作 接口的文檔在線自動生成,降低后端開發(fā)人員編寫接口文檔的負擔

    2024年02月02日
    瀏覽(23)
  • 面試項目-黑馬頭條-項目介紹

    面試項目-黑馬頭條-項目介紹

    B站視頻黑馬頭條視頻學習總結,侵權請聯(lián)系刪除 1.1 項目背景 隨著智能手機的普及,人們更加習慣于通過手機來看新聞。由于生活節(jié)奏的加快,很多人只能利用碎片時間來獲取信息,因此,對于移動資訊客戶端的需求也越來越高。黑馬頭條項目正是在這樣背景下開發(fā)出來。黑

    2024年02月09日
    瀏覽(25)
  • 黑馬頭條項目經(jīng)驗&BUG

    黑馬頭條項目經(jīng)驗&BUG

    同樣是配置文件,但與application.yml有所不同 bootstrap.yml的加載比application.yml早 bootstrap.yml作用范圍更廣,可以被多個應用程序共享(可以在每個服務的application.yml中配置 spring: cloud: config: (name)url ,從而配置bootstrap.yml的位置) bootstrap.yml具有更高的優(yōu)先級,可以覆蓋application.y

    2024年02月14日
    瀏覽(18)
  • AJAX——黑馬頭條-數(shù)據(jù)管理平臺項目

    AJAX——黑馬頭條-數(shù)據(jù)管理平臺項目

    功能: 登錄和權限判斷 查看文章內(nèi)容列表(篩選,分頁) 編輯文章(數(shù)據(jù)回顯) 刪除文章 發(fā)布文章(圖片上傳,富文本編輯器) 技術: 基于Bootstrap搭建網(wǎng)站標簽和樣式 集成wangEditor插件實現(xiàn)富文本編輯器 使用原生JS完成增刪改查等業(yè)務 基于axios與黑馬頭條線上接口交互

    2024年04月27日
    瀏覽(17)
  • 【黑馬頭條之項目部署_持續(xù)集成Jenkins】

    【黑馬頭條之項目部署_持續(xù)集成Jenkins】

    本筆記內(nèi)容為黑馬頭條項目的項目部署_持續(xù)集成部分 目錄 一、內(nèi)容介紹 1、什么是持續(xù)集成 2、持續(xù)集成的好處 3、今日內(nèi)容 二、軟件開發(fā)模式 1、軟件開發(fā)生命周期 2、軟件開發(fā)瀑布模型 3、軟件的敏捷開發(fā) 三、Jenkins安裝配置 1、Jenkins介紹 2、Jenkins環(huán)境搭建 1.Jenkins安裝配置

    2024年02月10日
    瀏覽(22)
  • 黑馬頭條項目學習--Day3: 自媒體文章發(fā)布

    黑馬頭條項目學習--Day3: 自媒體文章發(fā)布

    自媒體后臺搭建 ①:資料中找到heima-leadnews-wemedia.zip解壓 拷貝到heima-leadnews-service工程下,并指定子模塊 執(zhí)行l(wèi)eadnews-wemedia.sql腳本 添加對應的nacos配置 ②:資料中找到heima-leadnews-wemedia-gateway.zip解壓 拷貝到heima-leadnews-gateway工程下,并指定子模塊 添加對應的nacos配置 圖片上傳的

    2024年02月13日
    瀏覽(74)
  • Redis【實戰(zhàn)篇】---- 用戶簽到

    Redis【實戰(zhàn)篇】---- 用戶簽到

    我們針對簽到功能完全可以通過mysql來完成,比如說以下這張表 用戶一次簽到,就是一條記錄,假如有1000萬用戶,平均每人每年簽到次數(shù)為10次,則這張表一年的數(shù)據(jù)量為 1億條 每簽到一次需要使用(8 + 8 + 1 + 1 + 3 + 1)共22 字節(jié)的內(nèi)存,一個月則最多需要600多字節(jié) 我們?nèi)绾文?/p>

    2024年02月12日
    瀏覽(23)
  • Redis - 附近商鋪、用戶簽到、UV統(tǒng)計

    Redis - 附近商鋪、用戶簽到、UV統(tǒng)計

    底層都是基于地理坐標進行搜索,支持地理坐標的技術有很多,Redis就是其中之一 GEO 就是Geolocation的簡寫形式,代表 地理坐標 。 Redis 在3.2版本中加入了對GEO的支持, 允許存儲地理坐標信息 ,幫助我們根據(jù)經(jīng)緯度來檢索數(shù)據(jù)。 常見的命令有 : GEOADD :添加一個地理空間信息,

    2024年02月13日
    瀏覽(21)
  • 小程序實現(xiàn)簽到打卡功能--用戶端

    小程序實現(xiàn)簽到打卡功能--用戶端

    一、實現(xiàn)需求 實現(xiàn)用戶在規(guī)定區(qū)域內(nèi)完成打卡操作并以日歷的形式記錄。 注:本篇文章能夠實現(xiàn)打卡記錄是建立在有后端接口傳輸返回的數(shù)據(jù)上 二、效果展示 三、業(yè)務邏輯 點擊打卡按鈕,打卡成功后彈出相應的彈窗,并在日歷記錄上留下當天打卡的痕跡。在規(guī)定區(qū)域內(nèi)打

    2024年02月08日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包