Redis:19---常用功能之(HyperLogLog)

一、HyperLogLog概述

  • HyperLogLog并不是一種新的數據結構(實際類型為字符串類型),而是一種基數算法,通過HyperLogLog可以利用極小的內存空間完成獨立總數的統計,數據集可以是IP、Email、ID等

  • HyperLogLog提供了3個命令:pfadd、pfcount、pfmerge

  • ?

二、添加(pfadd)

pfadd key element [element …]
  • pfadd用于向HyperLogLog添加元素,如果添加成功返回1

  • 例如:下面向一個名為2016_06_06:unique:ids的hyperloglog中添加4個元素

?

三、計算獨立用戶數(pfcount)

pfcount key [key …]
  • pfcount用于計算一個或多個HyperLogLog的獨立總數

  • 例如:接著上面的演示案例,2016_03_06:unique:ids的獨立總數為4:

?

內存節省效果演示案例

  • ①插入前使用info memory查看一下內存占用率

?

  • ②下面建立一個名為test.sh的腳本,執行該腳本,向key為2016_05_01:unique:ids的HyperLogLog中插入100萬個元素(循環每次插入1000條)

elements=""
key="2016_05_01:unique:ids"
for i in `seq 1 1000000`
do
elements="${elements} uuid-"${i}
if [[ $((i%1000)) == 0 ]];
then
redis-cli pfadd ${key} ${elements}
elements=""
fi
done

?

  • ③執行完腳本之后,再次查看內存,發現內存只增加了14K左右

  • ④但是,使用pfcount查看結果,發現執行的結果并不止100萬個

  • ⑤現在改為使用集合類型進行測試,那么可以看到內存使用率在腳本執行完之后漲到了幾十MB,但是獨立用戶數為100萬

elements=""
key="2016_05_01:unique:ids:set"
for i in `seq 1 1000000`
do
elements="${elements} "${i}
if [[ $((i%1000)) == 0 ]];
then
redis-cli sadd ${key} ${elements}
elements=""
fi
done

  • 下圖列出了使用集合類型和HperLogLog統計百萬級用戶的占用空間對比:

數據類型

1天

1月

1年

集合類型

80M

2.4G

28G

HperLogLog

15K

450K

5M

  • 可以看到,HyperLogLog內存占用量小得驚人,但是用如此小空間來估算如此巨大的數據,必然不是100%的正確,其中一定存在誤差率。Redis官方給出的數字是0.81%的失誤率

四、合并(pfmerge)

pfmerge destkey sourcekey [sourcekey ...]
  • pfmerge可以求出多個HyperLogLog的并集并賦值給destkey

  • 例如:要計算 2016年3月5日和3月6日的訪問獨立用戶數,可以按照如下方式來執行,可以看到最終獨立用戶數是7:

五、HyperLogLog優缺點與使用建議

  • HyperLogLog內存占用量非常小,但是存在錯誤率

  • 開發者在進行數據結構選型時只需要確認如下兩條即可:

    • 只為了計算獨立總數,不需要獲取單條數據

    • 可以容忍一定誤差率,畢竟HyperLogLog在內存的占用量上有很大的優勢

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

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

相關文章

計算時間差的Oracle函數

Oracle函數可以實現諸多的功能,下面就介紹使用Oracle函數計算時間差的實現方法,如果您對Oracle函數方面感興趣的話,不妨一看。 兩個Date類型字段:START_DATE,END_DATE,計算這兩個日期的時間差(分…

leetcode181. 超過經理收入的員工(SQL)

Employee 表包含所有員工,他們的經理也屬于員工。每個員工都有一個 Id,此外還有一列對應員工的經理的 Id。 ------------------------------ | Id | Name | Salary | ManagerId | ------------------------------ | 1 | Joe | 70000 | 3 |…

UNIX(多線程):01---線程簡介及線程限制

一、線程的概念 典型的UNIX進程可以看成只有一個控制線程:一個進程在同一時刻只做一件事。有了多個控制線程后,在程序設計時可以把進程設計成在同一時刻能夠做不止一件事,每個線程處理各自獨立的任務二、線程的優點 通過為每種事件類型分配單獨的處理線程,可以簡化處理異步…

UNIX(多線程):13---condition_variable、wait、notify_one、notify_all

條件變量std::condition_variable、wait()、notify_one() 線程A: 等待一個條件滿足線程B: 專門往消息隊列中放入消息(數據),達到一定條件,通知處于等待中的線程A。std::condition_variable實際上是一個類,是一個和條件相關的一個類,說白了就是等待一個條件達成。這個類是…

leetcode176. 第二高的薪水(SQL)

編寫一個 SQL 查詢,獲取 Employee 表中第二高的薪水(Salary) 。 ------------ | Id | Salary | ------------ | 1 | 100 | | 2 | 200 | | 3 | 300 | ------------ 例如上述 Employee 表,SQL查詢應該返回 200 作為第二…

UNIX(多線程):17---異步任務提供者(Provider) 介紹

std::promise 類概述 Promise 對象可以保存某一類型 T 的值,該值可被 future 對象讀取(可能在另外一個線程中),因此 promise 也提供了一種線程同步的手段。在 promise 對象構造時可以和一個共享狀態(通常是std::future)相關聯,并可以在相關聯的共享狀態(std::future)上保…

leetcode180. 連續出現的數字(SQL)

編寫一個 SQL 查詢,查找所有至少連續出現三次的數字。 --------- | Id | Num | --------- | 1 | 1 | | 2 | 1 | | 3 | 1 | | 4 | 2 | | 5 | 1 | | 6 | 2 | | 7 | 2 | --------- 例如,給定上面的 Logs 表, 1 是唯一連續…

UNIX(多線程):18---異步任務提供者(Provider) 介紹(續)

本文主要介紹 std::packaged_task。 std::packaged_task 包裝一個可調用的對象,并且允許異步獲取該可調用對象產生的結果,從包裝可調用對象意義上來講,std::packaged_task 與 std::function 類似,只不過 std::packaged_task 將其包裝的可調用對象的執行結果傳遞給一個 std:…

leetcode182. 查找重復的電子郵箱(SQL)

編寫一個 SQL 查詢,查找 Person 表中所有重復的電子郵箱。 示例: ------------- | Id | Email | ------------- | 1 | ab.com | | 2 | cd.com | | 3 | ab.com | ------------- 根據以上輸入,你的查詢應返回以下結果: ----…

UNIX(多線程):19---Future 類型詳解

Future 類型詳解 本文主要介紹 std::future,std::shared_future 以及 std::future_error,另外還會介紹 <future> 頭文件中的 std::async,std::future_category 函數以及相關枚舉類型。 std::future 詳解 std::future 概述 前面已經多次提到過 std::future,那么 std::…

UNIX(多線程):20---生產者消費者實例

本文將綜合運用 C++11 中的新的基礎設施(主要是多線程、鎖、條件變量)來闡述一個經典問題——生產者消費者模型,并給出完整的解決方案。 生產者消費者問題是多線程并發中一個非常經典的問題,相信學過操作系統課程的同學都清楚這個問題的根源。本文將就四種情況分析并介紹生產…

leetcode183. 從不訂購的客戶(SQL)

某網站包含兩個表&#xff0c;Customers 表和 Orders 表。編寫一個 SQL 查詢&#xff0c;找出所有從不訂購任何東西的客戶。 Customers 表&#xff1a; ----------- | Id | Name | ----------- | 1 | Joe | | 2 | Henry | | 3 | Sam | | 4 | Max | ----------- Or…

UNIX(多線程):21---線程池實現原理

線程池簡介: 線程過多會帶來調度開銷,進而影響緩存局部性和整體性能。 而線程池維護著多個線程,等待著監督管理者分配可并發執行的任務。這避免了在處理短時間任務時創建與銷毀線程的代價。線程池不僅能夠保證內核的充分利用,還能防止過分調度。可用線程數量應該取決于可用…

leetcode197. 上升的溫度(SQL)

給定一個 Weather 表&#xff0c;編寫一個 SQL 查詢&#xff0c;來查找與之前&#xff08;昨天的&#xff09;日期相比溫度更高的所有日期的 Id。 --------------------------------------------- | Id(INT) | RecordDate(DATE) | Temperature(INT) | -----------------------…

UNIX(多線程):22---幾種常見的線程池

常見線程池 1、newSingleThreadExecutor 創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。 從構造方法來看,它可以單獨執行,也可以與周期線程池結合用。其任務隊列是LinkedBlockingQueue,這是個無界的阻塞…

js正則表達式限制文本框只能輸入數字,小數點,英文字母

1.文本框只能輸入數字代碼(小數點也不能輸入)<input οnkeyup"this.valuethis.value.replace(/\D/g,)" onafterpaste"this.valuethis.value.replace(/\D/g,)"> 2.只能輸入數字,能輸小數點. <input οnkeyup"if(isNaN(value))execCommand(und…

UNIX(多線程):23---線程池注意事項和常見問題

使用線程池的注意事項 死鎖任何多線程程序都有死鎖的風險,最簡單的情形是兩個線程AB,A持有鎖1,請求鎖2,B持有鎖2,請求鎖1。(這種情況在mysql的排他鎖也會出現,不會數據庫會直接報錯提示)。線程池中還有另一種死鎖:假設線程池中的所有工作線程都在執行各自任務時被阻塞…

leetcode 178. 分數排名(SQL)

編寫一個 SQL 查詢來實現分數排名。如果兩個分數相同&#xff0c;則兩個分數排名&#xff08;Rank&#xff09;相同。請注意&#xff0c;平分后的下一個名次應該是下一個連續的整數值。換句話說&#xff0c;名次之間不應該有“間隔”。 ----------- | Id | Score | ----------…

UNIX(多線程):24---哪些STL容器是線程安全的

在日常C++開發,少不了和STL,多線程打交道,那么在多線程下,哪些容器時線程安全的,那些不是? 好,這里就舉一個簡單的例子,我們先看看vector容器,相信你能看出一些問題: #include <iostream> #include <string> #include <algorithm> #inclu…

leetcode184. 部門工資最高的員工(SQL) 連接+嵌套查詢

Employee 表包含所有員工信息&#xff0c;每個員工有其對應的 Id, salary 和 department Id。 --------------------------------- | Id | Name | Salary | DepartmentId | --------------------------------- | 1 | Joe | 70000 | 1 | | 2 | Henry | 80000 …