【redis】數據類型之hyperloglog

Redis的HyperLogLog(HLL)是一種高效的概率數據結構,也是一種基于字符串的數據結構,用于估計大數據集的唯一元素數量(基數統計)。它通過極低的內存占用(約 12KB)實現接近線性的時間復雜度,適用于海量數據去重計數場景(如統計獨立訪客數),但需容忍約0.81%的標準誤差。

有關hyperloglog類型的命令可以通過help @hyperloglog命令來查看。有關命令的使用可以通過help 命令來查看,例如help pfadd

核心特性

低內存消耗:即使統計上億甚至幾十億的數量級,每個HyperLogLog鍵僅占用12KB內存,無論元素數量多少(極端情況下最多占用64KB)。

高效合并:支持多組HyperLogLog的合并去重(PFMERGE),并且復雜度也是O(1),適合分布式統計(如多日數據合并為周/月統計)。

去重能力:自動忽略重復元素,多次添加同一元素不會影響結果。

計算復雜度低:其插入、查詢操作的復雜度都是O(1),這使得它在處理大規模數據集時具有非常高的效率。

結果是估計值:雖然HyperLogLog提供的是基數估計值,但誤差非常小,標準誤差率可以控制在0.81%以內。

命令的使用

PFADD

PFADD:將一個或多個元素添加到HyperLogLog中,用于估算基數。

語法:

PFADD key element [element ...]

使用:

127.0.0.1:6379> pfadd visits:20990101 user1 user2
(integer) 1127.0.0.1:6379> pfadd visits:20990102 user2 user3
(integer) 1

PFCOUNT

PFCOUNT:返回一個或多個HyperLogLog的估算基數。。

語法:

PFCOUNT key [key ...]

使用:

# 統計單日獨立用戶
127.0.0.1:6379> pfcount visits:20990101
(integer) 2# 合并兩日數據
127.0.0.1:6379> pfcount visits:20990101 visits:20990102
(integer) 3

PFMERGE

PFMERGE:將一個或多個HyperLogLog合并到另一個HyperLogLog中,用于合并不同數據集的基數估算。

語法:

PFMERGE destkey sourcekey [sourcekey ...]

使用:

127.0.0.1:6379> pfmerge visits:week visits:20990101 visits:20990102
OK127.0.0.1:6379> pfcount visits:week
(integer) 3

實現原理

在Redis中,HyperLogLog的存儲也是個字符串,只不過這個字符串有個固定格式的頭部(16字節),包括魔術字符串、編碼方式、保留字段、緩存的基數以及數據字節等。

HyperLogLog的工作原理基于概率算法和哈希函數。它對要加入的每個新元素進行哈希處理,哈希值的一部分用于索引寄存器(將原始集合分成多個子集),另一部分用于計算哈希中最長的前導零序列。HyperLogLog根據寄存器數組中的值(這些寄存器被設置為迄今為止針對給定子集觀察到的最大連續零),計算出估計的基數,并應用修正公式來糾正估計誤差。

具體來說,Redis中HyperLogLog使用64bit的哈希函數,其中14bit用于寄存器索引,剩下的50bit用于計算前導0的個數。Redis中HLL有16384(2^14)個寄存器,其中存的值的范圍是0~50。

哈希與二進制轉換

每個元素通過哈希函數(如MurmurHash)轉換為固定長度(如64位)的二進制串。

作用:哈希保證元素分布均勻,避免數據傾斜導致的統計偏差。

分桶策略(Bucketing)

分桶規則:取哈希值前14位確定桶編號,一共2^14=16384個桶,后50位計算最長前導零數量。

基數估算公式

調和平均數:降低極端值影響,計算所有桶的調和均值 H
H = m ∑ i = 1 m 1 2 k i H = \frac{m}{\sum_{i=1}^{m} \frac{1}{2^{k_i}}} H=i=1m?2ki?1?m?

修正系數:最終基數估算值:
E = α ? m ? H E = \alpha \cdot m \cdot H E=α?m?H

其中 α 為修正系數(如 m=16384α≈0.7213)。

誤差控制與優化

標準誤差:1.04/√m,Redis實現誤差約0.81%

小數據集修正:當估算值 E < 2.5m 時,使用線性計數(Linear Counting)優化結果。

為了節省內存空間,HyperLogLog內部會采用不同的編碼方式進行存儲:

  • 稀疏編碼(默認):應對數據量小的場景。
  • 密集編碼:應對數據量大的場景。

適用場景

由于HyperLogLog具有高效存儲、概率估計和高速計算等特點,因此它非常適用于以下場景:

  • 基數統計:網站UV統計、統計每日/月的獨立訪客數。

  • 數據流量分析:例如分析用戶在某個時間段內訪問的不同頁面數、點擊不同廣告的用戶數等。

  • 實時分析:高頻事件(如搜索關鍵詞)的去重計數。

  • 大規模日志處理:快速估算日志中唯一IP或錯誤類型數量。

注意事項

  • 誤差范圍:標準誤差約0.81%,實際誤差可能因數據分布略高。

  • 非精確查詢:無法獲取具體元素或判斷元素是否存在。

  • 小數據集優化:Redis在基數較小時使用稀疏存儲優化空間。

Java中的使用

package com.morris.redis.demo.hyperloglog;import org.redisson.Redisson;
import org.redisson.api.RHyperLogLog;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.StringCodec;
import org.redisson.config.Config;import java.util.Arrays;/*** redisson中hyperloglog的使用*/
public class RedissonHyperLogLogDemo {public static void main(String[] args) {// 配置Redisson客戶端Config config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379");// 創建Redisson客戶端實例RedissonClient redisson = Redisson.create(config);// 創建hyperloglogRHyperLogLog<Object> hyperLogLog1 = redisson.getHyperLogLog("visits:20880101", StringCodec.INSTANCE);hyperLogLog1.add("user1");hyperLogLog1.addAll(Arrays.asList("user2", "user3"));RHyperLogLog<Object> hyperLogLog2 = redisson.getHyperLogLog("visits:20880102", StringCodec.INSTANCE);hyperLogLog2.add("user2");hyperLogLog2.addAll(Arrays.asList("user3", "user4"));System.out.println(hyperLogLog1.count()); // 3System.out.println(hyperLogLog1.countWith("visits:20880102")); // 4RHyperLogLog<Object> hyperLogLogWeek = redisson.getHyperLogLog("visits:week", StringCodec.INSTANCE);hyperLogLogWeek.mergeWith("visits:20880101", "visits:20880102");System.out.println(hyperLogLogWeek.count()); // 4// 關閉客戶端redisson.shutdown();}
}

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

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

相關文章

【C語言】第八期——指針、二維數組與字符串

目錄 1 初始指針 2 獲取變量的地址 3 定義指針變量、取地址、取值 3.1 定義指針變量 3.2 取地址、取值 4 對指針變量進行讀寫操作 5 指針變量作為函數參數 6 數組與指針 6.1 指針元素指向數組 6.2 指針加減運算&#xff08;了解&#xff09; 6.2.1 指針加減具體數字…

SpringBoot——生成Excel文件

在Springboot以及其他的一些項目中&#xff0c;或許我們可能需要將數據查詢出來進行生成Excel文件進行數據的展示&#xff0c;或者用于進行郵箱發送進行附件添加 依賴引入 此處demo使用maven依賴進行使用 <dependency><groupId>org.apache.poi</groupId>&…

mac 下 java 調用 gurobi 不能加載 jar

在 mac 電腦中的 java 始終不能加載 gurobi 的 jar 包&#xff0c;java 的開發軟件 eclipse&#xff0c;idea 總是顯示找不到 gurobi 的 jar 包&#xff0c;但是 jar 包明明就在那里。 摸索了三個小時&#xff0c;最后發現原因竟然是&#xff1a; jar 包太新&#xff0c;替換…

服務端配置TCP探活,超出探活時間后的行為?

server端啟動 &#xff08;完整源碼在最后&#xff09; 配置探活 setsockopt(client_fd, IPPROTO_TCP, TCP_KEEPIDLE, &(int){5}, sizeof(int)); // 空閑60秒后探測setsockopt(client_fd, IPPROTO_TCP, TCP_KEEPINTVL, &(int){10}, sizeof(int)); // 探測間隔10秒…

LLC諧振變換器恒壓恒流雙競爭閉環simulink仿真

1.模型簡介 本仿真模型基于MATLAB/Simulink&#xff08;版本MATLAB 2017Ra&#xff09;軟件。建議采用matlab2017 Ra及以上版本打開。&#xff08;若需要其他版本可聯系代為轉換&#xff09;針對全橋LLC拓撲&#xff0c;利用Matlab軟件搭建模型&#xff0c;分別對輕載&#xf…

MySQL 中如何查看 SQL 的執行計劃?

SQL 語句前面使用 EXPLAIN 關鍵字&#xff1a; EXPLAIN SELECT * FROM users WHERE id 1; 字段 含義 id 查詢的序號&#xff08;如果是子查詢或聯合查詢&#xff0c;會有多個 id&#xff09;。 select_type 查詢的類型&#xff08;簡單查詢、子查詢、聯合查詢等&#xff…

Discourse 中集成 Claude 3.7 Sonnet 模型

如果 Discourse 實例已經接入了 Anthropic。 那么只需要在后臺挑一個不希望繼續使用的模型改下就好。 否則需要重新在 Discourse 實例中配置 AI&#xff0c;然后獲得 Anthropic 的 key。 進入后臺的 AI 然后選擇 LLMs 雖然我們這里已經顯示成 3.7 了&#xff0c;但實際上所有…

Oracle 12c Docker安裝問題排查 sga_target 1536M is too small

一、問題描述 在虛擬機環境&#xff08;4核16GB內存&#xff09;上部署 truevoly/oracle-12c 容器鏡像時&#xff0c;一切運行正常。然而&#xff0c;當在一臺 128 核 CPU 和 512GB 內存的物理服務器上運行時&#xff0c;容器啟動時出現了 ORA-00821 等錯誤&#xff0c;提示 S…

DeepSeek 提示詞:高效的提示詞設計

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家&#xff0c;歷代文學網&#xff08;PC端可以訪問&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移動端可微信小程序搜索“歷代文學”&#xff09;總架構師&#xff0c;15年工作經驗&#xff0c;精通Java編…

KIMI K1.5:大規模強化學習在大語言模型中的應用與工程實踐

目錄 1、核心技術創新:長上下文強化學習 2、策略優化的技術細節 2.1、在線鏡像下降變體 2.2、長度懲罰機制 2.3、智能采樣策略 3、工程架構創新 3.1、混合部署框架 3.2、代碼沙箱與獎勵模型 3.3、分布式系統架構 4、實驗成果與性能提升 5、結論與未來展望 大語言模…

從 0 到 1:使用 Docker 部署個人博客系統

引言 在當今數字化時代&#xff0c;擁有一個個人博客來記錄自己的學習、生活和見解是一件非常有意義的事情。然而&#xff0c;傳統的博客部署方式往往涉及復雜的環境配置和依賴管理&#xff0c;容易讓人望而卻步。而 Docker 的出現&#xff0c;為我們提供了一種簡單、高效的解…

多進程網絡服務端詳細說明文檔

多進程網絡服務端詳細說明文檔 一、概述 本項目實現了一個基于多進程的 TCP 網絡服務端&#xff0c;主要用于處理多個客戶端的連接請求。為了提高代碼的可維護性和可復用性&#xff0c;分成了頭文件&#xff08;.h&#xff09;和多個源文件&#xff08;.cpp&#xff09;。具體…

HDFS數據多目錄、異構存儲、回收站

1.NameNode元數據多目錄 HDFS集群中可以在hdfs-site.xml中配置“dfs.namenode.name.dir”屬性來指定NameNode存儲數據的目錄&#xff0c;默認NameNode數據存儲在${hadoop.tmp.dir}/dfs/name目錄&#xff0c;“hadoop.tmp.dir”配置項在core-site.xml中。 我們也可以將NameNod…

TFChat:騰訊大模型知識引擎(DeepSeek R1)+飛書機器人實現AI智能助手

效果 TFChat項目地址 https://github.com/fish2018/TFChat 騰訊大模型知識引擎用的是DeepSeek R1&#xff0c;項目為sanic和redis實現&#xff0c;利用httpx異步處理流式響應&#xff0c;同時使用buffer來避免頻繁調用飛書接口更新卡片的網絡耗時。為了進一步減少網絡IO消耗&…

HTML5 面試題

1. HTML5 新增了哪些重要特性&#xff1f; 語義化標簽&#xff1a;這些標簽有助于提高頁面的可讀性和可維護性。多媒體支持&#xff1a;HTML5 引入了 和 標簽&#xff0c;可以直接嵌入音頻和視頻文件&#xff0c;無需依賴插件。本地存儲&#xff1a;引入了 localStorage 和 se…

【Linux】Linux常用命令

目錄 文件和目錄相關命令查看和管理進程磁盤和文件系統管理用戶和權限管理網絡相關命令文本處理命令系統狀態查看命令軟件包管理命令計劃任務和后臺作業其他常用命令 1. 文件和目錄相關命令 命令作用示例pwd顯示當前工作目錄pwdls列出目錄內容ls -l 查看詳細信息cd切換目錄cd…

布署elfk-準備工作

建議申請5臺機器部署elfk&#xff1a; filebeat(每臺app)--> logstash(2臺keepalived)--> elasticsearch(3臺)--> kibana(部署es上)采集輸出 處理轉發 分布式存儲 展示 ELK中文社區: 搜索客&#xff0c;搜索人自己的社區 官方…

DeepSeek:我的AI助手之旅

★【前言】: 初次使用AI助手幫我寫作,就像摸石頭過河一樣,一點點的前行。我在慢慢的摸索,慢慢的體會中,感悟出的一點個人心得體會現分享給大家。這也說明一個問題,網站上各種使用方法和技巧是對于已經使用過的人來說的方便和快捷,但對于剛剛接觸的使用者來說,網上的各…

esp8266 rtos sdk開發環境搭建

1. 安裝必要的工具 1.1 安裝 Git Git 用于從遠程倉庫克隆代碼&#xff0c;你可以從Git 官方網站下載 Windows 版本的安裝程序。安裝過程中可保持默認設置&#xff0c;安裝完成后&#xff0c;在命令提示符&#xff08;CMD&#xff09;或 PowerShell 中輸入git --version&#…