當前位置:首頁 » 文件管理 » es查詢緩存命中率

es查詢緩存命中率

發布時間: 2023-01-19 11:47:24

① elasticsearch基本查詢筆記(三)-- es查詢總結

term 查詢是簡單查詢,接受一個欄位名和參數,進行精準查詢,類似sql中:

ES中對應的DSL如下:

在ES5.x及以上版本,字元串類型需設置為keyword或text類型,根據類型來進行精確值匹配。

當進行精確值查詢,可以使用過濾器,因為過濾器的執行非常快,不會計算相關度(ES會計算查詢評分),且過濾器查詢結果容易被緩存

bool過濾器組成部分:

當我們需要多個過濾器時,只須將它們置入 bool 過濾器的不同部分即可。

terms是包含的意思,如下:

name包含["奧尼爾","麥迪"]

返回結果:

range查詢可同時提供包含(inclusive)和不包含(exclusive)這兩種范圍表達式,可供組合的選項如下:

類似sql中的范圍查詢:

ES中對應的DSL如下:

如下sql,age不為null:

ES中對應的DSL如下:

如下sql,age為null:

ES中對應的DSL如下:

註:missing查詢在5.x版本已經不存在。

匹配包含 not analyzed(未分詞分析)的前綴字元:

匹配具有匹配通配符表達式( (not analyzed )的欄位的文檔。 支持的通配符:

1) * 它匹配任何字元序列(包括空字元序列);

2) ? 它匹配任何單個字元。

請注意,此查詢可能很慢,因為它需要遍歷多個術語。
為了防止非常慢的通配符查詢,通配符不能以任何一個通配符*****或 ? 開頭。

正則表達式查詢允許您使用正則表達式術語查詢。
舉例如下:

注意: * 的匹配會非常慢,你需要使用一個長的前綴,
通常類似.*?+通配符查詢的正則檢索性能會非常低。

模糊查詢查找在模糊度中指定的最大編輯距離內的所有可能的匹配項,然後檢查術語字典,以找出在索引中實際存在待檢索的關鍵詞。

舉例:

檢索索引test_index中,type為user的全部信息。不過在 es6.x 版本,一個index僅有一個type,未來 es7.x 版本,將取消type,所以這個查詢沒啥意義。

返回指定id的全部信息。

全文檢索查詢,是通過分析器,對查詢條件進行分析,然後在全文本欄位進行全文查詢。

全文搜索取決於mapping中設定的analyzer(分析器),這里使用的是ik分詞器。

所以在進行查詢開發時候,需要先了解index的mapping,從而選擇查詢方式。

匹配查詢接受文本/數字/日期類型,分析它們,並構造查詢。

對查詢傳入參數進行分詞,搜索詞語相同文檔。

match_phrase查詢分析文本,並從分析文本中創建短語查詢。

用戶已經漸漸習慣在輸完查詢內容之前,就能為他們展現搜索結果,這就是所謂的即時搜索(instant search) 或輸入即搜索(search-as-you-type) 。

不僅用戶能在更短的時間內得到搜索結果,我們也能引導用戶搜索索引中真實存在的結果。

例如,如果用戶輸入 johnnie walker bl ,我們希望在它們完成輸入搜索條件前就能得到: Johnnie Walker Black Label 和 Johnnie Walker Blue Label 。

match_phrase_prefix與match_phrase相同,除了它允許文本中最後一個術語的前綴匹配。

② es使用與原理6 -- 聚合分析剖析

有些聚合分析的演算法,是很容易就可以並行的,比如說max

有些聚合分析的演算法,是不好並行的,比如說,count(distinct),並不是說,在每個node上,直接就出一些distinct value,就可以的,因為數據可能會很多,假設圖中的協調節點3百萬個數據去重後還剩下100萬distinct的數據,那麼內存需要來存儲這100萬條數據,這是不可能的

es會採取近似聚合的方式,就是採用在每個node上進行近估計的方式,得到最終的結論,cuont(distcint),100萬,1050萬/95萬 --> 5%左右的錯誤率
近似估計後的結果,不完全准確,但是速度會很快,一般會達到完全精準的演算法的性能的數十倍

precision_threshold優化准確率和內存開銷

brand去重,如果brand的unique value,在100個以內,小米,長虹,三星,TCL,HTL。。。
在多少個unique value以內,cardinality,幾乎保證100%准確
cardinality演算法,會佔用precision_threshold * 8 byte 內存消耗,100 * 8 = 800個位元組
佔用內存很小。。。而且unique value如果的確在值以內,那麼可以確保100%准確
100,數百萬的unique value,錯誤率在5%以內
precision_threshold,值設置的越大,佔用內存越大,1000 * 8 = 8000 / 1000 = 8KB,可以確保更多unique value的場景下,100%的准確
field,去重,count,這時候,unique value,10000,precision_threshold=10000,10000 * 8 = 80000個byte,80KB

doc value正排索引
搜索+聚合 是怎麼實現的?
假設是倒排索引實現的

倒排索引來實現是非常不現實的,因為我們搜索的那個欄位search_field 有可能是分詞的,這就需要去掃描整個索引才能實現聚合操作,效率是及其低下的。
正排索引結構:
doc2: agg1
doc3: agg2
1萬個doc --> 搜 -> 可能跟搜索到10000次,就搜索完了,就找到了1萬個doc的聚合field的所有值了,然後就可以執行分組聚合操作了
doc value原理

1、doc value原理

(1)index-time生成

PUT/POST的時候,就會生成doc value數據,也就是正排索引

(2)核心原理與倒排索引類似

正排索引,也會寫入磁碟文件中,然後呢,os cache先進行緩存,以提升訪問doc value正排索引的性能
如果os cache內存大小不足夠放得下整個正排索引,doc value,就會將doc value的數據寫入磁碟文件中

(3)性能問題:給jvm更少內存,64g伺服器,給jvm最多16g

es官方是建議,es大量是基於os cache來進行緩存和提升性能的,不建議用jvm內存來進行緩存,那樣會導致一定的gc開銷和oom問題
給jvm更少的內存,給os cache更大的內存
64g伺服器,給jvm最多16g,幾十個g的內存給os cache
os cache可以提升doc value和倒排索引的緩存和查詢效率

2、column壓縮

doc1: 550
doc2: 550
doc3: 500

合並相同值,550,doc1和doc2都保留一個550的標識即可
(1)所有值相同,直接保留單值
(2)少於256個值,使用table encoding模式:一種壓縮方式
(3)大於256個值,看有沒有最大公約數,有就除以最大公約數,然後保留這個最大公約數

重點:
對分詞的field,直接執行聚合操作,會報錯,大概意思是說,你必須要打開fielddata,然後將正排索引數據載入到內存中,才可以對分詞的field執行聚合操作,而且會消耗很大的內存
先修改 欄位的fielddata屬性為true,再查 就能查找到數據

當然,我們也可以使用內置field(keyword)不分詞,對string field進行聚合,如果對不分詞的field執行聚合操作,直接就可以執行,不需要設置fieldata=true

分詞field+fielddata的工作原理

doc value --> 不分詞的所有field,可以執行聚合操作 --> 如果你的某個field不分詞,那麼在index-time,就會自動生成doc value --> 針對這些不分詞的field執行聚合操作的時候,自動就會用doc value來執行
分詞field,是沒有doc value的。。。在index-time,如果某個field是分詞的,那麼是不會給它建立doc value正排索引的,因為分詞後,佔用的空間過於大,所以默認是不支持分詞field進行聚合的
分詞field默認沒有doc value,所以直接對分詞field執行聚合操作,是會報錯的

對於分詞field,必須打開和使用fielddata,完全存在於純內存中。。。結構和doc value類似。。。如果是ngram或者是大量term,那麼必將佔用大量的內存。。。

如果一定要對分詞的field執行聚合,那麼必須將fielddata=true,然後es就會在執行聚合操作的時候,現場將field對應的數據,建立一份fielddata正排索引,fielddata正排索引的結構跟doc value是類似的,
但是只會講fielddata正排索引載入到內存中來,然後基於內存中的fielddata正排索引執行分詞field的聚合操作

如果直接對分詞field執行聚合,報錯,才會讓我們開啟fielddata=true,告訴我們,會將fielddata uninverted index,正排索引,載入到內存,會耗費內存空間

為什麼fielddata必須在內存?因為大家自己思考一下,分詞的字元串,需要按照term進行聚合,需要執行更加復雜的演算法和操作,如果基於磁碟和os cache,那麼性能會很差

我們是不是可以預先生成載入fielddata到內存中來???
query-time的fielddata生成和載入到內存,變為index-time,建立倒排索引的時候,會同步生成fielddata並且載入到內存中來,這樣的話,對分詞field的聚合性能當然會大幅度增強

③ ES大數據量下的查詢優化

filesystem類似於我們在mysql上建立一層redis緩存;

es的搜索引擎嚴重依賴於底層的filesystem cache,如果給filesystem cache更多的內存,盡量讓內存可以容納所有的indx segment file索引數據文件,那麼你搜索的時候就基本都是走內存的,性能會非常高。

兩者差距非常大,走磁碟和走systenfile cache的讀取的性能差距可以說是秒級和毫秒級的差距了;

要讓es性能要好,最佳的情況下,就是我們的機器的內存,至少可以容納你的數據量的一半

最佳的情況下,是僅僅在es中就存少量的數據,存儲要用來搜索的那些索引,內存留給filesystem cache的,如果就100G,那麼你就控制數據量在100gb以內,相當於是,你的數據幾乎全部走內存來搜索,性能非常之高,一般可以在1秒以內

的少數幾個欄位就可以了,比如說,就寫入es id name age三個欄位就可以了,然後你可以把其他的欄位數據存在mysql裡面,我們一般是建議用 es + hbase 的一個架構。
hbase的特點是適用於海量數據的在線存儲,就是對hbase可以寫入海量數據,不要做復雜的搜索,就是做很簡單的一些根據id或者范圍進行查詢的這么一個操作就可以了

如果確實內存不足,但是我們又存儲了比較多的數據,比如只有30g給systemfile cache,但是存儲了60g數據情況,這種情況可以做數據預熱;

我們可以將一些高頻訪問的熱點數據(比如微博知乎的熱榜榜單數據,電商的熱門商品(旗艦版手機,榜單商品信息)等等)提前預熱,定期訪問刷到我們es里;(比如定期訪問一下當季蘋果旗艦手機關鍵詞,比如現在的iphone12)

對於那些你覺得比較熱的,經常會有人訪問的數據,最好做一個專門的緩存預熱子系統,就是對熱數據,每隔一段時間,提前訪問一下,讓數據進入filesystem cache裡面去。這樣下次別人訪問的時候,一定性能會好一些。

我們可以將冷數據寫入一個索引中,然後熱數據寫入另外一個索引中,這樣可以確保熱數據在被預熱之後,盡量都讓他們留在filesystem os cache里,別讓冷數據給沖刷掉。

盡量做到設計document的時候就把需要數據結構都做好,這樣搜索的數據寫入的時候就完成。對於一些太復雜的操作,比如join,nested,parent-child搜索都要盡量避免,性能都很差的。

es的分頁是較坑的 ,為啥呢?舉個例子吧,假如你每頁是10條數據,你現在要查詢第100頁,實際上是會把 每個shard上存儲的前1000條數據都查到 一個協調節點上,如果你有個5個shard,那麼就有5000條數據,接著 協調節點對這5000條數據進行一些合並、處理,再獲取到最終第100頁的10條數據。

因為他是分布式的,你要查第100頁的10條數據,你是不可能說從5個shard,每個shard就查2條數據?最後到協調節點合並成10條數據?這樣肯定不行,因為我們從單個結點上拿的數據幾乎不可能正好是所需的數據。我們必須得從每個shard都查1000條數據過來,然後根據你的需求進行排序、篩選等等操作,最後再次分頁,拿到裡面第100頁的數據。

你翻頁的時候,翻的越深,每個shard返回的數據就越多,而且協調節點處理的時間越長。非常坑爹。所以用es做分頁的時候,你會發現越翻到後面,就越是慢。

我們之前也是遇到過這個問題,用es作分頁,前幾頁就幾十毫秒,翻到10頁之後,幾十頁的時候,基本上就要5~10秒才能查出來一頁數據了

你系統不允許他翻那麼深的頁,或者產品同意翻的越深,性能就越差

如果是類似於微博中,下拉刷微博,刷出來一頁一頁的,可以用scroll api
scroll api1 scroll api2
scroll會一次性給你生成所有數據的一個快照,然後每次翻頁就是通過游標移動 ,獲取下一頁下一頁這樣子,性能會比上面說的那種分頁性能也高很多很多

scroll的原理實際上是保留一個數據快照,然後在一定時間內,你如果不斷的滑動往後翻頁的時候,類似於你現在在瀏覽微博,不斷往下刷新翻頁。那麼就用scroll不斷通過游標獲取下一頁數據,這個性能是很高的,比es實際翻頁要好的多的多。

缺點:

④ es文件瀏覽器可以離線緩存嗎

es文件瀏覽器不能離線緩存,緩存一般是在線狀態下才可以。

緩存是可以進行高速數據交換的存儲器,它先於內存與CPU交換數據,因此速率很快。L1 Cache(一級緩存)是CPU第一層高速緩存。內置的L1高速緩存的容量和結構對CPU的性能影響較大,不過高速緩沖存儲器均由靜態RAM組成,結構較復雜。

在CPU管芯面積不能太大的情況下,L1級高速緩存的容量不可能做得太大。一般L1緩存的容量通常在32—256KB。L2Cache(二級緩存)是CPU的第二層高速緩存,分內部和外部兩種晶元。內部的晶元二級緩存運行速率與主頻相同,而外部的二級緩存則只有主頻的一半。



相關信息

緩存的工作原理是當CPU要讀取一個數據時,首先從CPU緩存中查找,找到就立即讀取並送給CPU處理;沒有找到,就從速率相對較慢的內存中讀取並送給CPU處理,同時把這個數據所在的數據塊調入緩存中,可以使得以後對整塊數據的讀取都從緩存中進行,不必再調用內存。

正是這樣的讀取機制使CPU讀取緩存的命中率非常高(大多數CPU可達90%左右),也就是說CPU下一次要讀取的數據90%都在CPU緩存中,只有大約10%需要從內存讀取。這大大節省了CPU直接讀取內存的時間,也使CPU讀取數據時基本無需等待。CPU讀取數據的順序是先緩存後內存。

⑤ Elastic檢索技巧總結

在mysql中,我們常用的查詢 可能就是 精準查詢 模糊查詢 范圍查詢 等等,那麼在es中,有哪些是我們經常用到的呢?

match 查詢text,因為兩個都會分詞,所以只要分詞結果中有交集 就會顯示

match_phrase 是分詞的,text 也是分詞的,但是 text的分詞必須全部包含match_phrase的全部分詞才會展示,但是必須是連續有序的,可以簡單理解為,搜索關鍵詞a ,那麼在text欄位中必須包含a 才會展示

裡面的條件語句必須全部匹配

所有的條件語句都不能匹配

至少滿足裡面的一個條件

返回的文檔必須滿足filter子句的條件。但是跟Must不一樣的是,不會計算分值, 並且可以使用緩存,如果只看查詢的結果,must和filter是一樣的。區別是場景不一樣。如果結果需要算分就使用must,否則可以考慮使用filter。
為了說明filter查詢高效的原因,我們需要引入ES的一個概念query context和filter context。
query context關注的是,文檔到底有多匹配查詢的條件,這個匹配的程度是由相關性分數決定的,分數越高自然就越匹配。所以這種查詢除了關注文檔是否滿足查詢條件,還需要額外的計算相關性分數.
filter context關注的是,文檔是否匹配查詢條件,結果只有兩個,是和否。沒有其它額外的計算。它常用的一個場景就是過濾時間范圍。
對於bool查詢,must使用的就是query context,而filter使用的就是filter context。

[圖片上傳失敗...(image-8e2ee9-1637326113837)]

[圖片上傳失敗...(image-116b03-1637326113837)]

支持的操作如下:
1)+表示AND操作
2)| 表示OR操作
3)- 否定操作
4)*在術語結束時表示前綴查詢
5)(和)表示優先

我們使用谷歌或者網路搜索的時候,返回的結果往往會對我們搜索的關鍵字標紅顯示,那麼es 搜索是怎麼實現這個功能的呢
[圖片上傳失敗...(image-d16e32-1637326113837)]

⑥ Athlon64 3000+ES版有兩種緩存,是512好還是1M的好啊哪種穩定啊大神們幫幫忙

CPU緩存(Cache Memory)位於CPU與內存之間的臨時存儲器,它的容量比內存小但交換速度快。在緩存中的數據是內存中的一小部分,但這一小部分是短時間內CPU即將訪問的,當CPU調用大量數據時,就可避開內存直接從緩存中調用,從而加快讀取速度。由此可見,在CPU中加入緩存是一種高效的解決方案,這樣整個內存儲器(緩存+內存)就變成了既有緩存的高速度,又有內存的大容量的存儲系統了。緩存對CPU的性能影響很大,主要是因為CPU的數據交換順序和CPU與緩存間的帶寬引起的。 緩存的工作原理是當CPU要讀取一個數據時,首先從緩存中查找,如果找到就立即讀取並送給CPU處理;如果沒有找到,就用相對慢的速度從內存中讀取並送給CPU處理,同時把這個數據所在的數據塊調入緩存中,可以使得以後對整塊數據的讀取都從緩存中進行,不必再調用內存。 正是這樣的讀取機制使CPU讀取緩存的命中率非常高(大多數CPU可達90%左右),也就是說CPU下一次要讀取的數據90%都在緩存中,只有大約10%需要從內存讀取。這大大節省了CPU直接讀取內存的時間,也使CPU讀取數據時基本無需等待。總的來說,CPU讀取數據的順序是先緩存後內存。 最早先的CPU緩存是個整體的,而且容量很低,英特爾公司從Pentium時代開始把緩存進行了分類。當時集成在CPU內核中的緩存已不足以滿足CPU的需求,而製造工藝上的限制又不能大幅度提高緩存的容量。因此出現了集成在與CPU同一塊電路板上或主板上的緩存,此時就把 CPU內核集成的緩存稱為一級緩存,而外部的稱為二級緩存。一級緩存中還分數據緩存(Data Cache,D-Cache)和指令緩存(Instruction Cache,I-Cache)。二者分別用來存放數據和執行這些數據的指令,而且兩者可以同時被CPU訪問,減少了爭用Cache所造成的沖突,提高了處理器效能。英特爾公司在推出Pentium 4處理器時,用新增的一種一級追蹤緩存替代指令緩存,容量為12KμOps,表示能存儲12K條微指令。 隨著CPU製造工藝的發展,二級緩存也能輕易的集成在CPU內核中,容量也在逐年提升。現在再用集成在CPU內部與否來定義一、二級緩存,已不確切。而且隨著二級緩存被集成入CPU內核中,以往二級緩存與CPU大差距分頻的情況也被改變,此時其以相同於主頻的速度工作,可以為CPU提供更高的傳輸速度。 二級緩存是CPU性能表現的關鍵之一,在CPU核心不變化的情況下,增加二級緩存容量能使性能大幅度提高。而同一核心的CPU高低端之分往往也是在二級緩存上有差異,由此可見二級緩存對於CPU的重要性。 CPU在緩存中找到有用的數據被稱為命中,當緩存中沒有CPU所需的數據時(這時稱為未命中),CPU才訪問內存。從理論上講,在一顆擁有二級緩存的CPU中,讀取一級緩存的命中率為80%。也就是說CPU一級緩存中找到的有用數據占數據總量的80%,剩下的20%從二級緩存中讀取。由於不能准確預測將要執行的數據,讀取二級緩存的命中率也在80%左右(從二級緩存讀到有用的數據占總數據的16%)。那麼還有的數據就不得不從內存調用,但這已經是一個相當小的比例了。目前的較高端的CPU中,還會帶有三級緩存,它是為讀取二級緩存後未命中的數據設計的—種緩存,在擁有三級緩存的CPU中,只有約5%的數據需要從內存中調用,這進一步提高了CPU的效率。 為了保證CPU訪問時有較高的命中率,緩存中的內容應該按一定的演算法替換。一種較常用的演算法是「最近最少使用演算法」(LRU演算法),它是將最近一段時間內最少被訪問過的行淘汰出局。因此需要為每行設置一個計數器,LRU演算法是把命中行的計數器清零,其他各行計數器加1。當需要替換時淘汰行計數器計數值最大的數據行出局。這是一種高效、科學的演算法,其計數器清零過程可以把一些頻繁調用後再不需要的數據淘汰出緩存,提高緩存的利用率。 CPU產品中,一級緩存的容量基本在4KB到64KB之間,二級緩存的容量則分為128KB、256KB、512KB、1MB、2MB等。一級緩存容量各產品之間相差不大,而二級緩存容量則是提高CPU性能的關鍵。二級緩存容量的提升是由CPU製造工藝所決定的,容量增大必然導致CPU內部晶體管數的增加,要在有限的CPU面積上集成更大的緩存,對製造工藝的要 查看原帖>>

熱點內容
工程加密網 發布:2024-05-03 14:59:55 瀏覽:292
吃冰球解壓 發布:2024-05-03 14:59:10 瀏覽:895
編譯晶元發燙 發布:2024-05-03 14:59:05 瀏覽:549
優化演算法pdf 發布:2024-05-03 14:18:10 瀏覽:291
python演算法書 發布:2024-05-03 14:14:25 瀏覽:736
方舟怎麼加入伺服器閃退 發布:2024-05-03 14:05:27 瀏覽:491
安卓心跳怎麼打出來 發布:2024-05-03 13:59:23 瀏覽:100
存儲標准性 發布:2024-05-03 13:37:07 瀏覽:416
液鹼存儲 發布:2024-05-03 13:21:13 瀏覽:156
linux如何改配置文件 發布:2024-05-03 13:00:54 瀏覽:31