最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot+Redis Bitmap實(shí)現(xiàn)活躍用戶(hù)統(tǒng)計(jì)

 更新時(shí)間:2023年11月17日 10:40:25   作者:myprince003  
Redis的Bitmap數(shù)據(jù)結(jié)構(gòu)是一種緊湊的位圖,它可以用于實(shí)現(xiàn)各種場(chǎng)景,其中統(tǒng)計(jì)活躍用戶(hù)是一種經(jīng)典的業(yè)務(wù)場(chǎng)景,下面我們就來(lái)學(xué)習(xí)一下SpringBoot如何利用Redis中的Bitmap實(shí)現(xiàn)活躍用戶(hù)統(tǒng)計(jì)吧

前言

Redis的Bitmap數(shù)據(jù)結(jié)構(gòu)是一種緊湊的位圖,它可以用于實(shí)現(xiàn)各種場(chǎng)景,其中統(tǒng)計(jì)活躍用戶(hù)是一種經(jīng)典的業(yè)務(wù)場(chǎng)景。

實(shí)現(xiàn)原理是,通過(guò)將每個(gè)用戶(hù)表示為一個(gè)位,從而跟蹤用戶(hù)的活躍狀態(tài),使用位圖記錄用戶(hù)每天是否登錄,并計(jì)算月度或年度活躍用戶(hù)數(shù)。

案例代碼

以下是一個(gè)小例子,可以看到,使用SpringDataRedis,可以很輕松的實(shí)現(xiàn)BitMap的操作。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.BitSet;

@Service
public class UserLoginService {

    // 用戶(hù)登錄記錄的鍵前綴
    private static final String LOGIN_KEY_PREFIX = "login:"; 
    // 月份格式化器
    private static final DateTimeFormatter MONTH_FORMATTER = DateTimeFormatter.ofPattern("yyyyMM"); 
    // 年份格式化器
    private static final DateTimeFormatter YEAR_FORMATTER = DateTimeFormatter.ofPattern("yyyy"); 

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 記錄用戶(hù)登錄
     *
     * @param userId 用戶(hù)ID
     */
    public void recordLogin(String userId) {

        // 獲取存儲(chǔ)當(dāng)天用戶(hù)登錄信息的鍵
        String loginKey = getLoginKey(); 
        // 計(jì)算位圖偏移量,對(duì)應(yīng)用戶(hù)ID的哈希碼
        int bitOffset = getUserIdHashCode(userId); 
        // 將用戶(hù)ID對(duì)應(yīng)的位設(shè)置為1,表示用戶(hù)登錄
        redisTemplate.opsForValue().setBit(loginKey, bitOffset, true); 
    }

    /**
     * 獲取月度活躍用戶(hù)統(tǒng)計(jì)數(shù)據(jù)
     *
     * @return 月度活躍用戶(hù)統(tǒng)計(jì)數(shù)據(jù)
     */
    public BitSet getMonthlyActiveUsers() {

        // 獲取存儲(chǔ)月度活躍用戶(hù)信息的鍵
        String monthlyKey = getMonthlyKey(); 
        // 從Redis中獲取位圖數(shù)據(jù)
        return retrieveBitSet(monthlyKey); 
    }

    /**
     * 獲取年度活躍用戶(hù)統(tǒng)計(jì)數(shù)據(jù)
     *
     * @return 年度活躍用戶(hù)統(tǒng)計(jì)數(shù)據(jù)
     */
    public BitSet getYearlyActiveUsers() {

        // 獲取存儲(chǔ)年度活躍用戶(hù)信息的鍵
        String yearlyKey = getYearlyKey(); 
        // 從Redis中獲取位圖數(shù)據(jù)
        return retrieveBitSet(yearlyKey); 
    }

    /**
     * 獲取存儲(chǔ)當(dāng)天用戶(hù)登錄信息的鍵
     */
    private String getLoginKey() {

        LocalDate today = LocalDate.now();
        String dateKey = today.format(DateTimeFormatter.ISO_DATE);
        return LOGIN_KEY_PREFIX + dateKey;
    }

    /**
     * 計(jì)算用戶(hù)ID的哈希碼,保證非負(fù)數(shù)并適應(yīng)位圖長(zhǎng)度
     */
    private int getUserIdHashCode(String userId) {

        int hashCode = userId.hashCode();
        // 1073741823是Redis位圖最大支持長(zhǎng)度(2^30-1),可根據(jù)實(shí)際需求調(diào)整
        return Math.abs(hashCode % 1073741823); 
    }

    /**
     * 獲取存儲(chǔ)月度活躍用戶(hù)信息的鍵
     */
    private String getMonthlyKey() {

        LocalDate today = LocalDate.now();
        String monthKey = today.format(MONTH_FORMATTER);
        return LOGIN_KEY_PREFIX + "monthly:" + monthKey;
    }

    /**
     * 獲取存儲(chǔ)年度活躍用戶(hù)信息的鍵
     */
    private String getYearlyKey() {

        LocalDate today = LocalDate.now();
        String yearKey = today.format(YEAR_FORMATTER);
        return LOGIN_KEY_PREFIX + "yearly:" + yearKey;
    }

    /**
     * 從Redis中獲取位圖數(shù)據(jù)
     */
    private BitSet retrieveBitSet(String key) {

        // 獲取存儲(chǔ)在Redis中的位圖數(shù)據(jù)
        byte[] bytes = (byte[]) redisTemplate.opsForValue().get(key); 
        if (bytes != null) {
            // 將字節(jié)數(shù)組轉(zhuǎn)換為BitSet
            return BitSet.valueOf(bytes); 
        } else {
            // 若不存在,則返回空的BitSet
            return new BitSet(); 
        }
    }
}

其中有幾個(gè)地方解釋一下:

1、recordLogin方法用于記錄用戶(hù)登錄情況。每天的登錄情況被保存在以"login:日期"為鍵的位圖中,用戶(hù)的登錄狀態(tài)由位圖中對(duì)應(yīng)的位表示;

2、countMonthlyActiveUsers方法用于計(jì)算月度活躍用戶(hù)數(shù)量。每個(gè)月的活躍用戶(hù)數(shù)保存在以"login:monthly:年月"為鍵的位圖中,通過(guò)Redis的bitCount方法統(tǒng)計(jì)位圖中置為1的位數(shù),即月度活躍用戶(hù)數(shù);

3、ountYearlyActiveUsers方法用于計(jì)算年度活躍用戶(hù)數(shù)量,原理同上,只是統(tǒng)計(jì)的鍵變?yōu)?quot;login:yearly:年份";

4、getLoginKey、getUserIdHashCode、getMonthlyKey和getYearlyKey是輔助方法,負(fù)責(zé)生成對(duì)應(yīng)的Redis鍵或計(jì)算用戶(hù)ID的哈希碼。

轉(zhuǎn)換

上面的例子最終返回的是BitSet對(duì)象,通過(guò)這個(gè)對(duì)象我們經(jīng)過(guò)轉(zhuǎn)換后可以獲取到許多經(jīng)典的統(tǒng)計(jì)數(shù)據(jù),這里列舉一些經(jīng)典常用的統(tǒng)計(jì)結(jié)果示例。

大家可以根據(jù)這里面列舉的統(tǒng)計(jì)數(shù)據(jù),針對(duì)上面的代碼進(jìn)行替換,得到自己想要的結(jié)果。

import java.util.BitSet;

// 獲取月度活躍用戶(hù)統(tǒng)計(jì)數(shù)據(jù)
BitSet monthlyActiveUsers = userLoginService.getMonthlyActiveUsers();

// 獲取年度活躍用戶(hù)統(tǒng)計(jì)數(shù)據(jù)
BitSet yearlyActiveUsers = userLoginService.getYearlyActiveUsers();

// 統(tǒng)計(jì)月度活躍用戶(hù)數(shù)量
int monthlyActiveUserCount = monthlyActiveUsers.cardinality();

// 統(tǒng)計(jì)年度活躍用戶(hù)數(shù)量
int yearlyActiveUserCount = yearlyActiveUsers.cardinality();

// 判斷某個(gè)用戶(hù)是否為月度活躍用戶(hù)
String userId = "user123";
boolean isMonthlyActiveUser = monthlyActiveUsers.get(userLoginService.getUserIdHashCode(userId));

// 判斷某個(gè)用戶(hù)是否為年度活躍用戶(hù)
boolean isYearlyActiveUser = yearlyActiveUsers.get(userLoginService.getUserIdHashCode(userId));

// 輸出統(tǒng)計(jì)結(jié)果
System.out.println("月度活躍用戶(hù)數(shù)量: " + monthlyActiveUserCount);
System.out.println("年度活躍用戶(hù)數(shù)量: " + yearlyActiveUserCount);
System.out.println("用戶(hù)user123是否為月度活躍用戶(hù): " + isMonthlyActiveUser);
System.out.println("用戶(hù)user123是否為年度活躍用戶(hù): " + isYearlyActiveUser);

總結(jié)

Redis的Bitmap數(shù)據(jù)結(jié)構(gòu)非常靈活,可以根據(jù)具體需求實(shí)現(xiàn)各種位操作,但平時(shí)在項(xiàng)目中很多人沒(méi)有機(jī)會(huì)使用到,這個(gè)案例非常簡(jiǎn)單,希望能讓大家對(duì)此有個(gè)認(rèn)識(shí),未來(lái)用到了不會(huì)感到陌生。

以上就是SpringBoot+Redis Bitmap實(shí)現(xiàn)活躍用戶(hù)統(tǒng)計(jì)的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot Redis Bitmap用戶(hù)統(tǒng)計(jì)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring?JPA之find拓展方法示例詳解

    Spring?JPA之find拓展方法示例詳解

    這篇文章主要為大家介紹了Spring?JPA之find拓展方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Java鎖機(jī)制Lock用法示例

    Java鎖機(jī)制Lock用法示例

    這篇文章主要介紹了Java鎖機(jī)制Lock用法,結(jié)合具體實(shí)例形式分析了Java鎖機(jī)制的相關(guān)上鎖、釋放鎖、隱式鎖、顯式鎖等概念與使用技巧,需要的朋友可以參考下
    2018-08-08
  • SpringBoot3集成Calcite多數(shù)據(jù)源查詢(xún)的實(shí)戰(zhàn)示例小結(jié)

    SpringBoot3集成Calcite多數(shù)據(jù)源查詢(xún)的實(shí)戰(zhàn)示例小結(jié)

    本文介紹了Spring Boot 3集成Apache Calcite實(shí)現(xiàn)多數(shù)據(jù)源查詢(xún)的實(shí)戰(zhàn)指南,本文通過(guò)實(shí)例代碼給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2026-02-02
  • Java如何通過(guò)反射獲取私有構(gòu)造、私有對(duì)象、私有字段、私有方法

    Java如何通過(guò)反射獲取私有構(gòu)造、私有對(duì)象、私有字段、私有方法

    這篇文章主要介紹了Java如何通過(guò)反射獲取私有構(gòu)造、私有對(duì)象、私有字段、私有方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • java實(shí)現(xiàn)基于Tcp的socket聊天程序

    java實(shí)現(xiàn)基于Tcp的socket聊天程序

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)基于Tcp的socket聊天程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • 簡(jiǎn)單了解Spring循環(huán)依賴(lài)解決過(guò)程

    簡(jiǎn)單了解Spring循環(huán)依賴(lài)解決過(guò)程

    這篇文章主要介紹了簡(jiǎn)單了解Spring循環(huán)依賴(lài)解決過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • SpringBoot整合Activiti工作流的完整教程

    SpringBoot整合Activiti工作流的完整教程

    本文檔詳細(xì)介紹如何在SpringBoot項(xiàng)目中完整整合Activiti工作流引擎,特別針對(duì)內(nèi)存使用、性能和響應(yīng)速度進(jìn)行了全面優(yōu)化,包含環(huán)境搭建、核心API使用、實(shí)際業(yè)務(wù)場(chǎng)景實(shí)現(xiàn),并以請(qǐng)假審批流程為實(shí)戰(zhàn)案例進(jìn)行完整演示,需要的朋友可以參考下
    2026-03-03
  • SpringBoot整合TomCat實(shí)現(xiàn)本地圖片服務(wù)器代碼解析

    SpringBoot整合TomCat實(shí)現(xiàn)本地圖片服務(wù)器代碼解析

    這篇文章主要介紹了SpringBoot整合TomCat實(shí)現(xiàn)本地圖片服務(wù)器代碼解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • WPF實(shí)現(xiàn)自定義一個(gè)自刪除的多功能ListBox

    WPF實(shí)現(xiàn)自定義一個(gè)自刪除的多功能ListBox

    這篇文章主要為大家詳細(xì)介紹了如何利用WPF實(shí)現(xiàn)自定義一個(gè)自刪除的多功能ListBox,文中示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-12-12
  • Centos中安裝jdk案例講解

    Centos中安裝jdk案例講解

    這篇文章主要介紹了Centos中安裝jdk案例講解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08

最新評(píng)論

建阳市| 绥滨县| 垣曲县| 新丰县| 资阳市| 石门县| 永定县| 丹江口市| 虞城县| 信丰县| 河间市| 天峻县| 筠连县| 嵊州市| 凌海市| 彩票| 巴塘县| 宜丰县| 介休市| 香格里拉县| 买车| 五指山市| 安吉县| 永胜县| 济宁市| 富蕴县| 姜堰市| 双流县| 新和县| 江阴市| 望城县| 泽州县| 沈丘县| 泸西县| 莆田市| 城固县| 宜兴市| 成武县| 姚安县| 开化县| 东至县|