Elasticsearch HTML文件搜索性能提升實戰

集羣內存設置

Elasticsearch默認安裝後設置的內存是1GB,對於任何一個現實業務來說,這個設置實在太小了,稍有大批量查詢或者寫入操作,集羣很快就會出現問題。
ES在6.x版本後,通過修改安裝路徑elasticsearch/jvm.options文件來設置內存

-Xms10g
-Xmx10g

將內存設置爲10g,重啓服務後生效

systemctl restart elasticsearch.service

一個常見的問題是配置一個大內存,假設你有一個64G內存的機器,按照正常思維思考,你可能會認爲把64G內存都給Elasticsearch比較好,但現實是這樣嗎, 越大越好?

當然,內存對於Elasticsearch來說絕對是重要的,用於更多的內存數據提供更快的操作,而且還有一個內存消耗大戶-Lucene。

Lucene的設計目的是把底層OS裏的數據緩存到內存中。Lucene的段是分別存儲到單個文件中的,這些文件都是不會變化的,所以很利於緩存,同時操作系統也會把這些段文件緩存起來,以便更快的訪問。
如果將所有的內存都分配給Elasticsearch,不留一點給Lucene,那全文檢索性能會很差的。

所以標準的建議是把50%的內存給elasticsearch,剩下的50%也不會沒有用處的,Lucene會很快吞噬剩下的這部分內存用於文件緩存。
推薦安裝cerebro來查看ES集羣的狀態: cerebro.
在這裏插入圖片描述

副本和分片

分片(shard)

當有大量的文檔時,由於內存的限制、磁盤處理能力不足、無法足夠快的響應客戶端的請求等,一個節點可能不夠。這種情況下,數據可以分爲較小的分片。每個分片放到不同的服務器上。
當你查詢的索引分佈在多個分片上時,ES會把查詢發送給每個相關的分片,並將結果組合在一起,而應用程序並不知道分片的存在。

副本(replica)

爲提高查詢吞吐量或實現高可用性,可以使用分片副本。
副本是一個分片的精確複製,每個分片可以有零個或多個副本。ES中可以有許多相同的分片,其中之一被選擇更改索引操作,這種特殊的分片稱爲主分片。當主分片不可用時,集羣將副本提升爲新的主分片。
ES默認是5個分片1個副本,設置方法:

curl -XPUT 'http://127.0.0.1:9200/_template/template_http_request_record' 
-H 'Content-Type: application/json' -d 
{
  "index_patterns": [
    "test"#index
  ],
  "settings": {
    "number_of_shards": 1,#分片
    "number_of_replicas": 1#副本
  }
}

索引分片如何設置合理?
在Elasticsearch中,每個查詢在每個分片的單個線程中執行。然而,可以並行處理多個分片,並可以在相同分片上執行多個查詢和聚合。

【小分片的利弊】這意味着,在不涉及高速緩存時,最小查詢延遲將取決於數據、查詢的類型、分片的大小。查詢大量小分片將使得每個分片的處理速度更快,但是隨着更多的任務需要按順序排隊和處理,它不一定要比查詢較小數量的更大的分片更快。如果有多個併發查詢,則有很多小碎片也會降低查詢吞吐量。

ElasticSearch推薦的最大JVM堆空間是30~32G, 所以把分片最大容量限制爲30GB, 然後再對分片數量做合理估算. 例如, 你的數據能達到200GB, 我們推薦你最多分配7到8個分片.

查詢分頁

size+from淺分頁

當Elasticsearch響應請求時,它必須確定docs的順序,排列響應結果。如果請求的頁數較少(假設每頁10個docs), Elasticsearch不會有什麼問題,但是如果頁數較大時,比如請求第100頁,Elasticsearch不得不取出第1頁到第100頁的所有docs,再去除第1頁到第99頁的docs,得到第100頁的docs。

scroll深分頁

相對於from和size的分頁來說,使用scroll可以模擬一個傳統數據的遊標,記錄當前讀取的文檔信息位置。這個分頁的用法,不是爲了實時查詢數據,而是爲了一次性查詢大量的數據(甚至是全部的數據)。

因爲這個scroll相當於維護了一份當前索引段的快照信息,這個快照信息是你執行這個scroll查詢時的快照。在這個查詢後的任何新索引進來的數據,都不會在這個快照中查詢到。但是它相對於from和size,不是查詢所有數據然後剔除不要的部分,而是記錄一個讀取的位置,保證下一次快速繼續讀取。

from+size方式以及scroll方式優缺點對比:
1)對於from+size方式:當結果足夠大的時候,查詢頁碼越大,會大大加大內存和CPU的消耗。但該方式使用非常方便,可以任意跳頁。所以這種分頁方式需要做一些限制,比如只能查詢前100頁等

2)對於scroll方式: 當結果足夠大的時候, scroll 性能要比from+size效率高很多。但是隻能下一頁 下一頁的返回數據,不能跳頁。類似微博或者新聞app往下滑刷新內容的應用場景還是非常不錯的,但scroll的緩存時間設置不宜過長,佔內存。
因爲我的業務數據量左右,所以我用的scroll的方式,每次返回10條記錄,使用者根據需求點擊獲取更多數據,效果還是非常不錯的。
在這裏插入圖片描述

高亮對比

通過論壇中網友的建議來看,都推薦對於大文件高亮使用: fast-vector-highlighter。

Plain highlighter

ES默認的配置方式,官網明確說明該方式匹配慢,如果出現性能問題,請考慮其他高亮方式。

Postings highlighter

支持postings高亮方式,需要在mapping下添加如下信息:

"type": "text",
"index_options" : "offsets"

posting高亮方式的特點:
1)速度快,不需要對高亮的文檔再分析。文檔越大,獲得越高 性能 。
2)比fvh高亮方式需要的磁盤空間少。
3)將text文件分割成語句並對其高亮處理。對於自然語言發揮作用明顯,但對於html則不然。
4)將文檔視爲整個語料庫,並 使用BM25算法 爲該語料庫中的文檔打分。

PUT /example
{
  "mappings": {
    "doc" : {
      "properties": {
        "comment" : {
          "type": "text",
          "index_options" : "offsets"
        }
      }
    }
  }
}

Fast vector highlighter

如果在mapping中的text類型字段下添加了如下信息:

"type": "text","term_vector" : "with_positions_offsets"

fvh高亮方式的特點如下:
1)當文件>1MB(大文件)時候,尤其適合fvh高亮方式。
2)自定義爲 boundary_scanner的掃描方式。
3) 設定了 term_vector to with_positions_offsets會增加索引的大小。
4)能聯合多字段匹配返回一個結果,詳見matched_fields。
5)對於不同的匹配類型分配不同的權重,如:pharse匹配比term匹配高。

因爲我的業務場景是對HTML文件進行多詞匹配,文件很多都是大於1M,用ES默認的Plain highlighter,所以平均搜索時間都在5秒以上,複雜的可能需要20S以上。
在這裏插入圖片描述
將services.banner字段修改爲f’vh後,搜索效率大大提升,即使是複雜的搜索也在毫秒級。

{
	"mappings": {
		"doc": {
			"properties": {
				"services.banner": {
					"type": "text",
					"term_vector": "with_positions_offsets"
				}
			}
		}
	}
}

在這裏插入圖片描述
參考鏈接:
https://qbox.io/blog/optimizing-elasticsearch-how-many-shards-per-index.
http://doc.codingdict.com/elasticsearch/106/.
https://cloud.tencent.com/developer/article/1066368.

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