redis8.0新特性之t-digest計算數(shù)據(jù)百分位的使用
一、寫在前面
官方中文文檔:https://redis.ac.cn/docs/latest/develop/data-types/probabilistic/t-digest/
命令文檔:https://redis.ac.cn/docs/latest/commands/?group=tdigest
t-digest 是一種概率型數(shù)據(jù)結(jié)構(gòu),用于估計數(shù)據(jù)流的百分位數(shù)。
t-digest 是 Redis 開源版中的一種 sketch 數(shù)據(jù)結(jié)構(gòu),用于使用緊湊的 sketch 估計數(shù)據(jù)流或大型數(shù)據(jù)集的百分位數(shù)。
它可以回答以下問題:
數(shù)據(jù)流中有多大比例的值小于給定值?
數(shù)據(jù)流中有多少值小于給定值?
數(shù)據(jù)流中小于 p 百分比值的最高值是什么?(即 p 百分位數(shù)值是多少?)
1、什么是 t-digest?
t-digest 是一種數(shù)據(jù)結(jié)構(gòu),它可以在無需存儲和排序集合中的所有數(shù)據(jù)點的情況下估計百分位點。例如:要回答“我的數(shù)據(jù)庫操作中 99% 的平均延遲是多少?”這個問題,我們必須存儲每個用戶的平均延遲,對值進行排序,去掉最后 1%,然后才能找到其余所有值的平均值。這種過程不僅在排序這些值所需的處理方面成本高昂,而且在存儲這些值所需的空間方面也成本高昂。這正是 t-digest 解決的問題。
t-digest 還可以用于估計與百分位數(shù)相關(guān)的其他值,例如截斷均值(trimmed means)。
截斷均值是 sketch 中的平均值,不包括低于和高于截止百分位數(shù)的觀測值。例如,0.1 截斷均值是 sketch 中的平均值,不包括最低的 10% 和最高的 10% 的值。
2、使用場景
硬件/軟件監(jiān)控
您測量在線服務(wù)器響應(yīng)延遲,并希望查詢:
測得延遲的第 50、90 和 99 百分位數(shù)是多少?
測得延遲中有多大比例小于 25 毫秒?
忽略異常值后的平均延遲是多少?或者,第 10 和第 90 百分位數(shù)之間的平均延遲是多少?
在線游戲
數(shù)百萬人在您的在線游戲平臺上玩游戲,您想向每位玩家提供以下信息?
您的分數(shù)高于 x% 的游戲會話分數(shù)。
約有 y 個游戲會話中,人們的得分高于您。
要獲得比 90% 的游戲玩家更高的分數(shù),您的分數(shù)應(yīng)為 z。
網(wǎng)絡(luò)流量監(jiān)控
您測量每秒網(wǎng)絡(luò)傳輸?shù)?IP 數(shù)據(jù)包,并嘗試通過詢問以下問題來檢測拒絕服務(wù)攻擊:
最后一秒的數(shù)據(jù)包數(shù)量是否超過之前觀察到的值的 99%?
在正常網(wǎng)絡(luò)條件下,我預(yù)計會看到多少數(shù)據(jù)包?(答案:介于 x 和 y 之間,其中 x 代表第 1 百分位數(shù),y 代表第 99 百分位數(shù))。
預(yù)測性維護
測量的參數(shù)(噪聲水平、電流消耗等)是否異常?(不在 [第 1 百分位數(shù)…第 99 百分位數(shù)] 范圍內(nèi))?
我應(yīng)該將警報設(shè)置為哪些值?
二、使用
1、TDIGEST.CREATE 創(chuàng)建
# 語法 # COMPRESSION compression:是精度和內(nèi)存消耗之間可控制的權(quán)衡。對于一般用途,100 是一個常見值。1000 的精度更高。如果未傳遞值,默認壓縮為 100。 TDIGEST.CREATE key [COMPRESSION compression] # 示例 127.0.0.1:6379> TDIGEST.CREATE t COMPRESSION 100 OK
2、TDIGEST.ADD 添加元素
# 語法 # value:是觀察值(浮點數(shù))。 TDIGEST.ADD key value [value ...] # 示例,只能存放浮點數(shù),不能存字符串 127.0.0.1:6379> TDIGEST.ADD t 1 2 3 OK 127.0.0.1:6379> TDIGEST.ADD t 1.1 2.123 3.324 OK 127.0.0.1:6379> TDIGEST.ADD t string (error) ERR T-Digest: error parsing val parameter
3、TDIGEST.BYRANK 根據(jù)排名獲取值
對于每個輸入的排名,返回該排名對應(yīng)值的估計值(浮點數(shù))。
單次調(diào)用中可以檢索多個估計值。
# 語法 # rank #排名,應(yīng)檢索該排名對應(yīng)的值。 #0 是最小觀測值的排名。 #n-1 是最大觀測值的排名;n 表示添加到 sketch 的觀測值數(shù)量。 # 返回值 #數(shù)組 - 包含 value_1, value_2, ..., value_R 的浮點數(shù)組 #當 rank 為 0 時返回精確結(jié)果(最小觀測值) #當 rank 為 n-1 時返回精確結(jié)果(最大觀測值),其中 n 表示添加到 sketch 的觀測值數(shù)量。 #當 rank 等于 n 或大于 n 時返回 'inf' #如果 sketch 為空,所有值都為 'nan'。 TDIGEST.BYRANK key rank [rank ...]
127.0.0.1:6379> TDIGEST.CREATE t COMPRESSION 1000 OK 127.0.0.1:6379> TDIGEST.ADD t 1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 OK # 排行第0 就是第一,從小到大排 # 獲取排行時,如果超過元素數(shù)量,返回inf 127.0.0.1:6379> TDIGEST.BYRANK t 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1) "1" 2) "2" 3) "2" 4) "3" 5) "3" 6) "3" 7) "4" 8) "4" 9) "4" 10) "4" 11) "5" 12) "5" 13) "5" 14) "5" 15) "5" 16) "inf"
4、TDIGEST.BYREVRANK 根據(jù)倒排名獲取值
# 語法 # revrank #要檢索其值的反向排名。 #0 是最大觀測值的值的反向排名。 #n-1 是最小觀測值的值的反向排名;n 表示添加到摘要中的觀測值數(shù)量。 # 返回值為數(shù)組 - 一個由 value_1, value_2, ..., value_R 等浮點數(shù)填充的數(shù)組 #當 revrank 為 0 時(最大觀測值的值),返回準確結(jié)果 #當 revrank 為 n-1 時(最小觀測值的值),返回準確結(jié)果,其中 n 表示添加到摘要中的觀測值數(shù)量。 #當 revrank 等于或大于 n 時,返回 '-inf' #如果摘要為空,則所有值均為 'nan'。 TDIGEST.BYREVRANK key reverse_rank [reverse_rank ...]
redis> TDIGEST.CREATE t COMPRESSION 1000 OK redis> TDIGEST.ADD t 1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 OK # 獲取倒排名,從大到小排 redis> TDIGEST.BYREVRANK t 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1) "5" 2) "5" 3) "5" 4) "5" 5) "5" 6) "4" 7) "4" 8) "4" 9) "4" 10) "3" 11) "3" 12) "3" 13) "2" 14) "2" 15) "1" 16) "-inf"
5、TDIGEST.CDF 根據(jù)值獲取比例
對于每個輸入值,返回小于給定值(加上等于給定值的一半觀測值)的觀測值所占比例(浮點數(shù))的估計值。
(聽起來有點拗口,具體看例子)
# 語法 TDIGEST.CDF key value [value ...]
redis> TDIGEST.CREATE t COMPRESSION 1000 OK redis> TDIGEST.ADD t 1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 OK # 小于觀測數(shù)的比例+等于觀測數(shù)的比例/2 redis> TDIGEST.CDF t 0 1 2 3 4 5 6 1) "0" 2) "0.033333333333333333" 3) "0.13333333333333333" 4) "0.29999999999999999" 5) "0.53333333333333333" 6) "0.83333333333333337" 7) "1" # 如下例子,元素總數(shù)為15,小于5的元素有10個,所以小于5的元素比例為0.6666666667 # 等于5的元素有5個,所以等于5的元素比例為0.3333333333333333 # 所以結(jié)果為0.6666666667 + 0.3333333333333333/2 = 0.8333333333333334 # 相當于結(jié)果為(10+5/2) / 15 = 12.5/15 = 0.8333333333333334 127.0.0.1:6379> TDIGEST.CDF t 5 1) "0.8333333333333334"
6、TDIGEST.INFO 獲取t-digest信息
# 語法 TDIGEST.INFO key # 返回值 壓縮 整數(shù)回復(fù) sketch 的壓縮率(可在準確性和內(nèi)存消耗之間進行權(quán)衡控制) 容量 整數(shù)回復(fù) 用于存儲質(zhì)心和傳入的未合并觀察值的緩沖大小 已合并節(jié)點 整數(shù)回復(fù) 已合并觀察值的數(shù)量 未合并節(jié)點 整數(shù)回復(fù) 緩沖節(jié)點(未壓縮觀察值)的數(shù)量 已合并權(quán)重 整數(shù)回復(fù) 已合并節(jié)點值的權(quán)重 未合并權(quán)重 整數(shù)回復(fù) 未合并節(jié)點(未壓縮觀察值)值的權(quán)重 觀察值 整數(shù)回復(fù) 添加到 sketch 的觀察值數(shù)量 總壓縮次數(shù) 整數(shù)回復(fù) 此 sketch 對數(shù)據(jù)進行壓縮的次數(shù) 內(nèi)存使用量 整數(shù)回復(fù) 為 sketch 分配的字節(jié)數(shù)
redis> TDIGEST.CREATE t OK redis> TDIGEST.ADD t 1 2 3 4 5 OK redis> TDIGEST.INFO t 1) Compression 2) (integer) 100 3) Capacity 4) (integer) 610 5) Merged nodes 6) (integer) 0 7) Unmerged nodes 8) (integer) 5 9) Merged weight 10) (integer) 0 11) Unmerged weight 12) (integer) 5 13) Observations 14) (integer) 5 15) Total compressions 16) (integer) 0 17) Memory usage 18) (integer) 9768
7、TDIGEST.MAX 獲取最大值
# 語法 TDIGEST.MAX key # 示例 redis> TDIGEST.CREATE t OK redis> TDIGEST.MAX t "nan" redis> TDIGEST.ADD t 3 4 1 2 5 OK redis>TDIGEST.MAX t "5"
8、TDIGEST.MIN 獲取最小值
# 語法 TDIGEST.MIN key # 示例 redis> TDIGEST.CREATE t OK redis> TDIGEST.MIN t "nan" redis> TDIGEST.ADD t 3 4 1 2 5 OK redis> TDIGEST.MIN t "1"
9、TDIGEST.MERGE合并
# 語法 # destination-key #是用于合并觀察值的 t-digest 草圖的鍵名。 #如果 destination-key 不存在,則創(chuàng)建一個新的草圖。 #如果 destination-key 是現(xiàn)有草圖,其值將與源鍵的值合并。要覆蓋目標鍵的內(nèi)容,請使用 OVERRIDE。 # numkeys #要合并觀察值來源的草圖數(shù)量(1 個或更多)。 #source-key #每個都是要合并觀察值來源的 t-digest 草圖的鍵名。 # COMPRESSION compression #是準確性和內(nèi)存消耗之間可控的權(quán)衡。100 是常見的值,適用于一般用途。1000 更準確。如果未傳遞值,默認壓縮值為 100。 #未指定 COMPRESSION 時 #如果 destination-key 不存在或指定了 OVERRIDE,則壓縮值設(shè)置為所有源草圖中的最大值。 #如果 destination-key 已存在且未指定 OVERRIDE,則其壓縮值不會改變。 #OVERRIDE #指定時,如果 `destination-key` 已存在,則會覆蓋它。 TDIGEST.MERGE destination-key numkeys source-key [source-key ...] [COMPRESSION compression] [OVERRIDE]
redis> TDIGEST.CREATE s1 OK redis> TDIGEST.CREATE s2 OK redis> TDIGEST.ADD s1 10.0 20.0 OK redis> TDIGEST.ADD s2 30.0 40.0 OK # 將s1、s2這兩個 合并到sM redis> TDIGEST.MERGE sM 2 s1 s2 OK redis> TDIGEST.BYRANK sM 0 1 2 3 4 1) "10" 2) "20" 3) "30" 4) "40" 5) "inf"
10、TDIGEST.QUANTILE 根據(jù)比例獲取元素
對于每個輸入的比例,返回小于該比例觀測值的估算值(浮點數(shù))。
# 語法 # quantile #輸入比例(0 到 1 之間,包含 0 和 1) # 返回值為數(shù)組 - 一個包含估算值(浮點數(shù))的數(shù)組,形如 value_1, value_2, ..., value_N。 #當 quantile 為 0 時(最小觀測值),返回準確結(jié)果 #當 quantile 為 1 時(最大觀測值),返回準確結(jié)果 #如果摘要為空,則所有值為 'nan'。 TDIGEST.QUANTILE key quantile [quantile ...]
redis> TDIGEST.CREATE t COMPRESSION 1000 OK redis> TDIGEST.ADD t 1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 OK redis> TDIGEST.QUANTILE t 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 1) "1" 2) "2" 3) "3" 4) "3" 5) "4" 6) "4" 7) "4" 8) "5" 9) "5" 10) "5" 11) "5"
11、TDIGEST.RANK 根據(jù)值獲取排名
對于每個輸入值(浮點數(shù)),返回該值的估計排名(草圖中小于該值的觀測數(shù) + 等于該值的觀測數(shù)的一半)。
# 語法 #value #需要估計排名的輸入值。 # 返回值 #數(shù)組回復(fù) - 一個由 rank_1, rank_2, ..., rank_V 填充的整數(shù)數(shù)組 #-1 - 當 value 小于最小觀測值時。 #觀測值數(shù)量 - 當 value 大于最大觀測值時。 #否則:對(小于 value 的觀測數(shù) + 等于 value 的觀測數(shù)的一半)的估計值。 #0 是最小觀測值的排名。 #n-1 是最大觀測值的排名;n 表示添加到草圖中的觀測數(shù)。 #如果草圖為空,則所有值均為 -2。 TDIGEST.RANK key value [value ...]
redis> TDIGEST.CREATE s COMPRESSION 1000 OK redis> TDIGEST.ADD s 10 20 30 40 50 60 OK # 根據(jù)值獲取排名 redis> TDIGEST.RANK s 0 10 20 30 40 50 60 70 1) (integer) -1 2) (integer) 0 3) (integer) 1 4) (integer) 2 5) (integer) 3 6) (integer) 4 7) (integer) 5 8) (integer) 6 # 根據(jù)值獲取倒排名 redis> TDIGEST.REVRANK s 0 10 20 30 40 50 60 70 1) (integer) 6 2) (integer) 5 3) (integer) 4 4) (integer) 3 5) (integer) 2 6) (integer) 1 7) (integer) 0 8) (integer) -1
redis> TDIGEST.CREATE s COMPRESSION 1000 OK redis> TDIGEST.ADD s 10 10 10 10 20 20 OK # 對于每個輸入值(浮點數(shù)),返回該值的估計排名(草圖中小于該值的觀測數(shù) + 等于該值的觀測數(shù)的一半)。 redis> TDIGEST.RANK s 10 20 1) (integer) 2 2) (integer) 5 redis> TDIGEST.REVRANK s 10 20 1) (integer) 4 2) (integer) 1
12、TDIGEST.REVRANK 根據(jù)值獲取倒排名
對于每個輸入值(浮點數(shù)),返回該值的估計逆向排名(草圖中的觀察值中大于該值的數(shù)量 + 等于該值的觀察值數(shù)量的一半)。
# 語法 # value #需要估計逆向排名的輸入值。 #返回值 #Array reply - 包含 revrank_1, revrank_2, ..., revrank_V 的整數(shù)數(shù)組 #-1 - 當 value 大于最大觀察值時。 #觀察值數(shù)量 - 當 value 小于最小觀察值時。 #否則:估計的數(shù)量(大于 value 的觀察值 + 等于 value 的觀察值的一半)。 #0 是最大觀察值的逆向排名。 #n-1 是最小觀察值的逆向排名;n 表示添加到草圖中的觀察值數(shù)量。 #如果草圖為空,則所有值均為 -2。 TDIGEST.REVRANK key value [value ...]
redis> TDIGEST.CREATE s COMPRESSION 1000 OK redis> TDIGEST.ADD s 10 20 30 40 50 60 OK redis> TDIGEST.RANK s 0 10 20 30 40 50 60 70 1) (integer) -1 2) (integer) 0 3) (integer) 1 4) (integer) 2 5) (integer) 3 6) (integer) 4 7) (integer) 5 8) (integer) 6 redis> TDIGEST.REVRANK s 0 10 20 30 40 50 60 70 1) (integer) 6 2) (integer) 5 3) (integer) 4 4) (integer) 3 5) (integer) 2 6) (integer) 1 7) (integer) 0 8) (integer) -1
redis> TDIGEST.CREATE s COMPRESSION 1000 OK redis> TDIGEST.ADD s 10 10 10 10 20 20 OK redis> TDIGEST.RANK s 10 20 1) (integer) 2 2) (integer) 5 redis> TDIGEST.REVRANK s 10 20 1) (integer) 4 2) (integer) 1
13、TDIGEST.RESET清空數(shù)據(jù)
# 語法 TDIGEST.RESET key # 示例 redis> TDIGEST.RESET t OK
14、TDIGEST.TRIMMED_MEAN 求平均
返回草圖均值的估計值,排除低于或高于截斷分位數(shù)閾值的觀測值。
# 語法 # low_cut_quantile #范圍 [0..1] 的浮點數(shù)值,應(yīng)小于 high_cut_quantile #當?shù)扔?0 時:無低位截斷。 #當大于 0 時:排除低于此分位數(shù)的觀測值。 # high_cut_quantile #范圍 [0..1] 的浮點數(shù)值,應(yīng)大于 low_cut_quantile #當小于 1 時:排除大于或等于此分位數(shù)的觀測值。 #當?shù)扔?1 時:無高位截斷。 TDIGEST.TRIMMED_MEAN key low_cut_quantile high_cut_quantile
redis> TDIGEST.CREATE t COMPRESSION 1000 OK redis> TDIGEST.ADD t 1 2 3 4 5 6 7 8 9 10 OK redis> TDIGEST.TRIMMED_MEAN t 0.1 0.6 "4" redis> TDIGEST.TRIMMED_MEAN t 0.3 0.9 "6.5" redis> TDIGEST.TRIMMED_MEAN t 0 1 "5.5"
到此這篇關(guān)于redis8.0新特性之t-digest計算數(shù)據(jù)百分位的使用的文章就介紹到這了,更多相關(guān)redis8.0 t-digest內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
redis哨兵模式分布式鎖實現(xiàn)與實踐方式(redisson)
這篇文章主要介紹了redis哨兵模式分布式鎖實現(xiàn)與實踐方式(redisson),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03

