Elasticsearch 遇到的問題彙總




前段時間一直在研究ES(Elasticsearch簡稱)集羣,故難免會遇到一些問題,現就遇到的問題做下深入的分析和總結。在分析之前我們先對ES集羣中涉及到的關鍵名詞進行了解。

一 ES集羣比較重要名詞解釋

   1)shards

     shards指的是索引分片的大小,一個大的索引被分爲若干個分片後,存儲於不同的節點上以構成分佈式搜索。分片不一定是越多越好,分片數量要按自己的業務要求來選定,且單臺機器的分片數最好不要超過三個。如果這個值設置太大會對集羣索引管理帶來壓力從而影響查詢性能。

   2)replicas

     指代的是索引的副本數量,副本數雖然有利於集羣的冗餘,但是數量多了大大影響了集羣的寫入性能,且消耗集羣更多的存儲。爲均衡考慮一般將此值設置爲1

   3)recovery

     從字面意思可知,它代表的是數據的恢復,當索引主分片丟失時會從從分片去恢復數據,如果集羣的內部資源都用於恢復數據,將會對集羣的寫入性能和查詢性能帶來很大的影響。故在恢復數據時,集羣中可以指定恢復數據速率大小。

   4)索引結構名詞

       (1)_all

             此字段的含義是指Elasticsearch 將會通過_all字段存儲其他字段中的值,查詢時只需給定待查詢字段的值而不需要給定字段名稱。此字段默認開啓,如果不禁用_all,會使集羣的索引變大,故一般情況下要禁用此字段。

       (2)_source

           此字段指在生成索引時會存儲原始傳給ES的Json數據, 此字段有如下功能:1 可以作爲高亮功能的數據源、2 可以根據自己需求去包含或者排除某些字段。

此字段是默認開啓的,如果考慮到存儲性能和ES寫入性能,可以禁用此字段或者根據此字段去包含或者排除不需要存儲的字段。

        (3)doc_values

          此字段是在索引時建立的,而不是搜索的時候。當通過非反向的反向索引搜索時候(倒排索引),如果以in-memort方式,內存中的字段數據必須被頻繁的讀寫,而doc_vaules 是預先建立的,並能更快的初始化。一般面對的場景有:1 索引量大的搜索,訪問fielddata會比較緩慢,設置doc_values會有顯著的效果,在大量請求的時候,你甚至不會注意到你的搜索會變慢。結合更快的垃圾回收機制和初始化時間,你會留意到搜索性能會得到有效提升。 2 文件系統的緩存空間越多,docvalue的性能會越好。如果文件都是docvalues並且都位於文件系統的緩存中,那麼訪問這些文件的速度幾乎與訪問內存媲美的。而文件系統緩存由內核控制而非JVM。此字段在ES1.x版本中默認是關閉的,但在ES2.x版本中默認開啓。

          (4) store

          此字段指的是指定索引中某個字段需不需要單獨存儲,如果設置索引中feild2的store屬性爲true時,在查詢時如果指定查詢feild2字段,則ES集羣會辨認此字段被單獨存儲,將不會從_source中加載數據,而是從feild2的存儲塊中取,此字段設置爲true的場景:如果你的文檔長度很長,存儲_source或者從_source中獲取field的代價很大,你可以顯式的將某些field的store屬性設置爲yes。缺點如上邊所說:假設你存儲了10個field,而如果想獲取這10個field的值,則需要多次的io,對集羣性能影響很大。如果字段的store屬性設置爲true對集羣的存儲和寫入性能有很大的影響。

        (5)fielddata_fields

           此字段例子如下:

            {  "query" : { 

                             ...

                       },

                  "fielddata_fields" : ["test1", "test2"] 

             }

        它的主要作用是返回指定的字段且該字段未被單獨存儲時(store的屬性設置爲no),使用此字段會存在大量的內存消耗,使用時必須注意,指定的字段不能太多。突然聯想到fields字段具有類似的功能,但是fields只能返回_source中的字段。

         

        (6)template

        從字段指可以爲一個索引創建一個模板,此原理和設計模式中的模板模式類似。

          (7) _ttl

         此字段表示索引的生存時間,如果啓用此字段默認,默認是對索引數據保存30天,由於啓用此字段後,其會定時循環掃描ES集羣看是否有索引或者類型超過了生存時間,故如果不禁止此字段會對集羣性能有部分影響,

        

二 遇到的一些問題及其原因分析

  2.1 ES集羣的批量寫入性能問題。

    離線數據寫入ES集羣對寫入速度要求比較高,故一直在追尋影響批量寫入性能的原因。剛開始時一直在懷疑是ES中機器和網絡傳輸性能影響,經過測試排查後發現當離線數據寫入ES集羣時,每臺機器的各項負載都比較低,故此原因直接排除。故唯一的可能是ES集羣批量接受數據性能的影響,影響ES集羣寫入速度可以分爲以下幾個方面:         

    1)索引的結構

         索引的結構的對數據的寫入速度影響最大,在上節的名詞解釋了使用_source、store、_all、doc_value會對寫入性能有很大影響,故可以考慮上節介紹去改變索引結構去提升寫入性能。

    2)  副本數量

       寫入索引數據時,會先向相應的索引分片寫入數據,然後其分片同步向其副本寫入數據,如果索引副本寫入完成,整個寫入過程才完成。如果副本過多會對寫入速度有影響。

    3)批量接受隊列大小

       集羣接受批量請求隊列如果過於小,則其餘數據會一直等待,從而引起客戶端寫入程序超時異常,客戶端程序捕獲超時異常後會重傳數據,故整個過程對寫入速度有一定的影響。

    4)索引段合併

      在索引shard中,會存在索引段,當段文件過多時,ES集羣內部會自動段合併,段合併會消耗集羣的性能,故對集羣的寫入速度有一些影響。一般情況下設置索引段文件數爲默認的值,不僅加快查詢速度也提升集羣批量寫入性能。也可以指定段合併的速率來控制合併消耗的資源。

    5)減少索引shard刷新間隔和禁止_ttl字段

     索引shard刷新和啓用_ttl字段會消耗集羣資源,故對批量寫入性能存在影響

 

2.2 ES集羣查詢性能(索引性能)

    要想提升ES集羣的查詢性能必須瞭解數據的索引過程

   1) ES索引的過程(轉載網上)

   ES索引的過程到相對Lucene的索引過程多了分佈式數據的擴展,而ES集羣主要是用tranlog進行各節點之間的數據平衡。所以從上我可以通過索引的settings進行第一優化:   

  “index.translog.flush_threshold_ops”: “100000″  

  “index.refresh_interval”: “-1″

 這兩個參數第一是到tranlog數據達到多少條進行平衡,默認爲5000,而這個過程相對而言是比較浪費時間和資源的。所以我們可以將這個值調大一些還是設爲-1關閉,進而手動進行tranlog平衡。第二參數是刷新頻率,默認爲120s是指索引在生命週期內定時刷新,一但有數據進來能refresh像lucene裏面commit,我們知道當數據addDoucment會,還不能檢索到要commit之後才能行數據的檢索所以可以將其關閉,在最初索引完後手動refresh一之,然後將索引setting裏面的index.refresh_interval參數按需求進行修改,從而可以提高索引過程效率。另外的知道ES索引過程中如果有副本存在,數據也會馬上同步到副本中去。我個人建議在索引過程中將副本數設爲0,待索引完成後將副本數按需量改回來,這樣也可以提高索引效率。

 “number_of_replicas”: 0

上面聊了一次索引過程的優化之後,我們再來聊一下檢索速度比較慢的問題,其實檢索速度快度與索引質量有很大的關係。而索引質量的好壞與很多因素有關。

  2)影響副本的性能因素

     (1)分片數

          在第一節說到,分片數的大小對寫入和查詢性能影響。

       (2)副本數

         不要誤解副本數越多,對查詢性能幫助越大,經過測試發現隨副本數的增加檢索速度會有微量的下降。

    (3)分詞

       現階段ES項目中尚未接觸到分詞,可以肯定的是選用不同的詞庫分詞,索引速度是有影響。

    (4)索引段

       索引段即lucene中的segments概念,我們知道ES索引過程中會refresh和tranlog也就是說我們在索引過程中segments number不至一個。而segments number與檢索是有直接聯繫的,segments number越多檢索越慢,而將segments numbers 有可能的情況下保證爲1這將可以提到將近一半的檢索速度。

      max_num_segments =1 

       (5) 刪除文檔

       經過一段時間測試發現,執行刪除命令時,雖然索引名稱刪除了,但是真實的數據沒有刪除,其實在ES集羣內部在刪除時會存在大量的段合併,此合併會消耗很多集羣資源,從而造成索引速度變慢。解決辦法

    $ curl -XPOST 'http://localhost:9200/twitter/_optimize? only_expunge_deletes =true'  這樣就直接刪除了文檔了。


接下如再遇到ES其他問題,將會在此文檔更新!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章