redis8.0新特性之t-digest計(jì)算數(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),用于估計(jì)數(shù)據(jù)流的百分位數(shù)。
t-digest 是 Redis 開源版中的一種 sketch 數(shù)據(jù)結(jié)構(gòu),用于使用緊湊的 sketch 估計(jì)數(shù)據(jù)流或大型數(shù)據(jù)集的百分位數(shù)。
它可以回答以下問(wèn)題:
數(shù)據(jù)流中有多大比例的值小于給定值?
數(shù)據(jù)流中有多少值小于給定值?
數(shù)據(jù)流中小于 p 百分比值的最高值是什么?(即 p 百分位數(shù)值是多少?)
1、什么是 t-digest?
t-digest 是一種數(shù)據(jù)結(jié)構(gòu),它可以在無(wú)需存儲(chǔ)和排序集合中的所有數(shù)據(jù)點(diǎn)的情況下估計(jì)百分位點(diǎn)。例如:要回答“我的數(shù)據(jù)庫(kù)操作中 99% 的平均延遲是多少?”這個(gè)問(wèn)題,我們必須存儲(chǔ)每個(gè)用戶的平均延遲,對(duì)值進(jìn)行排序,去掉最后 1%,然后才能找到其余所有值的平均值。這種過(guò)程不僅在排序這些值所需的處理方面成本高昂,而且在存儲(chǔ)這些值所需的空間方面也成本高昂。這正是 t-digest 解決的問(wèn)題。
t-digest 還可以用于估計(jì)與百分位數(shù)相關(guān)的其他值,例如截?cái)嗑担╰rimmed means)。
截?cái)嗑凳?sketch 中的平均值,不包括低于和高于截止百分位數(shù)的觀測(cè)值。例如,0.1 截?cái)嗑凳?sketch 中的平均值,不包括最低的 10% 和最高的 10% 的值。
2、使用場(chǎng)景
硬件/軟件監(jiān)控
您測(cè)量在線服務(wù)器響應(yīng)延遲,并希望查詢:
測(cè)得延遲的第 50、90 和 99 百分位數(shù)是多少?
測(cè)得延遲中有多大比例小于 25 毫秒?
忽略異常值后的平均延遲是多少?或者,第 10 和第 90 百分位數(shù)之間的平均延遲是多少?
在線游戲
數(shù)百萬(wàn)人在您的在線游戲平臺(tái)上玩游戲,您想向每位玩家提供以下信息?
您的分?jǐn)?shù)高于 x% 的游戲會(huì)話分?jǐn)?shù)。
約有 y 個(gè)游戲會(huì)話中,人們的得分高于您。
要獲得比 90% 的游戲玩家更高的分?jǐn)?shù),您的分?jǐn)?shù)應(yīng)為 z。
網(wǎng)絡(luò)流量監(jiān)控
您測(cè)量每秒網(wǎng)絡(luò)傳輸?shù)?IP 數(shù)據(jù)包,并嘗試通過(guò)詢問(wèn)以下問(wèn)題來(lái)檢測(cè)拒絕服務(wù)攻擊:
最后一秒的數(shù)據(jù)包數(shù)量是否超過(guò)之前觀察到的值的 99%?
在正常網(wǎng)絡(luò)條件下,我預(yù)計(jì)會(huì)看到多少數(shù)據(jù)包?(答案:介于 x 和 y 之間,其中 x 代表第 1 百分位數(shù),y 代表第 99 百分位數(shù))。
預(yù)測(cè)性維護(hù)
測(cè)量的參數(shù)(噪聲水平、電流消耗等)是否異常?(不在 [第 1 百分位數(shù)…第 99 百分位數(shù)] 范圍內(nèi))?
我應(yīng)該將警報(bào)設(shè)置為哪些值?
二、使用
1、TDIGEST.CREATE 創(chuàng)建
# 語(yǔ)法 # COMPRESSION compression:是精度和內(nèi)存消耗之間可控制的權(quán)衡。對(duì)于一般用途,100 是一個(gè)常見值。1000 的精度更高。如果未傳遞值,默認(rèn)壓縮為 100。 TDIGEST.CREATE key [COMPRESSION compression] # 示例 127.0.0.1:6379> TDIGEST.CREATE t COMPRESSION 100 OK
2、TDIGEST.ADD 添加元素
# 語(yǔ)法 # value:是觀察值(浮點(diǎn)數(shù))。 TDIGEST.ADD key value [value ...] # 示例,只能存放浮點(diǎn)數(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ù)排名獲取值
對(duì)于每個(gè)輸入的排名,返回該排名對(duì)應(yīng)值的估計(jì)值(浮點(diǎn)數(shù))。
單次調(diào)用中可以檢索多個(gè)估計(jì)值。
# 語(yǔ)法 # rank #排名,應(yīng)檢索該排名對(duì)應(yīng)的值。 #0 是最小觀測(cè)值的排名。 #n-1 是最大觀測(cè)值的排名;n 表示添加到 sketch 的觀測(cè)值數(shù)量。 # 返回值 #數(shù)組 - 包含 value_1, value_2, ..., value_R 的浮點(diǎn)數(shù)組 #當(dāng) rank 為 0 時(shí)返回精確結(jié)果(最小觀測(cè)值) #當(dāng) rank 為 n-1 時(shí)返回精確結(jié)果(最大觀測(cè)值),其中 n 表示添加到 sketch 的觀測(cè)值數(shù)量。 #當(dāng) rank 等于 n 或大于 n 時(shí)返回 '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í),如果超過(guò)元素?cái)?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ù)倒排名獲取值
# 語(yǔ)法 # revrank #要檢索其值的反向排名。 #0 是最大觀測(cè)值的值的反向排名。 #n-1 是最小觀測(cè)值的值的反向排名;n 表示添加到摘要中的觀測(cè)值數(shù)量。 # 返回值為數(shù)組 - 一個(gè)由 value_1, value_2, ..., value_R 等浮點(diǎn)數(shù)填充的數(shù)組 #當(dāng) revrank 為 0 時(shí)(最大觀測(cè)值的值),返回準(zhǔn)確結(jié)果 #當(dāng) revrank 為 n-1 時(shí)(最小觀測(cè)值的值),返回準(zhǔn)確結(jié)果,其中 n 表示添加到摘要中的觀測(cè)值數(shù)量。 #當(dāng) revrank 等于或大于 n 時(shí),返回 '-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ù)值獲取比例
對(duì)于每個(gè)輸入值,返回小于給定值(加上等于給定值的一半觀測(cè)值)的觀測(cè)值所占比例(浮點(diǎn)數(shù))的估計(jì)值。
(聽起來(lái)有點(diǎn)拗口,具體看例子)
# 語(yǔ)法 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 # 小于觀測(cè)數(shù)的比例+等于觀測(cè)數(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個(gè),所以小于5的元素比例為0.6666666667 # 等于5的元素有5個(gè),所以等于5的元素比例為0.3333333333333333 # 所以結(jié)果為0.6666666667 + 0.3333333333333333/2 = 0.8333333333333334 # 相當(dāng)于結(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信息
# 語(yǔ)法 TDIGEST.INFO key # 返回值 壓縮 整數(shù)回復(fù) sketch 的壓縮率(可在準(zhǔn)確性和內(nèi)存消耗之間進(jìn)行權(quán)衡控制) 容量 整數(shù)回復(fù) 用于存儲(chǔ)質(zhì)心和傳入的未合并觀察值的緩沖大小 已合并節(jié)點(diǎn) 整數(shù)回復(fù) 已合并觀察值的數(shù)量 未合并節(jié)點(diǎn) 整數(shù)回復(fù) 緩沖節(jié)點(diǎn)(未壓縮觀察值)的數(shù)量 已合并權(quán)重 整數(shù)回復(fù) 已合并節(jié)點(diǎn)值的權(quán)重 未合并權(quán)重 整數(shù)回復(fù) 未合并節(jié)點(diǎn)(未壓縮觀察值)值的權(quán)重 觀察值 整數(shù)回復(fù) 添加到 sketch 的觀察值數(shù)量 總壓縮次數(shù) 整數(shù)回復(fù) 此 sketch 對(duì)數(shù)據(jù)進(jìn)行壓縮的次數(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 獲取最大值
# 語(yǔ)法 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 獲取最小值
# 語(yǔ)法 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合并
# 語(yǔ)法 # destination-key #是用于合并觀察值的 t-digest 草圖的鍵名。 #如果 destination-key 不存在,則創(chuàng)建一個(gè)新的草圖。 #如果 destination-key 是現(xiàn)有草圖,其值將與源鍵的值合并。要覆蓋目標(biāo)鍵的內(nèi)容,請(qǐng)使用 OVERRIDE。 # numkeys #要合并觀察值來(lái)源的草圖數(shù)量(1 個(gè)或更多)。 #source-key #每個(gè)都是要合并觀察值來(lái)源的 t-digest 草圖的鍵名。 # COMPRESSION compression #是準(zhǔn)確性和內(nèi)存消耗之間可控的權(quán)衡。100 是常見的值,適用于一般用途。1000 更準(zhǔn)確。如果未傳遞值,默認(rèn)壓縮值為 100。 #未指定 COMPRESSION 時(shí) #如果 destination-key 不存在或指定了 OVERRIDE,則壓縮值設(shè)置為所有源草圖中的最大值。 #如果 destination-key 已存在且未指定 OVERRIDE,則其壓縮值不會(huì)改變。 #OVERRIDE #指定時(shí),如果 `destination-key` 已存在,則會(huì)覆蓋它。 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這兩個(gè) 合并到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ù)比例獲取元素
對(duì)于每個(gè)輸入的比例,返回小于該比例觀測(cè)值的估算值(浮點(diǎn)數(shù))。
# 語(yǔ)法 # quantile #輸入比例(0 到 1 之間,包含 0 和 1) # 返回值為數(shù)組 - 一個(gè)包含估算值(浮點(diǎn)數(shù))的數(shù)組,形如 value_1, value_2, ..., value_N。 #當(dāng) quantile 為 0 時(shí)(最小觀測(cè)值),返回準(zhǔn)確結(jié)果 #當(dāng) quantile 為 1 時(shí)(最大觀測(cè)值),返回準(zhǔn)確結(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ù)值獲取排名
對(duì)于每個(gè)輸入值(浮點(diǎn)數(shù)),返回該值的估計(jì)排名(草圖中小于該值的觀測(cè)數(shù) + 等于該值的觀測(cè)數(shù)的一半)。
# 語(yǔ)法 #value #需要估計(jì)排名的輸入值。 # 返回值 #數(shù)組回復(fù) - 一個(gè)由 rank_1, rank_2, ..., rank_V 填充的整數(shù)數(shù)組 #-1 - 當(dāng) value 小于最小觀測(cè)值時(shí)。 #觀測(cè)值數(shù)量 - 當(dāng) value 大于最大觀測(cè)值時(shí)。 #否則:對(duì)(小于 value 的觀測(cè)數(shù) + 等于 value 的觀測(cè)數(shù)的一半)的估計(jì)值。 #0 是最小觀測(cè)值的排名。 #n-1 是最大觀測(cè)值的排名;n 表示添加到草圖中的觀測(cè)數(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 # 對(duì)于每個(gè)輸入值(浮點(diǎn)數(shù)),返回該值的估計(jì)排名(草圖中小于該值的觀測(cè)數(shù) + 等于該值的觀測(cè)數(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ù)值獲取倒排名
對(duì)于每個(gè)輸入值(浮點(diǎn)數(shù)),返回該值的估計(jì)逆向排名(草圖中的觀察值中大于該值的數(shù)量 + 等于該值的觀察值數(shù)量的一半)。
# 語(yǔ)法 # value #需要估計(jì)逆向排名的輸入值。 #返回值 #Array reply - 包含 revrank_1, revrank_2, ..., revrank_V 的整數(shù)數(shù)組 #-1 - 當(dāng) value 大于最大觀察值時(shí)。 #觀察值數(shù)量 - 當(dāng) value 小于最小觀察值時(shí)。 #否則:估計(jì)的數(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ù)
# 語(yǔ)法 TDIGEST.RESET key # 示例 redis> TDIGEST.RESET t OK
14、TDIGEST.TRIMMED_MEAN 求平均
返回草圖均值的估計(jì)值,排除低于或高于截?cái)喾治粩?shù)閾值的觀測(cè)值。
# 語(yǔ)法 # low_cut_quantile #范圍 [0..1] 的浮點(diǎn)數(shù)值,應(yīng)小于 high_cut_quantile #當(dāng)?shù)扔?0 時(shí):無(wú)低位截?cái)唷? #當(dāng)大于 0 時(shí):排除低于此分位數(shù)的觀測(cè)值。 # high_cut_quantile #范圍 [0..1] 的浮點(diǎn)數(shù)值,應(yīng)大于 low_cut_quantile #當(dāng)小于 1 時(shí):排除大于或等于此分位數(shù)的觀測(cè)值。 #當(dāng)?shù)扔?1 時(shí):無(wú)高位截?cái)唷? 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計(jì)算數(shù)據(jù)百分位的使用的文章就介紹到這了,更多相關(guān)redis8.0 t-digest內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Redis在項(xiàng)目中常見的12種使用場(chǎng)景示例和說(shuō)明
Redis是一個(gè)開源的高性能鍵值對(duì)數(shù)據(jù)庫(kù),它以其內(nèi)存中數(shù)據(jù)存儲(chǔ)、鍵過(guò)期策略、持久化、事務(wù)、豐富的數(shù)據(jù)類型支持以及原子操作等特性,在許多項(xiàng)目中扮演著關(guān)鍵角色,以下是整理的12個(gè)Redis在項(xiàng)目中常見的使用場(chǎng)景舉例說(shuō)明和解釋2024-06-06
Redis分布式鎖與Redlock算法實(shí)現(xiàn)
在Redis中,可以使用多種方式實(shí)現(xiàn)分布式鎖,如使用SETNX命令或RedLock算法,本文就來(lái)介紹一下Redis分布式鎖與Redlock算法實(shí)現(xiàn),感興趣的可以了解一下2023-12-12
如何基于Session實(shí)現(xiàn)短信登錄功能
對(duì)比起Cookie,Session是存儲(chǔ)在服務(wù)器端的會(huì)話,相對(duì)安全,并且不像Cookie那樣有存儲(chǔ)長(zhǎng)度限制,下面這篇文章主要給大家介紹了關(guān)于如何基于Session實(shí)現(xiàn)短信登錄功能的相關(guān)資料,需要的朋友可以參考下2022-10-10
如何利用 Redis 實(shí)現(xiàn)接口頻次限制
這篇文章主要介紹了如何利用 Redis 實(shí)現(xiàn)接口頻次限制,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02
redis哨兵模式分布式鎖實(shí)現(xiàn)與實(shí)踐方式(redisson)
這篇文章主要介紹了redis哨兵模式分布式鎖實(shí)現(xiàn)與實(shí)踐方式(redisson),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03

