轉(zhuǎn)-ElasticSearch - 信息聚合系列之近似聚合

信息聚合系列之近似聚合

摘要

如果所有的數(shù)據(jù)都在一臺(tái)機(jī)器上,那么生活會(huì)容易許多,CS201 課商教的經(jīng)典算法就足夠應(yīng)付這些問題。但如果所有的數(shù)據(jù)都在一臺(tái)機(jī)器上,那么就不需要像 Elasticsearch 這樣的分布式軟件了。不過一旦我們開始分布式數(shù)據(jù)存儲(chǔ),算法的選擇就需務(wù)必小心。

版本

elasticsearch版本: elasticsearch-2.x

內(nèi)容

如果所有的數(shù)據(jù)都在一臺(tái)機(jī)器上,那么生活會(huì)容易許多,CS201 課商教的經(jīng)典算法就足夠應(yīng)付這些問題。但如果所有的數(shù)據(jù)都在一臺(tái)機(jī)器上,那么就不需要像 Elasticsearch 這樣的分布式軟件了。不過一旦我們開始分布式數(shù)據(jù)存儲(chǔ),算法的選擇就需務(wù)必小心。

有些算法可以分布執(zhí)行,到目前為止討論過的所有聚合都是單次請(qǐng)求獲得精確結(jié)果的。這些類型的算法通常是高度并行的,因?yàn)樗鼈儫o須任何額外代價(jià),就能在多臺(tái)機(jī)器上并行執(zhí)行。比如當(dāng)計(jì)算?max?度量時(shí),以下的算法就非常簡單:

請(qǐng)求廣播到所有分片。

查看每個(gè)文檔的?price?字段。如果?price > current_max,將?current_max?替換成?price。

返回所有分片的最大?price?并傳給協(xié)調(diào)節(jié)點(diǎn)。

找到從所有分片返回的最大?price?。這是最終的最大值。

這個(gè)算法可以隨著機(jī)器數(shù)的線性增長而橫向擴(kuò)展,無須任何協(xié)調(diào)操作(機(jī)器之間不需要討論中間結(jié)果),而且內(nèi)存消耗很?。ㄒ粋€(gè)整型就能代表最大值)。

不幸的是,不是所有的算法都像獲取最大值這樣簡單。更加復(fù)雜的操作則需要在算法的性能和內(nèi)存使用上做出權(quán)衡。對(duì)于這個(gè)問題,我們有個(gè)三角因子模型:大數(shù)據(jù)、精確性和實(shí)時(shí)性。

我們需要選擇其中兩項(xiàng):

精確 + 實(shí)時(shí)

數(shù)據(jù)可以存入單臺(tái)機(jī)器的內(nèi)存之中,我們可以隨心所欲,使用任何想用的算法。結(jié)果會(huì) 100% 精確,響應(yīng)會(huì)相對(duì)快速。

大數(shù)據(jù) + 精確

傳統(tǒng)的 Hadoop。可以處理 PB 級(jí)的數(shù)據(jù)并且為我們提供精確的答案,但它可能需要幾周的時(shí)間才能為我們提供這個(gè)答案。

大數(shù)據(jù) + 實(shí)時(shí)

近似算法為我們提供準(zhǔn)確但不精確的結(jié)果。

Elasticsearch 目前支持兩種近似算法(cardinality(基數(shù))?和?percentiles(百分位數(shù)))。它們會(huì)提供準(zhǔn)確但不是 100% 精確的結(jié)果。以犧牲一點(diǎn)小小的估算錯(cuò)誤為代價(jià),這些算法可以為我們換來高速的執(zhí)行效率和極小的內(nèi)存消耗。

對(duì)于大多數(shù)應(yīng)用領(lǐng)域,能夠?qū)崟r(shí)返回高度準(zhǔn)確的結(jié)果要比 100% 精確結(jié)果重要得多。乍一看這可能是天方夜譚。有人會(huì)叫“我們需要精確的答案!”。但仔細(xì)考慮 0.5% 錯(cuò)誤所帶來的影響:

99% 的網(wǎng)站延時(shí)都在 132ms 以下。

0.5% 的誤差對(duì)以上延時(shí)的影響在正負(fù) 0.66ms 。

近似計(jì)算會(huì)在毫秒內(nèi)放回結(jié)果,而“完全正確”的結(jié)果就可能需要幾秒,甚至無法返回。

只要簡單的查看網(wǎng)站的延時(shí)情況,難道我們會(huì)在意近似結(jié)果是在 132.66ms 內(nèi)返回而不是 132ms?當(dāng)然,不是所有的領(lǐng)域都能容忍這種近似結(jié)果,但對(duì)于絕大多數(shù)來說是沒有問題的。接受近似結(jié)果更多的是一種文化觀念上的壁壘而不是商業(yè)或技術(shù)上的需要。

查找唯一值的數(shù)目(Finding Distinct Counts)

Elasticsearch 提供的首個(gè)近似聚合是基數(shù)度量。它提供一個(gè)字段的基數(shù),即該字段的唯一值的數(shù)目。可能會(huì)對(duì) SQL 形式比較熟悉:

SELECTDISTINCT(color)FROMcars

Distinct 計(jì)數(shù)是一個(gè)普通的操作,可以回答很多基本的商業(yè)問題:

網(wǎng)站的獨(dú)立訪問用戶(UVs)是多少?

賣了多少種汽車?

每月有多少獨(dú)立用戶購買了商品?

我們可以用基數(shù)度量確定經(jīng)銷商銷售汽車顏色的種類:

GET/cars/transactions/_search? {"size":0,"aggs": {"distinct_colors": {"cardinality": {"field":"color"}? ? ? ? ? }? ? ? }? }

返回的結(jié)果表明已經(jīng)售賣了三種不同顏色的汽車:

..."aggregations": {"distinct_colors": {"value":3}? }...

可以讓我們的例子變得更有用:每月有多少顏色的車被售出?為了得到這個(gè)度量,我們只需要將一個(gè)?cardinality?度量嵌入一個(gè)?date_histogram:

GET/cars/transactions/_search? {"size":0,"aggs": {"months": {"date_histogram": {"field":"sold","interval":"month"},"aggs": {"distinct_colors": {"cardinality": {"field":"color"}? ? ? ? ? ? }? ? ? ? ? }? ? ? ? }? ? }? }

學(xué)會(huì)權(quán)衡(Understanding the Trade-offs)

正如我們本章開頭提到的,cardinality?度量是一個(gè)近似算法。它是基于?HyperLogLog++(HLL)算法的,HLL 會(huì)先對(duì)我們的輸入作哈希運(yùn)算,然后根據(jù)哈希運(yùn)算的結(jié)果中的 bits 做概率估算從而得到基數(shù)。

我們不需要理解技術(shù)細(xì)節(jié)(如果確實(shí)感興趣,可以閱讀這篇論文),但我們最好應(yīng)該關(guān)注一下這個(gè)算法的特性:

可配置的精度,用來控制內(nèi)存的使用(更精確 = 更多內(nèi)存)。

對(duì)于低基數(shù)集能夠達(dá)到高準(zhǔn)確度。

固定的內(nèi)存使用。即使有幾千或甚至上百億的唯一值,內(nèi)存的使用也只是依賴于配置里的精度要求。

要配置精度,我們必須指定?precision_threshold?參數(shù)的值。這個(gè)閥值定義了在何種基數(shù)水平下我們希望得到一個(gè)近乎精確的結(jié)果。參考以下示例:

GET/cars/transactions/_search? {"size":0,"aggs": {"distinct_colors": {"cardinality": {"field":"color","precision_threshold":100#1}? ? ? ? ? }? ? ? }? }

#1?precision_threshold?接受 0–40,000 之間的數(shù)字,更大的值還是會(huì)被當(dāng)作 40,000 來處理。

示例會(huì)確保當(dāng)字段唯一值在 100 以內(nèi)時(shí)會(huì)得到非常準(zhǔn)確的結(jié)果。盡管算法是無法保證這點(diǎn)的,但如果基數(shù)在閥值以下,幾乎總是 100% 正確的。高于閥值的基數(shù)會(huì)開始節(jié)省內(nèi)存而犧牲準(zhǔn)確度,同時(shí)也會(huì)對(duì)度量結(jié)果帶入誤差。

對(duì)于指定的閥值,HLL 的數(shù)據(jù)結(jié)構(gòu)會(huì)大概使用內(nèi)存?precision_threshold * 8?字節(jié),所以就必須在犧牲內(nèi)存和獲得額外的準(zhǔn)確度間做平衡。

在實(shí)際應(yīng)用中,100?的閥值可以在唯一值為百萬的情況下仍然將誤差維持 5% 以內(nèi)。

速度優(yōu)化(Optimizing for Speed)

如果想要獲得唯一數(shù)目的值,通常需要查詢整個(gè)數(shù)據(jù)集合(或幾乎所有數(shù)據(jù))。所有基于所有數(shù)據(jù)的操作都必須迅速,原因是顯然的。HyperLogLog 的速度已經(jīng)很快了,它只是簡單的對(duì)數(shù)據(jù)做哈希以及一些位操作。

但如果速度對(duì)我們至關(guān)重要,可以做進(jìn)一步的優(yōu)化,因?yàn)?HLL 只需要字段內(nèi)容的哈希值,我們可以在索引時(shí)就預(yù)先計(jì)算好。就能在查詢時(shí)跳過哈希計(jì)算然后將數(shù)據(jù)信息直接加載出來。

注意

預(yù)先計(jì)算哈希值只對(duì)內(nèi)容很長或者基數(shù)很高的字段有用,計(jì)算這些字段的哈希值的消耗在查詢時(shí)是無法忽略的。

盡管數(shù)值字段的哈希計(jì)算是非??焖俚?,存儲(chǔ)它們的原始值通常需要同樣(或更少)的內(nèi)存空間。這對(duì)低基數(shù)的字符串字段同樣適用,Elasticsearch 的內(nèi)部優(yōu)化能夠保證每個(gè)唯一值只計(jì)算一次哈希。

基本上說,預(yù)先計(jì)算并不能保證所有的字段都快,它只對(duì)那些具有高基數(shù)和內(nèi)容很長的字符串字段有作用。需要記住的是預(yù)先計(jì)算也只是簡單地將代價(jià)轉(zhuǎn)到索引時(shí),代價(jià)就在那里,不增不減。

To do this, we need to add a new multifield to our data. We’ll delete our index, add a new mapping that includes the hashed field, and then reindex:

要想這么做,我們需要為數(shù)據(jù)增加一個(gè)新的多值字段。我們先刪除索引,再增加一個(gè)包括哈希值字段的映射,然后重新索引:

DELETE/cars/PUT/cars/{"mappings": {"transactions": {"properties": {"color": {"type":"string","fields": {"hash": {"type":"murmur3"#1}? ? ? ? ? ? }? ? ? ? ? }? ? ? ? }? ? ? }? ? }? }? POST/cars/transactions/_bulk? {"index": {}}? {"price":10000,"color":"red","make":"honda","sold":"2014-10-28"}? {"index": {}}? {"price":20000,"color":"red","make":"honda","sold":"2014-11-05"}? {"index": {}}? {"price":30000,"color":"green","make":"ford","sold":"2014-05-18"}? {"index": {}}? {"price":15000,"color":"blue","make":"toyota","sold":"2014-07-02"}? {"index": {}}? {"price":12000,"color":"green","make":"toyota","sold":"2014-08-19"}? {"index": {}}? {"price":20000,"color":"red","make":"honda","sold":"2014-11-05"}? {"index": {}}? {"price":80000,"color":"red","make":"bmw","sold":"2014-01-01"}? {"index": {}}? {"price":25000,"color":"blue","make":"ford","sold":"2014-02-12"}

#1 多值字段的類型是?murmur3,這是一個(gè)哈希函數(shù)。

現(xiàn)在當(dāng)我們執(zhí)行聚合時(shí),我們使用?color.hash?字段而不是?color?字段:

GET/cars/transactions/_search? {"size":0,"aggs": {"distinct_colors": {"cardinality": {"field":"color.hash"#1}? ? ? ? ? }? ? ? }? }

#1 注意我們指定的是哈希過的多值字段,而不是原始字段。

現(xiàn)在?cardinality?度量會(huì)讀取?"color.hash"?里的值(預(yù)先計(jì)算的哈希值),并將它們作為原始值的動(dòng)態(tài)哈希值。

每個(gè)文檔節(jié)省的時(shí)間有限,但如果哈希每個(gè)字段需要 10 納秒而我們的聚合需要訪問一億文檔,那么每個(gè)查詢就需要多花 1 秒鐘的時(shí)間。如果我們發(fā)現(xiàn)自己在很多文檔都會(huì)使用?cardinality?基數(shù),可以做些性能分析看是否有必要在我們部署的應(yīng)用中采用預(yù)先計(jì)算哈希的方式。

百分計(jì)算(Calculating Percentiles)

Elasticsearch 提供的另外一個(gè)近似度量就是?percentiles?百分位數(shù)度量。百分位數(shù)展現(xiàn)某以具體百分比下觀察到的數(shù)值。例如,第95個(gè)百分位上的數(shù)值,是高于 95% 的數(shù)據(jù)總和。

百分位數(shù)通常用來找出異常。在(統(tǒng)計(jì)學(xué))的正態(tài)分布下,第 0.13 和 第 99.87 的百分位數(shù)代表與均值距離三倍標(biāo)準(zhǔn)差的值。任何處于三倍標(biāo)準(zhǔn)差之外的數(shù)據(jù)通常被認(rèn)為是不尋常的,因?yàn)樗c平均值相差太大。

更具體的說,假設(shè)我們正運(yùn)行一個(gè)龐大的網(wǎng)站,而我們的任務(wù)是保證用戶請(qǐng)求能得到快速響應(yīng),因此我們就需要監(jiān)控網(wǎng)站的延時(shí)來判斷響應(yīng)是否能達(dá)到目標(biāo)。

在此場(chǎng)景下,一個(gè)常用的度量方法就是平均響應(yīng)延時(shí),但這是一個(gè)不好的選擇(盡管很常用),因?yàn)槠骄鶖?shù)通常會(huì)隱藏那些異常值,中位數(shù)有著同樣的問題。我們可以嘗試最大值,但這個(gè)度量會(huì)輕而易舉的被單個(gè)異常值破壞。

在圖 Figure 40, “Average request latency over time” 查看問題。如果我們倚靠如平均值或中位數(shù)這樣的簡單度量,就會(huì)得到像這樣一幅圖 Figure 40, “Average request latency over time”.

Figure 40. Average request latency over time

一切正常。圖上有輕微的波動(dòng),但沒有什么值得關(guān)注的。但如果我們加載 99 百分位數(shù)時(shí)(這個(gè)值代表最慢的 1% 的延時(shí)),我們看到了完全不同的一幅畫面,如圖Figure 41, “Average request latency with 99th percentile over time” 所示。

Figure 41. Average request latency with 99th percentile over time

令人吃驚!在上午九點(diǎn)半時(shí),均值只有 75ms。如果作為一個(gè)系統(tǒng)管理員,我們都不會(huì)看他第二眼。一切正常!但 99 百分位告訴我們有 1% 的用戶碰到的延時(shí)超過 850ms,這是另外一幅場(chǎng)景。在上午4點(diǎn)48時(shí)也有一個(gè)小波動(dòng),這甚至無法從平均值和中位數(shù)曲線上觀察到。

這只是百分位的一個(gè)應(yīng)用場(chǎng)景,百分位還可以被用來快速用肉眼觀察數(shù)據(jù)的分布,檢查是否有數(shù)據(jù)傾斜或雙峰甚至更多。

百分位度量(Percentile Metric)

讓我加載一個(gè)新的數(shù)據(jù)集(汽車的數(shù)據(jù)不太適用于百分位)。我們要索引一系列網(wǎng)站延時(shí)數(shù)據(jù)然后運(yùn)行一些百分位操作進(jìn)行查看:

POST/website/logs/_bulk? {"index": {}}? {"latency":100,"zone":"US","timestamp":"2014-10-28"}? {"index": {}}? {"latency":80,"zone":"US","timestamp":"2014-10-29"}? {"index": {}}? {"latency":99,"zone":"US","timestamp":"2014-10-29"}? {"index": {}}? {"latency":102,"zone":"US","timestamp":"2014-10-28"}? {"index": {}}? {"latency":75,"zone":"US","timestamp":"2014-10-28"}? {"index": {}}? {"latency":82,"zone":"US","timestamp":"2014-10-29"}? {"index": {}}? {"latency":100,"zone":"EU","timestamp":"2014-10-28"}? {"index": {}}? {"latency":280,"zone":"EU","timestamp":"2014-10-29"}? {"index": {}}? {"latency":155,"zone":"EU","timestamp":"2014-10-29"}? {"index": {}}? {"latency":623,"zone":"EU","timestamp":"2014-10-28"}? {"index": {}}? {"latency":380,"zone":"EU","timestamp":"2014-10-28"}? {"index": {}}? {"latency":319,"zone":"EU","timestamp":"2014-10-29"}

數(shù)據(jù)有三個(gè)值:延時(shí)、數(shù)據(jù)中心的區(qū)域以及時(shí)間戳。讓我們對(duì)數(shù)據(jù)全集執(zhí)行百分位操作以獲得數(shù)據(jù)分布情況的直觀感受:

GET/website/logs/_search? {"size":0,"aggs": {"load_times": {"percentiles": {"field":"latency"#1}? ? ? ? ? },"avg_load_time": {"avg": {"field":"latency"#2}? ? ? ? ? }? ? ? }? }

#1?percentiles?度量被應(yīng)用到?latency?延時(shí)字段。

#2 為了比較,我們對(duì)相同字段使用?avg?度量。

默認(rèn)情況下,percentiles?度量會(huì)返回一組預(yù)定義的百分位數(shù)值:[1, 5, 25, 50, 75, 95, 99]。它們表示了人們感興趣的常用百分位數(shù)值,極端的百分位數(shù)在范圍的兩邊,其他的一些處于中部。在返回的響應(yīng)中,我們可以看到最小延時(shí)在 75ms 左右,而最大延時(shí)差不多有 600ms。與之形成對(duì)比的是,平均延時(shí)在 200ms 左右,信息并不是很多:

..."aggregations": {"load_times": {"values": {"1.0":75.55,"5.0":77.75,"25.0":94.75,"50.0":101,"75.0":289.75,"95.0":489.34999999999985,"99.0":596.2700000000002}? ? },"avg_load_time": {"value":199.58333333333334}? }

所以顯然延時(shí)的分布很廣,然我們看看它們是否與數(shù)據(jù)中心的地理區(qū)域有關(guān):

GET/website/logs/_search? {"size":0,"aggs": {"zones": {"terms": {"field":"zone"#1},"aggs": {"load_times": {"percentiles": {#2"field":"latency","percents": [50,95.0,99.0]#3}? ? ? ? ? ? ? ? ? },"load_avg": {"avg": {"field":"latency"}? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? }? ? ? ? ? }? ? ? }? }

#1 首先根據(jù)區(qū)域我們將延時(shí)分到不同的桶中。

#2 再計(jì)算每個(gè)區(qū)域的百分位數(shù)值。

#3?percents?參數(shù)接受了我們想返回的一組百分位數(shù),因?yàn)槲覀冎粚?duì)長的延時(shí)感興趣。

在響應(yīng)結(jié)果中,我們發(fā)現(xiàn)歐洲區(qū)域(EU)要比美國區(qū)域(US)慢很多,在美國區(qū)域(US),50 百分位與 99 百分位十分接近,它們都接近均值。

與之形成對(duì)比的是,歐洲區(qū)域(EU)在 50 和 99 百分位有較大區(qū)分。現(xiàn)在,顯然可以發(fā)現(xiàn)是歐洲區(qū)域(EU)拉低了延時(shí)的統(tǒng)計(jì)信息,我們知道歐洲區(qū)域的 50% 延時(shí)都在 300ms+。

..."aggregations": {"zones": {"buckets": [? ? ? ? ? {"key":"eu","doc_count":6,"load_times": {"values": {"50.0":299.5,"95.0":562.25,"99.0":610.85}? ? ? ? ? ? },"load_avg": {"value":309.5}? ? ? ? ? },? ? ? ? ? {"key":"us","doc_count":6,"load_times": {"values": {"50.0":90.5,"95.0":101.5,"99.0":101.9}? ? ? ? ? ? },"load_avg": {"value":89.66666666666667}? ? ? ? ? }? ? ? ]? ? }? }? ...

百分位等級(jí)(Percentile Ranks)

這里有另外一個(gè)緊密相關(guān)的度量叫?percentile_ranks。百分位度量告訴我們落在某個(gè)百分比以下的所有文檔的最小值。例如,如果 50 百分位是 119ms,那么有 50% 的文檔數(shù)值都不超過 119ms。percentile_ranks?告訴我們某個(gè)具體值屬于哪個(gè)百分位。119ms 的?percentile_ranks?是在 50 百分位。這基本是個(gè)雙向關(guān)系,例如:

50 百分位是 119ms。

119ms 百分位等級(jí)是 50 百分位。

所以假設(shè)我們網(wǎng)站必須維持的服務(wù)等級(jí)協(xié)議(SLA)是響應(yīng)時(shí)間低于 210ms。然后,開個(gè)玩笑,我們老板警告我們?nèi)绻憫?yīng)時(shí)間超過 800ms 會(huì)把我開除??梢岳斫獾氖牵覀兿M烙卸嗌侔俜直鹊恼?qǐng)求可以滿足 SLA 的要求(并期望至少在 800ms 以下?。?。

為了做到這點(diǎn),我們可以應(yīng)用?percentile_ranks?度量而不是?percentiles?度量:

GET/website/logs/_search? {"size":0,"aggs": {"zones": {"terms": {"field":"zone"},"aggs": {"load_times": {"percentile_ranks": {"field":"latency","values": [210,800]#1}? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? }? ? ? ? ? }? ? ? }? }

#1?percentile_ranks?度量接受一組我們希望分級(jí)的數(shù)值。

在聚合運(yùn)行后,我們能得到兩個(gè)值:

"aggregations": {"zones": {"buckets": [? ? ? ? ? {"key":"eu","doc_count":6,"load_times": {"values": {"210.0":31.944444444444443,"800.0":100}? ? ? ? ? ? }? ? ? ? ? },? ? ? ? ? {"key":"us","doc_count":6,"load_times": {"values": {"210.0":100,"800.0":100}? ? ? ? ? ? }? ? ? ? ? }? ? ? ]? ? }? }

這告訴我們?nèi)c(diǎn)重要的信息:

在歐洲(EU),210ms 的百分位等級(jí)是 31.94% 。

在美國(US),210ms 的百分位等級(jí)是 100% 。

在歐洲(EU)和美國(US),800ms 的百分位等級(jí)是 100% 。

通俗的說,在歐洲區(qū)域(EU)只有 32% 的響應(yīng)時(shí)間滿足服務(wù)等級(jí)協(xié)議(SLA),而美國區(qū)域(US)始終滿足服務(wù)等級(jí)協(xié)議的。但幸運(yùn)的是,兩個(gè)區(qū)域所有響應(yīng)時(shí)間都在 800ms 以下,所有我們還不會(huì)被炒魷魚(至少目前不會(huì))。

percentile_ranks?度量提供了與?percentiles?相同的信息,但它以不同方式呈現(xiàn),如果我們對(duì)某個(gè)具體數(shù)值更關(guān)心,使用它會(huì)更方便。

學(xué)會(huì)權(quán)衡(Understanding the Trade-offs)

和基數(shù)一樣,計(jì)算百分位需要一個(gè)近似算法。樸素的實(shí)現(xiàn)會(huì)維護(hù)一個(gè)所有值的有序列表,但當(dāng)我們有幾十億數(shù)據(jù)分布在幾十個(gè)節(jié)點(diǎn)時(shí),這幾乎是不可能的。

取而代之的是?percentiles?使用一個(gè) TDigest 算法(由 Ted Dunning 在?Computing Extremely Accurate Quantiles Using T-Digests?里面提出的)。有了 HyperLogLog,就不需要理解完整的技術(shù)細(xì)節(jié),但有必要了解算法的特性:

百分位的準(zhǔn)確度與百分位的極端程度相關(guān),也就是說 1 或 99 的百分位要比 50 百分位要準(zhǔn)確。這只是數(shù)據(jù)結(jié)構(gòu)內(nèi)部機(jī)制的一種特性,但這是一個(gè)好的特性,因?yàn)槎鄶?shù)人只關(guān)心極端的百分位。

對(duì)于數(shù)值集合較小的情況,百分位非常準(zhǔn)確。如果數(shù)據(jù)集足夠小,百分位可能 100% 精確。

隨著桶里數(shù)值的增長,算法會(huì)開始對(duì)百分位進(jìn)行估算。它能有效在準(zhǔn)確度和內(nèi)存節(jié)省之間做出權(quán)衡。不準(zhǔn)確的程度比較難以總結(jié),因?yàn)樗蕾囉诰酆蠒r(shí)數(shù)據(jù)的分布以及數(shù)據(jù)量的大小。

與基數(shù)類似,我們可以通過修改參數(shù)?compression?來控制內(nèi)存與準(zhǔn)確度之間的比值。

TDigest 算法用節(jié)點(diǎn)近似計(jì)算百分比:節(jié)點(diǎn)越多,準(zhǔn)確度越高(同時(shí)內(nèi)存消耗也越大),這都與數(shù)據(jù)量成正比。compression?參數(shù)限制節(jié)點(diǎn)的最大數(shù)目為?20 * compression。

因此,通過增加壓縮比值,我們可以提高準(zhǔn)確度同時(shí)也消耗更多內(nèi)存。更大的壓縮比值會(huì)使算法運(yùn)行更慢,因?yàn)榈讓拥臉湫螖?shù)據(jù)結(jié)構(gòu)的存儲(chǔ)也會(huì)增長,也導(dǎo)致操作的代價(jià)更高。默認(rèn)的壓縮比值是?100。

一個(gè)節(jié)點(diǎn)粗略計(jì)算使用 32 字節(jié)的內(nèi)存,所以在最壞的情況下(例如,大量數(shù)據(jù)有序存入),默認(rèn)設(shè)置會(huì)生成一個(gè)大小約為 64KB 的 TDigest。在實(shí)際應(yīng)用中,數(shù)據(jù)會(huì)更隨機(jī),所以 TDigest 使用的內(nèi)存會(huì)更少。


被ES的聚合效率折騰的沒脾氣,轉(zhuǎn)幾篇文章看看

https://www.cnblogs.com/richaaaard/p/5319299.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 12,307評(píng)論 6 13
  • 晚上接兒子回家路上給他奶奶打電話,他奶奶說想他了,兒子說那明天回家看看奶奶,我直接說兒子你說的好痛快,萬一你爸不回...
    天宇嘛嘛閱讀 192評(píng)論 0 1
  • 一杯香茗 和著清涼 對(duì)著弦月 坐在院落大理石的圓桌前 寧靜中囈語 粼粼的光華 蕩漾在樽的酒面 散彌出一種香薰 在花...
    空城_5002閱讀 178評(píng)論 0 4
  • 如果時(shí)光老了 我們還能坐在一起 我負(fù)責(zé)溫柔 你只管吃肉 世界上有兩條真理我深信不疑:一個(gè)是永遠(yuǎn)不要和你的女友爭(zhēng)論,...
    木子叁皮閱讀 353評(píng)論 0 0

友情鏈接更多精彩內(nèi)容