Redis 概率型數據結構實戰指南

1. 為什么要用「近似」?

隨著業務量爆發式增長,精確統計 的內存或 CPU 成本可能難以接受。例如:

  • 統計一天內 唯一 IP 數 —— 用 SET 精確去重,百萬 IP→占用數百 MB。
  • 統計海量商品銷量、實時計算 P99 延遲、獲取 TOP-N 熱門頁面……

概率型(Probabilistic)數據結構 通過犧牲可控的精度,換取極低內存與高吞吐,成為解決此類問題的利器。Redis-Bloom 模塊為 Redis 提供了一整套成熟實現,go-redis v9 已封裝全部指令,開箱即用。

2. 近似集合操作

需求數據結構誤差特點是否可刪除
是否出現過Bloom Filter假陽性(可調)?
Cuckoo Filter假陽性(略低)?
集合基數HyperLogLog標準誤差 ≈ 0.81%

2.1 Bloom Filter —— 最小內存的存在性判斷

// 批量寫入
okList, _ := rdb.BFMAdd(ctx,"recorded_users","andy", "cameron", "david", "michelle",
).Result()                      // [true true true true]// 判斷存在
exists, _ := rdb.BFExists(ctx, "recorded_users", "cameron")  // true
absent, _ := rdb.BFExists(ctx, "recorded_users", "kaitlyn")  // false

應用場景

  • 去重寫日志、判重爬蟲 URL、垃圾郵件過濾。
  • 典型誤判率 1%~0.01%,可通過 BF.RESERVE 自定義。

2.2 Cuckoo Filter —— 支持刪除

rdb.CFAdd(ctx, "other_users", "paolo")           // true
rdb.CFDel(ctx, "other_users", "paolo")           // true
rdb.CFExists(ctx, "other_users", "paolo")        // false

選型要點

對比項BloomCuckoo
寫入速度更快略慢
內存更省稍高
DEL不支持支持
查詢性能略慢更快

結論:需要刪除就選 Cuckoo;極端節省內存或寫密集則用 Bloom。

2.3 HyperLogLog —— 基數統計王者

// group:1 共 3 個不同成員
rdb.PFAdd(ctx, "group:1", "andy", "cameron", "david")
// group:2 共 4 個不同成員
rdb.PFAdd(ctx, "group:2", "kaitlyn", "michelle", "paolo", "rachel")cnt1, _ := rdb.PFCount(ctx, "group:1")           // 3
cnt2, _ := rdb.PFCount(ctx, "group:2")           // 4// 合并后去重
rdb.PFMerge(ctx, "both_groups", "group:1", "group:2")
total, _ := rdb.PFCount(ctx, "both_groups")      // 7
  • 固定 12 KB 即可統計 2?? 去重計數。
  • 誤差 ≈ 0.81%。
  • 典型場景:UV、去重后計數、唯一用戶量。

3. 近似統計運算

需求數據結構誤差可調典型場景
頻率估計Count-min Sketch?商品銷量、PV 計數
分位數/百分位t-digest?延遲 P99、身高分布
TOP-K 排名Top-K?最熱商品/頁面

3.1 Count-min Sketch —— 近似頻率查詢

// 誤差≤0.1%,錯誤概率≤0.05%
rdb.CMSInitByProb(ctx, "items_sold", 0.01, 0.005)rdb.CMSIncrBy(ctx, "items_sold","bread", 300, "tea", 200, "coffee", 200, "beer", 100)rdb.CMSIncrBy(ctx, "items_sold", "bread", 100, "coffee", 150)freq, _ := rdb.CMSQuery(ctx, "items_sold", "bread", "coffee") // [400 350]
  • 內存固定(取決于誤差參數),無需隨 item 增長。
  • 「流式」場景比 ZINCRBY ? ZRANGE 省內存高效。

3.2 t-digest —— 分位數利器

rdb.TDigestCreate(ctx, "male_heights")
rdb.TDigestAdd(ctx, "male_heights", 175.5, 181, 160.8, 152, 177, 196, 164)p75, _ := rdb.TDigestQuantile(ctx, "male_heights", 0.75) // [181]
cdf, _ := rdb.TDigestCDF(ctx, "male_heights", 181)       // ≈0.7857
min, _ := rdb.TDigestMin(ctx, "male_heights")            // 152
max, _ := rdb.TDigestMax(ctx, "male_heights")            // 196
  • 采樣點多時仍保持 O(1) 內存。
  • 適合 P95、P99 時延監控、A/B 實驗指標。

3.3 Top-K —— 熱門榜單實時統計

// 創建「Top3」榜單
rdb.TopKReserve(ctx, "top_3_songs", 3)// 批量增加播放量
rdb.TopKIncrBy(ctx, "top_3_songs","Starfish Trooper", 3000,"Only one more time", 1850,"Rock me, Handel", 1325,"How will anyone know?", 3890,"Average lover", 4098,"Road to everywhere", 770)// 列出前 3
top3, _ := rdb.TopKList(ctx, "top_3_songs")
// [Average lover, How will anyone know?, Starfish Trooper]// 查詢某歌曲是否在榜
hit, _ := rdb.TopKQuery(ctx, "top_3_songs", "Starfish Trooper") // [true]
  • 內部基于 Count-min + 堆,內存固定。
  • 適合實時 TOP-N 榜單,如熱搜、熱賣、熱文章。

4. 選型與實踐指南

場景建議數據結構備注
唯一訪問 IP / UVHyperLogLog固定 12 KB / 0.81% 誤差
日志去重、注冊判重Bloom / Cuckoo需刪除 → Cuckoo;否則 Bloom
商品銷量、頁面 PVCount-min Sketch更關注趨勢而非精確值
延遲分布監控t-digest秒級更新 P95/P99
最熱商品/話題榜單Top-K高并發流式排名
拼寫/命名黑名單Bloom Filter快速 filtration

提示

  1. 所有模塊均屬于 RedisBloom,需加載模塊或使用 Redis Stack。

  2. go-redis v9 命令位于 github.com/redis/go-redis/v9,大寫前綴如 BFMAddCMSInitByProb

  3. 針對誤差/容量調優:

    • Bloom:BF.RESERVE key errorRate capacity
    • CMS:CMS.INITBYPROB key error prob
    • t-digest:可選壓縮率 TDIGEST.CREATE key compression

5. 踩坑 & 性能建議

問題解決方案
誤差過大調大容量 / 調小 errorRate;但會增內存
Top-K 大量并發 INCRBY 壓力采用 Pipeline 批量上報
同一 Key 頻繁刪除(Cuckoo 滿)提前預估容量,使用 CF.RESERVE
CMS 超過容量后誤差逐漸增大按天/小時拆分 Key 或定期快照重建
t-digest 估算極端分位不準 (P99.9)增大 compression、增加樣本數
HyperLogLog 需要合并太多 Key兩層:先分片,再定期 PFMERGE

6. 生產 Checklist

  1. 模塊加載redis-stack-server--loadmodule redisbloom.so
  2. 版本:Redis ≥ 6.2,RedisBloom ≥ 2.6。
  3. 監控:結合 INFO modules 觀察 BF/CMS 內部 stats;或自定義 Metrics。
  4. 備份:RDB/AOF 包含概率結構,但恢復后誤差不變;無須額外處理。
  5. 容量預估:使用統計學公式或壓測,寧可稍大,不可過小。
  6. 代碼封裝:為每種結構寫 DAO,隱藏底層命令,方便替換與調參。

7. 總結

概率型數據結構 = 低成本 + 可接受誤差
高 QPS / 大數據量 / 對精度容忍度高 的場景,它們能顯著減少內存與 IO,提升系統整體吞吐。合理選型、正確調參,再配合 go-redis 的高效封裝,你就能輕松構建 高性能、低成本 的統計與去重服務。

推薦閱讀

  • RedisBloom 官方案例
  • ACM 論文《Less Hashing, Same Performance: Building a Better Bloom Filter》
  • Dunning & Ertl《A Comprehensive Evaluation of Approximate Cardinality Estimation Algorithms》

Happy Coding,愿你的 Redis 永不爆表!

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

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

相關文章

Android開發工程師:Linux一條find grep命令通關搜索內容與文件

find . -type f \( -name "*.java" -o -name "*.xml" \) -not -path "./out/*" -exec grep -irnE activity|class {} 多關鍵詞搜索:使用正則表達式 pattern1|pattern2 同時搜索多個關鍵詞(如 activity|class)單…

深入理解瀏覽器解析機制和XSS向量編碼

URL 編碼 "javascript:alert(1)"---->%6a%61%76%61%73%63%72%69%70%74:%61%6c%65%72%74%28%31%29<a href"%6a%61%76%61%73%63%72%69%70%74:%61%6c%65%72%74%28%31%29">aaa</a>-------瀏覽器解析不了。 頁面識別在url解碼之前&#xff0c;在…

ThinkPHP8極簡上手指南:開啟高效開發之旅

目錄一、環境搭建1.1 安裝 PHP1.2 安裝 Composer二、安裝 ThinkPHP8三、目錄結構解析四、第一個簡單示例&#xff1a;Hello, ThinkPHP84.1 創建控制器4.2 編寫控制器方法4.3 配置路由4.4 訪問測試五、進階示例&#xff1a;數據庫查詢5.1 配置數據庫連接5.2 創建模型5.3 編寫查詢…

智能制造之物料詳解

在制造業業務系統中&#xff0c;物料流轉貫穿“需求→采購→入庫→生產→成品→交付”全流程&#xff0c;各系統通過數據協同實現物料狀態、位置、數量的精準追蹤。以下按流轉階段拆解&#xff1a;一、需求發起與計劃階段&#xff08;CRM/ERP/PLM主導&#xff09;1. 需求源頭…

Qt的安裝和環境配置

QT開發環境的搭建&#xff0c;需要安裝3個部分&#xff0c;C編譯器、Qt SDK(SDK是軟件開發工具包)、QT的集成開發環境(IDE)Qt的3種集成開發環境&#xff1a;Qt Creator&#xff1a;是由Qt官方提供的&#xff0c;容易上手&#xff0c;不需要額外的配置&#xff0c;但是有一些bug…

解析MCUboot的實現原理和Image結構

目錄 概述 1 MCUboot的功能 1.1 代碼包結構 1.2 限制 2 MCUboot Image 2.1 Image格式 2.2 Flash Map 2.3 Image 槽 2.4 使用scratch交換 2.5 Image 尾部數據結構 3 交換區 3.1 單交換區 3.2 Multiple Image boot 3.3 Image交換 4 交換狀態&#xff08;swap statu…

YOLOv8目標檢測項目代碼詳解與習題

YOLOv8目標檢測項目代碼詳解與習題一、項目代碼詳解該代碼是基于 YOLOv8 和 OpenCV 實現的圖像目標檢測項目&#xff0c;核心功能是加載預訓練的 YOLOv8 模型&#xff0c;對指定圖像進行目標檢測&#xff0c;然后可視化檢測結果并保存或顯示。以下是逐行解析&#xff1a;# -*- …

gradle關于dependency-management的使用

1、相關文檔Spring官方文檔&#xff1a;https://docs.spring.io/dependency-management-plugin/docs/current-SNAPSHOT/reference/html/#introduction倉庫版本查看&#xff1a;https://mvnrepository.com/artifact/io.spring.gradle/dependency-management-plugin/1.0.15.RELEA…

Java SpringBoot 對接FreeSwitch

1.增加Maven依賴<dependency><groupId>org.freeswitch.esl.client</groupId><artifactId>org.freeswitch.esl.client</artifactId><version>0.9.2</version></dependency><!-- XML-RPC --><dependency><groupI…

限流算法與實現

費曼學習法學習限流算法為什么要限流mysql插入600次/秒超過這個閾值&#xff0c;要么使用mysql集群、要么限流&#xff0c;防止宕機有哪些算法固定窗口就是個計數器&#xff0c;一秒內超過閾值&#xff0c;不允許訪問缺點&#xff1a;不均勻&#xff0c;跨越臨界點的一秒內&…

Android本地瀏覽PDF(Android PDF.js 簡要學習手冊)

環境 Min SDK: 21 依賴&#xff1a; implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1" implementation "androidx.webkit:webkit:1.12.0"權限&#xff1a; <uses-permission android:name"android.permission.INTERNE…

CVE-2022-41128

概述CVE-2022-41128 是 Microsoft Internet Explorer&#xff08;IE&#xff09;瀏覽器中 JavaScript 引擎&#xff08;JScript/Chakra&#xff09;的一個 0day 漏洞&#xff08;披露時無官方補丁&#xff09;&#xff0c;屬于內存破壞類漏洞&#xff0c;可被用于遠程代碼執行&…

基于LSTM的時間序列到時間序列的回歸模擬

獲取項目源碼點擊文末名片項目背景與目標 本項目旨在開發一種基于長短期記憶網絡&#xff08;LSTM&#xff09;的模型&#xff0c;用于時間序列到時間序列的回歸模擬任務。通過處理多組不同來源的時間序列數據&#xff0c;本模型的目標是從給定的輸入序列中預測相應的輸出序列。…

Linux基礎命令詳解:從入門到精通

本文整理了Linux系統中最常用的基礎命令&#xff0c;每個命令都配有詳細說明和具體示例&#xff0c;幫助你快速掌握Linux操作技巧。文章中用的終端是XShell,系統是Centos&#x1f4c1; 1. ls - 列出目錄&#xff08;文件夾&#xff09;內容 功能&#xff1a;顯示當前目錄下的文…

正點原子stm32F407學習筆記10——輸入捕獲實驗

一、輸入捕獲簡介 輸入捕獲模式可以用來測量脈沖寬度或者測量頻率。我們以測量脈寬為例&#xff0c;用一個簡圖來 說明輸入捕獲的原理&#xff0c;如圖所示&#xff1a;假定定時器工作在向上計數模式&#xff0c;圖中 t1到t2 時間&#xff0c;就是我們需要測量的高電平時間。測…

深入理解設計模式:狀態模式(State Pattern)

在軟件開發中&#xff0c;我們經常會遇到對象的行為隨著其內部狀態的變化而變化的情況。例如&#xff0c;一個訂單可能處于"待支付"、"已支付"、"已發貨"或"已完成"等不同狀態&#xff0c;每個狀態下訂單的操作邏輯可能完全不同。如果…

企業級網絡綜合集成實踐:VLAN、Trunk、STP、路由協議(OSPF/RIP)、PPP、服務管理(TELNET/FTP)與安全(ACL)

NE綜合實驗4 一、實驗拓撲二、實驗需求 按照圖示配置IP地址。Sw7和sw8之間的直連鏈路配置鏈路聚合。公司內部業務網段為vlan10和vlan20&#xff0c;vlan10是市場部&#xff0c;vlan20是技術部&#xff0c;要求對vlan進行命名以便區分識別&#xff1b;pc10屬于vlan10&#xff0c…

小架構step系列20:請求和響應的擴展點

1 概述通過上一篇了解請求和響應的流程&#xff0c;Spring在設計上留了不少擴展點。里面通過查找接口的方式獲取的地方&#xff0c;都可以成為一種擴展點&#xff0c;因為只要實現這類接口就可以成為Spring加載的一部分。本文了解一下這些擴展點&#xff0c;方便后面進行擴展。…

模型材質一鍵替換~輕松還原多種三維場景

1. 概述模型的材質決定了三維場景的整體視效&#xff0c;山海鯨可視化不僅支持模型材質的替換與編輯&#xff0c;而且提供了大量現成的模型材質供大家使用&#xff0c;能夠幫助大家實現更高效的三維場景搭建。模型材質主要分為PBR材質和水面材質兩個部分。其中大部分靜態模型都…

【JS逆向基礎】數據庫之mysql

前言&#xff1a;mysql數據庫管理系統&#xff0c;由瑞典MySQL AB 公司開發&#xff0c;目前屬于 Oracle 旗下公司。MySQL 最流行的關MySQL是一個開源免費的關系型數據庫管系型數據庫管理系統&#xff0c;在 WEB 應用方面ySQL是最好的 RDBMS (Relational Database Management S…