Redis - 使用 Redis HyperLogLog 進行高效基數統計

文章目錄

  • 引言
  • HyperLogLog 工作原理
  • Spring Boot 集成 Redis
    • 1. 添加依賴
    • 2. 配置 Redis 連接
    • 3. Redis 配置類
  • HyperLogLog 實戰應用
    • 1. 基礎操作服務類
    • 2. 網站日活躍用戶統計
    • 3. 性能測試與誤差分析
  • 應用場景分析
    • 適用場景
    • 不適用場景
  • 性能優化技巧
  • 與傳統方案對比
  • 結論

在這里插入圖片描述

引言

在數據分析和監控系統中,基數統計(即統計唯一元素數量)是一個常見但資源密集型的任務。傳統方法在處理大規模數據時面臨內存消耗大和計算成本高的問題。Redis 的 HyperLogLog (HLL) 數據結構以極小內存占用(約 12KB)提供接近準確的基數估計,標準誤差僅約 0.81%。

接下來我們將探討如何在 Spring Boot 中使用 Spring Data Redis 實現高效的基數統計。

HyperLogLog 工作原理

HyperLogLog 基于概率算法:

  1. 對每個元素應用哈希函數
  2. 計算哈希值的二進制前導零數量
  3. 使用調和平均數估算基數

這種設計使得 HLL 能夠:

  • 以固定內存處理任意大集合
  • 提供 O(1) 時間復雜度的添加和查詢操作
  • 支持多集合合并操作

Spring Boot 集成 Redis

1. 添加依賴

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
</dependencies>

2. 配置 Redis 連接

# application.properties
spring.redis.host=localhost
spring.redis.port=6379

3. Redis 配置類

@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(connectionFactory);template.setKeySerializer(new StringRedisSerializer());template.setHashKeySerializer(new StringRedisSerializer());return template;}
}

HyperLogLog 實戰應用

1. 基礎操作服務類

@Service
public class HyperLogLogService {private final RedisTemplate<String, String> redisTemplate;public HyperLogLogService(RedisTemplate<String, String> redisTemplate) {this.redisTemplate = redisTemplate;}// 添加元素到 HLLpublic void add(String key, String... values) {redisTemplate.opsForHyperLogLog().add(key, values);}// 獲取基數估計值public long count(String key) {return redisTemplate.opsForHyperLogLog().size(key);}// 合并多個 HLLpublic void merge(String destinationKey, String... sourceKeys) {redisTemplate.opsForHyperLogLog().union(destinationKey, sourceKeys);}
}

2. 網站日活躍用戶統計

@RestController
@RequestMapping("/analytics")
public class AnalyticsController {private final HyperLogLogService hllService;public AnalyticsController(HyperLogLogService hllService) {this.hllService = hllService;}// 記錄用戶訪問@PostMapping("/visit")public ResponseEntity<String> recordVisit(@RequestParam String userId,@RequestParam String date) {String key = "dau:" + date;hllService.add(key, userId);return ResponseEntity.ok("Visit recorded");}// 獲取日活躍用戶數@GetMapping("/dau")public ResponseEntity<Long> getDailyActiveUsers(@RequestParam String date) {String key = "dau:" + date;long count = hllService.count(key);return ResponseEntity.ok(count);}// 獲取多日合并活躍用戶數@GetMapping("/mau")public ResponseEntity<Long> getMonthlyActiveUsers(@RequestParam int year,@RequestParam int month) {List<String> keys = new ArrayList<>();LocalDate start = LocalDate.of(year, month, 1);LocalDate end = start.withDayOfMonth(start.lengthOfMonth());for (LocalDate date = start; !date.isAfter(end); date = date.plusDays(1)) {keys.add("dau:" + date);}String monthlyKey = "mau:" + year + "-" + month;hllService.merge(monthlyKey, keys.toArray(new String[0]));return ResponseEntity.ok(hllService.count(monthlyKey));}
}

3. 性能測試與誤差分析

@SpringBootTest
public class HyperLogLogTests {@Autowiredprivate HyperLogLogService hllService;@Testvoid testAccuracyWithLargeDataset() {String key = "test:accuracy";int totalUsers = 100_000;Set<String> realUsers = new HashSet<>();// 添加 10 萬用戶(包含部分重復)for (int i = 0; i < 150_000; i++) {String userId = "user-" + (int)(Math.random() * totalUsers);hllService.add(key, userId);realUsers.add(userId);}long estimatedCount = hllService.count(key);long realCount = realUsers.size();System.out.println("真實基數: " + realCount);System.out.println("HLL估計值: " + estimatedCount);System.out.println("誤差率: " + String.format("%.2f%%", 100.0 * Math.abs(realCount - estimatedCount) / realCount));// 典型輸出:// 真實基數: 99987// HLL估計值: 100542// 誤差率: 0.56%}
}

應用場景分析

適用場景

  1. 大規模用戶分析:日活/月活用戶統計
  2. 網絡監控:統計唯一訪問 IP
  3. 廣告分析:估算廣告曝光獨立用戶數
  4. 實時數據流:去重計數

不適用場景

  1. 需要精確計數的業務(如金融交易)
  2. 需要獲取具體元素的場景
  3. 極小數據集(傳統方法更合適)

性能優化技巧

  1. 鍵名設計優化

    // 使用哈希標簽確保相關鍵在同一槽位
    String key = "{analytics}:dau:" + date;
    
  2. 管道批處理

    public void batchAdd(String key, List<String> values) {redisTemplate.executePipelined((RedisCallback<Object>) connection -> {for (String value : values) {connection.pfAdd(key.getBytes(), value.getBytes());}return null;});
    }
    
  3. 內存優化配置

    # 啟用 HLL 稀疏表示(對小數據集更高效)
    spring.redis.hyperloglog.sparse=true
    

與傳統方案對比

方案內存占用 (100萬用戶)精確性合并能力復雜度
MySQL DISTINCT~50MB精確復雜O(n)
Redis SET~16MB精確支持O(1)
Redis HLL~12KB~99.19%高效O(1)

結論

Redis HyperLogLog 為大規模基數統計提供了優雅解決方案:

  1. 內存效率極高 - 固定 12KB 內存占用
  2. 操作復雜度恒定 - O(1) 時間操作
  3. 分布式友好 - 支持多集合并行合并
  4. 易于集成 - Spring Data Redis 提供簡潔 API

雖然 HLL 提供的是概率性估計,但在大多數分析場景中,其微小的誤差率(<1%)是可接受的,尤其是考慮到它帶來的巨大資源節省。對于需要精確統計的場景,可考慮結合使用 HLL 和 Redis Bloom Filter 等互補技術。

提示:在實際生產環境中,建議定期將 HLL 結果持久化到數據庫,并設置 Redis 鍵的 TTL 策略以管理內存使用。

so, 我們可以在 Spring Boot 應用中輕松實現高效、可擴展的基數統計系統,處理海量數據而無需擔心資源消耗問題。

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/92732.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/92732.shtml
英文地址,請注明出處:http://en.pswp.cn/web/92732.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

後端開發技術教學(三) 表單提交、數據處理

上回&#xff1a;後端開發技術教學(二) 條件指令、循環結構、定義函數 -CSDN博客 必要資源&#xff1a; trae中文版下載網址: TRAE - The Real AI Engineer phpStudy 2018 : phpStudy - Windows 一鍵部署 PHP 開發環境 小皮出品 目錄 一、表單提交 1.1 get & post 1.…

Python訓練Day39

浙大疏錦行 圖像數據的格式&#xff1a;灰度和彩色數據模型的定義顯存占用的4種地方 模型參數梯度參數優化器參數數據批量所占顯存神經元輸出中間狀態 batchisize和訓練的關系 一、 圖像數據的介紹 圖像數據&#xff0c;相較于結構化數據&#xff08;表格數據&#xff09;他的特…

十八、MySQL-DML-數據操作-插入(增加)、更新(修改)、刪除

DML數據操作添加數據更新(修改)數據刪除數據總結代碼&#xff1a; -- DML:數據操作語言-- -- DML:插入數據-insert -- 1.為tb_emp表的username,name&#xff0c;gender 字股插入值insert into tb_emp(username,name,gender,create_time,update_time) values (Toki,小時,2,now()…

Linux 安裝 JDK 8u291 教程(jdk-8u291-linux-x64.tar.gz 解壓配置詳細步驟)?

一、準備工作 ?下載 JDK 安裝包? 去 Oracle 官網或者可信的鏡像站下載&#xff1a; ?jdk-8u291-linux-x64.tar.gz? &#xff08;這是一個壓縮包&#xff0c;不是安裝程序&#xff0c;解壓就能用&#xff09; ?jdk-8u291-linux-x64.tar.gz?下載鏈接&#xff1a;https://pa…

藍橋杯----鎖存器、LED、蜂鳴器、繼電器、Motor

(七)、鎖存器1、原理藍橋杯中數據傳入口都是P0&#xff0c;也就是數碼管段選、位選數據、LED亮滅的數據、蜂鳴器啟動或禁用的數據&#xff0c;外設啟動或者關閉都需要通過P0寫入數據&#xff0c;那么如何這樣共用一個端口會造成沖突嘛&#xff0c;答案是肯定的。所以藍橋杯加入…

AI熱點周報(8.3~8.9):OpenAI重返開源,Anthropic放大招,Claude4.1、GPT5相繼發布

名人說&#xff1a;博觀而約取&#xff0c;厚積而薄發。——蘇軾《稼說送張琥》 創作者&#xff1a;Code_流蘇(CSDN)&#xff08;一個喜歡古詩詞和編程的Coder&#x1f60a;&#xff09; 目錄一、OpenAI的"開源回歸"&#xff1a;時隔5年的戰略大轉彎1. GPT-OSS系列&a…

《Kubernetes部署篇:基于x86_64+aarch64架構CPU+containerd一鍵離線部署容器版K8S1.33.3高可用集群》

總結&#xff1a;整理不易&#xff0c;如果對你有幫助&#xff0c;可否點贊關注一下&#xff1f; 更多詳細內容請參考&#xff1a;企業級K8s集群運維實戰 一、部署背景 由于業務系統的特殊性&#xff0c;我們需要針對不同的客戶環境部署基于containerd容器版 K8S 1.33.3集群&a…

Linux抓包命令tcpdump詳解筆記

文章目錄一、tcpdump 是什么&#xff1f;二、基本語法三、常用參數說明四、抓包示例&#xff08;通俗易懂&#xff09;1. 抓所有數據包&#xff08;默認 eth0&#xff09;2. 指定接口抓包3. 抓取端口 80 的數據包&#xff08;即 HTTP 請求&#xff09;4. 抓取訪問某個 IP 的數據…

抖音、快手、視頻號等多平臺視頻解析下載 + 磁力嗅探下載、視頻加工(提取音頻 / 壓縮等)

跟你們說個安卓上的下載工具&#xff0c;還挺厲害的。它能支持好多種下載方式&#xff0c;具體多少種我沒細數&#xff0c;反正挺全乎的。? 平時用得最多的就是視頻解析&#xff0c;像抖音、快手、B 站上那些視頻&#xff0c;想存下來直接用它就行&#xff0c;連海外視頻的也能…

【iOS】JSONModel源碼學習

JSONModel源碼學習前言JSONModel的使用最基礎的使用轉換屬性名稱自定義錯誤模型嵌套JSONModel的繼承源碼實現initWithDictionaryinit__doesDictionaryimportDictionary優點前言 之前了解過JSONModel的一些使用方法等&#xff0c;但是對于底層實現并不清楚了解&#xff0c;今天…

SmartMediaKit 模塊化音視頻框架實戰指南:場景鏈路 + 能力矩陣全解析

?? 引言&#xff1a;從“內核能力”到“模塊體系”的演進 自 2015 年起&#xff0c;大牛直播SDK&#xff08;SmartMediaKit&#xff09;便致力于打造一個可深度嵌入、跨平臺兼容、模塊自由組合的實時音視頻基礎能力框架。經過多輪技術迭代與場景打磨&#xff0c;該 SDK 已覆…

【第5話:相機模型1】針孔相機、魚眼相機模型的介紹及其在自動駕駛中的作用及使用方法

相機模型介紹及相機模型在自動駕駛中的作用及使用方法 相機模型是計算機視覺中的核心概念&#xff0c;用于描述真實世界中的點如何投影到圖像平面上。在自動駕駛系統中&#xff0c;相機模型用于環境感知&#xff0c;如物體檢測和場景理解。下面我將詳細介紹針孔相機模型和魚眼相…

推薦一款優質的開源博客與內容管理系統

Halo是一款由Java Spring Boot打造的開源博客與內容管理系統&#xff08;CMS&#xff09;&#xff0c;在 GitHub上擁有超過36K Start的活躍開發者社區。它使用GPL?3.0授權開源&#xff0c;穩定性與可維護性極高。 Halo的設計簡潔、注重性能&#xff0c;同時保持高度靈活性&a…

【GPT入門】第43課 使用LlamaFactory微調Llama3

【GPT入門】第43課 使用LlamaFactory微調Llama31.環境準備2. 下載基座模型3.LLaMA-Factory部署與啟動4. 重新訓練![在這里插入圖片描述](https://i-blog.csdnimg.cn/direct/e7aa869f8e2c4951a0983f0918e1b638.png)1.環境準備 采購autodl服務器&#xff0c;24G,GPU,型號3090&am…

計算機網絡:如何理解目的網絡不再是一個完整的分類網絡

這一理解主要源于無分類域間路由&#xff08;CIDR&#xff09;技術的廣泛應用&#xff0c;它打破了傳統的基于類的IP地址分配方式。具體可從以下方面理解&#xff1a; 傳統分類網絡的局限性&#xff1a;在早期互聯網中&#xff0c;IP地址被分為A、B、C等固定類別&#xff0c;每…

小米開源大模型 MiDashengLM-7B:不僅是“聽懂”,更能“理解”聲音

目錄 前言 一、一枚“重磅炸彈”&#xff1a;開源&#xff0c;意味著一扇大門的敞開 二、揭秘MiDashengLM-7B&#xff1a;它究竟“神”在哪里&#xff1f; 2.1 “超級耳朵” 與 “智慧大腦” 的協作 2.2 突破&#xff1a;從 “聽見文字” 到 “理解世界” 2.3 創新訓練&a…

mysql出現大量redolog、undolog排查以及解決方案

排查步驟 監控日志增長情況 -- 查看InnoDB狀態 SHOW ENGINE INNODB STATUS;-- 查看redo log配置和使用情況 SHOW VARIABLES LIKE innodb_log_file%; SHOW VARIABLES LIKE innodb_log_buffer_size;-- 查看undo log信息 SHOW VARIABLES LIKE innodb_undo%;檢查長時間運行的事務 -…

華為網路設備學習-28(BGP協議 三)路由策略

目錄&#xff1a; 一、BGP路由匯總1、注&#xff1a;使用network命令注入的BGP不會被自動匯總2、主類網絡號計算過程如下&#xff1a;3.示例 開啟BGP路由自動匯總bgp100 開啟BGP路由自動匯總import-route 直連路由 11.1.1.0 /24對端 為 10.1.12.2 AS 2004.手動配置BGP路…

微信小程序中實現表單數據實時驗證的方法

一、實時驗證的基本實現思路表單實時時驗證通過監聽表單元素的輸入事件&#xff0c;在用戶輸入過程中即時對數據進行校驗&#xff0c;并并即時反饋驗證結果&#xff0c;主要實現步驟包括&#xff1a;為每個表單字段綁定輸入事件在事件處理函數中獲取當前輸入值應用驗證規則進行…

openpnp - 頂部相機如果超過6.5米影響通訊質量,可以加USB3.0信號放大器延長線

文章目錄openpnp - 頂部相機如果超過6.5米影響通訊質量&#xff0c;可以加USB3.0信號放大器延長線概述備注ENDopenpnp - 頂部相機如果超過6.5米影響通訊質量&#xff0c;可以加USB3.0信號放大器延長線 概述 手頭有1080x720x60FPS的攝像頭模組備件&#xff0c;換上后&#xff…