<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Elasticsearch 檢索性能優(yōu)化實(shí)戰(zhàn)指南

          共 6596字,需瀏覽 14分鐘

           ·

          2021-10-30 10:49

          1、當(dāng)我們在說 Elasticsearch 檢索性能優(yōu)化的時(shí)候,實(shí)際在說什么?!

          • 檢索響應(yīng)慢!
          • 并發(fā)檢索用戶多時(shí),響應(yīng)時(shí)間不達(dá)標(biāo)
          • 卡死了!
          • 怎么還沒有出結(jié)果?
          • 怎么這么慢?
          • 為啥競品產(chǎn)品的很快就返回結(jié)果了?
          • 宕機(jī)了

          等等......

          這些都與可能檢索有關(guān),確切的說和檢索性能有關(guān)。

          檢索性能的優(yōu)化涉及知識(shí)點(diǎn)比較零散,我以官方文檔的檢索性能優(yōu)化部分作為大框架和主線,結(jié)合實(shí)戰(zhàn)經(jīng)驗(yàn)和咨詢經(jīng)驗(yàn)用通俗易懂的語言做下解讀。

          2、內(nèi)存要給到位

          Elasticsearch 嚴(yán)重依賴文件系統(tǒng)緩存來加快搜索速度。通常,你應(yīng)該確保至少有一半的可用內(nèi)存進(jìn)入文件系統(tǒng)緩存,以便 Elasticsearch 可以將索引的熱點(diǎn)區(qū)域保留在物理內(nèi)存中。

          線上環(huán)境還見過2核4G配置的,基本上跑不了太多數(shù)據(jù)量。

          推薦閱讀:干貨 | 吃透Elasticsearch 堆內(nèi)存

          3、磁盤必要時(shí)換 SSD

          對寫入速度有超高要求的,SSD就是“祥瑞”。

          SSD 成本考慮可能不能一步到位,但至少得是普通機(jī)械磁盤。

          切記盡量不用:NFS 或 SMB 遠(yuǎn)程文件系統(tǒng)。

          4、CPU 考慮核數(shù)和線程數(shù)

          在并發(fā)寫入或查詢量大之后,就會(huì)出現(xiàn) CPU 打滿的情況。

          可以優(yōu)化的空間就是:基于CPU 核數(shù)合理調(diào)節(jié)線程池和隊(duì)列的大小。

          推薦閱讀:

          Elasticsearch 線程池和隊(duì)列問題,請先看這一篇

          5、數(shù)據(jù)建模要合理

          多表關(guān)聯(lián)非 Elasticsearch 所擅長。換句話說,Elasticsearch 支持多表關(guān)聯(lián)方式有限。

          像 Mysql 中的動(dòng)不動(dòng)幾個(gè)表的 join 操作,在 Elasticsearch 要考慮必要性和實(shí)現(xiàn)復(fù)雜度。

          Elasticsearch 多表關(guān)聯(lián)僅限于如下幾種:

          • 父子文檔 join:適用于子文檔頻繁更新場景。
          • nested 嵌套類型:適用于子文檔相對固定、更新頻率低的場景。
          • 大寬表拉伸存儲(chǔ):本質(zhì)空間換時(shí)間。
          • 業(yè)務(wù)層面自己結(jié)合檢索后的返回結(jié)果,自己實(shí)現(xiàn)關(guān)聯(lián)。

          且:Nested 可以使查詢慢幾倍,而父子 Join 類型可以使查詢慢數(shù)百倍。

          大家在建模的時(shí)候多考慮,如果不刻意建模全部使用默認(rèn)字段,看看可能帶來的“災(zāi)難”性的后果,反過來就能理解建模的重要性。

          建模細(xì)節(jié)點(diǎn)有很多,推薦閱讀:

          干貨 | 論Elasticsearch數(shù)據(jù)建模的重要性

          Elasticsearch 數(shù)據(jù)建模實(shí)戰(zhàn)指南

          干貨 | Elasticsearch多表關(guān)聯(lián)設(shè)計(jì)指南

          6、盡可能減少檢索字段數(shù)目

          query_string 或 multi_match 查詢目標(biāo)的字段越多,速度就越慢。

          提高多個(gè)字段搜索速度的常用技術(shù)是在索引時(shí)將它們的值借助 copy_to 復(fù)制到單個(gè)字段中,然后在搜索時(shí)使用該字段。

          copy_to 實(shí)現(xiàn)了 1 帶 2 、1 帶 3 甚至 1 帶 N 的效果。

          7、合理設(shè)置 size 大小

          在檢索請求的時(shí)候 size 值設(shè)置很大,會(huì)導(dǎo)致命中數(shù)據(jù)量大,可能會(huì)帶來嚴(yán)重的性能問題。

          建議:合理設(shè)置分頁 size 值。如果著實(shí)數(shù)據(jù)量大考慮:scroll 或者 search_after 實(shí)現(xiàn)。

          推薦參考:

          干貨 | 全方位深度解讀 Elasticsearch 分頁查詢

          8、多使用寫入前預(yù)處理操作

          我之前的文章講情感分析區(qū)間查詢的時(shí)候,其實(shí)本質(zhì)就三個(gè)區(qū)間:負(fù)面、正面、中性。

          如果用 range_query 區(qū)間檢索勢必會(huì)慢。

          建模的時(shí)候,可以考慮數(shù)據(jù)寫入的時(shí)候,轉(zhuǎn)成:-1、0、1 的 keyword 類型值。

          將 range_query 的范圍檢索變成了基于倒排索引的精準(zhǔn)查找 term query,效率自然會(huì)提升。

          能借助 ingest 預(yù)處理完成的,不要放到后面借助 script + update_by_query。

          使用過 script + update_by_query的自然知道有多苦。

          看到這里有同感的老鐵可以留言說一下感受。

          推薦閱讀:

          Elasticsearch 運(yùn)行時(shí)類型 Runtime fields 深入詳解

          9、能用 keyword 字段類型就不要使用其他

          如果一個(gè)字段可以設(shè)置為:number 數(shù)值類型字段也可以設(shè)置為 keyword 類型。在建模階段可以參考如下考慮方式實(shí)現(xiàn)建模選型。

          得看你的應(yīng)用場景,如果涉及 range query 推薦 number 類型,具體可以:integer、long 或者其他數(shù)值類型。

          如果僅是精準(zhǔn)匹配 term 級(jí)別的檢索,那 keyword 就能搞定。

          如果還感覺兩種都有可能,建議設(shè)置:keyword 和 number 雙類型,借助 fields 實(shí)現(xiàn)。

          fields 組合類型實(shí)現(xiàn)參考如下:

          PUT?test_0001
          {
          ??"mappings":?{
          ????"properties":?{
          ??????"age":{
          ????????"type":"integer",
          ????????"fields":?{
          ??????????"keyword":{
          ????????????"type":"keyword"
          ??????????}
          ????????}
          ??????}
          ????}
          ??}
          }

          10、盡量規(guī)避使用腳本

          如果可能,請避免使用:

          • 基于腳本的排序
          • 基于腳本的聚合
          • 基于script_score 查詢

          painless 腳本翻譯為中文是:“無痛”。

          但,用過你就知道有多痛。

          • 第一:不是很好用,很多示例,官方文檔也沒有窮盡所有樣例,需要花時(shí)間摸索。
          • 第二:性能問題,解決問題一時(shí)爽,線上一跑“悔斷腸”。

          那,不讓用,線上的確需要咋辦?

          盡量前置寫入的時(shí)候結(jié)合 ingest + script 實(shí)現(xiàn)。

          如果對寫入指標(biāo)要求沒有那么高,通過稍微增大寫入的時(shí)間間接提高了檢索效率,何樂而不為?

          推薦閱讀:

          Elasticsearch 線上問題實(shí)戰(zhàn)——如何借助 painless 更新時(shí)間?

          11、日期做舍入處理,能間接利用緩存

          GET?index/_search
          {
          ??"query":?{
          ????"constant_score":?{
          ??????"filter":?{
          ????????"range":?{
          ??????????"my_date":?{
          ????????????"gte":?"now-1h/m",
          ????????????"lte":?"now/m"
          ??????????}
          ????????}
          ??????}
          ????}
          ??}
          }

          “/m” 的方式能有效利用時(shí)間緩存。

          推薦閱讀:

          12、有效使用 filter 緩存

          在 Elasticsearch 查詢中有效使用 filter 過濾器可以顯著提高搜索性能。

          filter 過濾優(yōu)勢體現(xiàn)在:

          • 緩存。
          • 和query 相比,不需要計(jì)算評分,所以更快。
          推薦閱讀:

          吃透 | Elasticsearch filter和query的不同

          13、對歷史索引數(shù)據(jù)使用段合并

          前提:基于時(shí)間切分索引,對于相對冷的數(shù)據(jù),訪問密集型沒有那么高的數(shù)據(jù),推薦使用段合并。

          切記:不要對正在寫入數(shù)據(jù)的索引進(jìn)行段合并。

          7.X 版本可以借助 ILM 索引生命周期管理實(shí)現(xiàn)。

          推薦閱讀:

          14、啟用 eager global ordinals 提升高基數(shù)聚合性能

          適用場景:高基數(shù)聚合。

          高基數(shù)聚合場景中的高基數(shù)含義:一個(gè)字段包含很大比例的唯一值。

          global ordinals 的本質(zhì)是:啟用 eager_global_ordinals 時(shí),會(huì)在刷新(refresh)分片時(shí)構(gòu)建全局序號(hào)。這將構(gòu)建全局序號(hào)的成本從搜索階段轉(zhuǎn)移到了數(shù)據(jù)索引化(寫入)階段。

          PUT?my-index-000001
          {
          ??"mappings":?{
          ????"properties":?{
          ??????"tags":?{
          ????????"type":?"keyword",
          ????????"eager_global_ordinals":?true
          ??????}
          ????}
          ??}
          }
          推薦閱讀:

          Elasticsearch 聚合性能優(yōu)化六大猛招

          15、預(yù)熱文件系統(tǒng)緩存

          如果重新啟動(dòng)運(yùn)行 Elasticsearch 的機(jī)器,文件系統(tǒng)緩存將是空的,因此操作系統(tǒng)將索引的熱點(diǎn)區(qū)域加載到內(nèi)存中需要一些時(shí)間,以便快速搜索操作。

          可以使用 index.store.preload 設(shè)置根據(jù)文件擴(kuò)展名明確告訴操作系統(tǒng)哪些文件應(yīng)該立即加載到內(nèi)存中。

          PUT?/my-index-000001
          {
          ??"settings":?{
          ????"index.store.preload":?["nvd",?"dvd"]
          ??}
          }

          在 lucene 中,

          • nvd 是指:全文檢索文件;
          • dvd 是指:用于聚合排序的列存文件。

          16、合理使用 index sort 邊寫入邊排序機(jī)制

          PUT?my-index-000001
          {
          ??"settings":?{
          ????"index":?{
          ??????"sort.field":?"date",?
          ??????"sort.order":?"desc"??
          ????}
          ??},
          ??"mappings":?{
          ????"properties":?{
          ??????"date":?{
          ????????"type":?"date"
          ??????}
          ????}
          ??}
          }

          這個(gè)配置相信你一看就懂,發(fā)生在寫入前,創(chuàng)建索引的時(shí)候設(shè)定的排序字段。

          本質(zhì):通過降低寫入速度間接提升檢索速度。

          17、通過 perference 優(yōu)化緩存利用率

          perference 用在兩次檢索結(jié)果不一致的時(shí)候,本質(zhì)是:主、副本分片數(shù)據(jù)不一致導(dǎo)致的,有半路由的機(jī)制。

          合理使用 perference 參數(shù)能優(yōu)化緩存使用率。

          18、設(shè)置合理的分片數(shù)和副本數(shù)

          主分片的設(shè)置需要結(jié)合:集群數(shù)據(jù)節(jié)點(diǎn)規(guī)模、全部數(shù)據(jù)量和日增數(shù)據(jù)量等綜合維度給出值,一般建議:設(shè)置為數(shù)據(jù)節(jié)點(diǎn)的1-3倍。

          分片不宜過小、過碎。有很多小分片可能會(huì)導(dǎo)致大量的網(wǎng)絡(luò)調(diào)用和線程開銷,這會(huì)嚴(yán)重影響搜索性能。

          副本數(shù)不是越多越好?

          在許多情況下,擁有更多副本有助于提高搜索性能。但是不代表副本越多越好。

          增加副本的前提是考慮:磁盤存儲(chǔ)空間的容量上限和磁盤警戒水位線。本質(zhì)還是以空間換時(shí)間。

          一般非高可用場景,基本一個(gè)副本足夠。

          官方給出了合理副本大小的公式供參考:

          如果你的集群有 num_nodes 個(gè)節(jié)點(diǎn)、num_primaries 主分片,并且你希望最多同時(shí)處理 max_failures 個(gè)節(jié)點(diǎn)故障,那么適合你的副本數(shù)為:

          ?max(max_failures,?ceil(num_nodes?/?num_primaries)?-?1)

          19、避免使用 wildcard 檢索

          避免使用 wildcard 通配符檢索,尤其是前綴通配符查詢。

          我自己早些年線上環(huán)境實(shí)現(xiàn)曾經(jīng)大量使用:wildcard,導(dǎo)致客戶現(xiàn)場演示宕機(jī),我自己因此也寫了“檢討書”,血淋淋的教訓(xùn)再次告訴大家。

          幾年后回頭看當(dāng)時(shí)為什么選型 wildcard?復(fù)盤原因小結(jié)如下:

          • MySql 的使用慣性。

          MySql 中 select * from table where title like ‘%長津湖%'。順理成章的認(rèn)為 Elasticsearch 中的 wildcard 也能實(shí)現(xiàn)類型功能。

          • 對 Elasticsearch 不求甚解。

          能簡單使用且測試環(huán)境小樣沒有問題,直接更新線上環(huán)節(jié)。客戶現(xiàn)場數(shù)據(jù)一多,直接崩潰。

          • 為達(dá)目的,功能優(yōu)先,沒有考慮性能。

          產(chǎn)品經(jīng)理要求字段中存在的字符都能檢索出來。

          Elasticsearch 本質(zhì)是倒排索引提高檢索效率,如果分詞詞典不完備,除非 ngram 逐個(gè)字符細(xì)粒度分詞,否則幾乎做不到的。

          wildcard 功能方面必然能滿足,但是性能問題當(dāng)時(shí)沒有做大量測試。

          • 沒有對 Elasticseearch 全局認(rèn)識(shí)

          全局看,Elasticsearch 就那么幾種類型,全文檢索類型、精準(zhǔn)匹配類型是重頭戲。

          當(dāng)時(shí)選型的時(shí)候,摸著石頭過河,拿起石頭就用,結(jié)果石頭有“刺“,把手給扎了。

          更好的方式應(yīng)該是:全局認(rèn)識(shí),有幾種類型石頭?哪里有石頭?石頭應(yīng)用場景是什么?我的業(yè)務(wù)需要哪種類型的石頭?

          后面優(yōu)化的方案就是:字詞混合索引 + match_phrase 短語匹配實(shí)現(xiàn),一方面保證了匹配的精準(zhǔn)性,另一方面保證了召回率。

          推薦閱讀:

          Elasticsearch 警惕使用 wildcard 檢索!然后呢?

          20、謹(jǐn)慎使用 Regex 正則檢索

          正則檢索也會(huì)有響應(yīng)慢及性能問題,要謹(jǐn)慎使用。

          21、謹(jǐn)慎使用全量聚合和多重嵌套聚合

          聚合的本質(zhì)是不精準(zhǔn)的,原因在于主、副本分片數(shù)據(jù)的不一致性。

          對于實(shí)時(shí)性業(yè)務(wù)數(shù)據(jù),每分、每秒都有數(shù)據(jù)寫入的,要考慮數(shù)據(jù)在變化,聚合結(jié)果也會(huì)隨之變化。

          我在業(yè)務(wù)開發(fā)中使用全量聚合的目的是規(guī)避聚合結(jié)果的不精準(zhǔn)性,但是帶來的則是性能問題。

          多重嵌套聚合隨之嵌套層數(shù)的增多,復(fù)雜度也會(huì)激增,檢索響應(yīng)速度會(huì)變慢甚至帶來性能問題。

          推薦閱讀:

          Elasticsearch 聚合數(shù)據(jù)結(jié)果不精確,怎么破?

          22、設(shè)置合理的 Timeout 時(shí)間

          超時(shí)參數(shù)和在參數(shù)后終止在執(zhí)行大量搜索或結(jié)果數(shù)據(jù)龐大時(shí)非常有用。

          在 python 客戶端或者 java 客戶端連接的時(shí)候都建議設(shè)置好 Timeout 值。

          23、合理設(shè)置刪除文檔的方式

          當(dāng)數(shù)據(jù)量非常大了之后怎么辦?兩種方式做一下對比:

          • 方式一:大索引存儲(chǔ)。

          數(shù)據(jù)量大了之后,刪除部分索引數(shù)據(jù),借助:delete_by_uery 實(shí)現(xiàn)。

          • 方式二:冷熱集群架構(gòu)+基于時(shí)間切分索引。

          必要時(shí)候,刪除較早日期的索引,借助:delete 實(shí)現(xiàn)。

          方式一本質(zhì)是邏輯刪除,數(shù)據(jù)看似刪除了,但磁盤空間短期內(nèi)會(huì)暴增。待段合并后,才會(huì)物理刪除。

          方式二本質(zhì)是物理刪除,刪除索引會(huì)立即釋放磁盤。

          所以,當(dāng)磁盤空間吃緊,尤其到了警戒水位線:85%、90%、95%之后。

          方式二刪除:穩(wěn)、準(zhǔn)、狠。而方式一相對“磨磨唧唧、娘娘們們”,非必要不推薦。

          推薦閱讀:

          24、小結(jié)

          Elasticsearch 檢索性能優(yōu)化,斷斷續(xù)續(xù)寫過幾篇,但都不夠系統(tǒng)。

          本次,結(jié)合官方文檔+其他幾篇參考文獻(xiàn)+實(shí)戰(zhàn)經(jīng)驗(yàn)進(jìn)行綜合梳理,期望能給大家?guī)硎斋@。

          性能優(yōu)化非一朝一夕之功,本文并沒有窮盡所有檢索優(yōu)化細(xì)節(jié),更多實(shí)踐細(xì)節(jié)需要大家結(jié)合業(yè)務(wù)實(shí)際進(jìn)行嘗試、探索、發(fā)現(xiàn)。

          你在業(yè)務(wù)開發(fā)中如何優(yōu)化查詢性能的呢?歡迎留言交流。

          參考

          https://www.elastic.co/guide/en/elasticsearch/reference/master/tune-for-search-speed.html?

          https://opster.com/blogs/improve-elasticsearch-search-performance/?

          https://opster.com/elasticsearch-glossary/elasticsearch-slow-search-query-guide/?

          https://medium.com/analytics-vidhya/improving-elasticsearch-query-performance-3b59c6b15a97?

          https://opster.com/elasticsearch-glossary/elasticsearch-increase-search-speed/

          推薦

          1、重磅 | 死磕 Elasticsearch 方法論認(rèn)知清單(2021年國慶更新版)
          2Elasticsearch 7.X 進(jìn)階實(shí)戰(zhàn)私訓(xùn)課(口碑不錯(cuò))
          3、讓Elasticsearch飛起來!——性能優(yōu)化實(shí)踐干貨

          短時(shí)間快習(xí)得多干貨!

          已帶領(lǐng)70位球友通過 Elastic 官方認(rèn)證!

          中國僅通過百余人

          比同事搶先一步學(xué)習(xí)進(jìn)階干貨
          瀏覽 88
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲精品免费观看 | 欧美成人777奇米影视91色 | 亚洲精品一区中文字幕乱码 | 在线sm调教视频网站 | 奴隷令嬢の屈辱调教鬼六 |