操bb国片四区三区,亚洲一片内射无码,91短视频福利导航,蜜桃臀成人免费在线视频观看

時隔3年重新開源,這些 ElasticSearch 應用技能運維必會?

2024-09-02 09:11:59 Jinyu
圖片

2021年1月15日,Elastic 創(chuàng)始人兼 CEO Shay Bannon 宣布改變 ElasticSearch 和 Kibana 的開源協(xié)議,由 Apache 2.0 變更為 SSPL 和 Elastic License。
SSPL 是一種針對服務器端軟件的開源許可證,由 MongDB 公司創(chuàng)建,用戶可以在自己的項目中使用 SSPL 的項目許可,但不能將其作為獨立的商業(yè)產(chǎn)品出售。
時隔3年,Elasticsearch 與 Kibana 將再次回歸開源,AGPL 將作為新的許可選項,與 ELv2 和 SSPL 并列,以此消除人們心中的疑慮與不安。
下面推薦一篇 ElasticSearch 的簡介,深入理解功能和應用。

一、ES 的基本使用

在決定使用Elasticsearch的時候首先要考慮的是版本問題,Elasticsearch(排除 0.x 和 1.x)目前有如下常用的穩(wěn)定的主版本:2.x,5.x,6.x,7.x(current)。
你可能會發(fā)現(xiàn)沒有3.x和4.x,ES從2.4.6直接跳到了5.0.0。其實是為了 ELK(ElasticSearch,Logstash,Kibana)技術(shù)棧的版本統(tǒng)一,免的給用戶帶來混亂。
在 Elasticsearch是2.x(2.x的最后一版2.4.6的發(fā)布時間是July 25, 2017)的情況下,Kibana已經(jīng)是4.x(Kibana 4.6.5 的發(fā)布時間是 July 25, 2017)。
那么在Kibana的下一主版本肯定是5.x了,所以Elasticsearch直接將自己的主版本發(fā)布為 5.0.0 了。
統(tǒng)一之后,我們選版本就不會猶豫困惑了,我們選定Elasticsearch的版本后再選擇相同版本的Kibana就行了,不用擔憂版本不兼容的問題。
Elasticsearch是使用Java構(gòu)建,所以除了注意ELK技術(shù)的版本統(tǒng)一,我們在選擇Elasticsearch的版本的時候還需要注意JDK的版本。
每個大版本所依賴的JDK版本也不同,目前7.2版本已經(jīng)可以支持JDK11。

安裝使用

下載和解壓Elasticsearch,解壓后即可用:

安裝目錄下運行 bin/elasticsearch 來啟動 ES。
默認在 9200 端口運行,請求 curl http://localhost:9200/ 或者瀏覽器輸入 http://localhost:9200,得到一個 JSON 對象,其中包含當前節(jié)點、集群、版本等信息。


















{"name" : "U7fp3O9","cluster_name" : "elasticsearch","cluster_uuid" : "-Rj8jGQvRIelGd9ckicUOA","version" : {"number" : "6.8.1","build_flavor" : "default","build_type" : "zip","build_hash" : "1fad4e1","build_date" : "2019-06-18T13:16:52.517138Z","build_snapshot" : false,"lucene_version" : "7.7.0","minimum_wire_compatibility_version" : "5.6.0","minimum_index_compatibility_version" : "5.0.0"},"tagline" : "You Know, for Search"}

集群健康狀態(tài)

要檢查群集運行狀況目前有很多監(jiān)控比如Grafana、Prometheus有集成好的模版、此外還有Cerebro進行集群管理,這里暫時看基本的信息,從Kibana控制臺中運行以下命令GET/_cluster/health,得到如下信息:

















{"cluster_name" : "lzj","status" : "yellow","timed_out" : false,"number_of_nodes" : 1,"number_of_data_nodes" : 1,"active_primary_shards" : 9,"active_shards" : 9,"relocating_shards" : 0,"initializing_shards" : 0,"unassigned_shards" : 5,"delayed_unassigned_shards" : 0,"number_of_pending_tasks" : 0,"number_of_in_flight_fetch" : 0,"task_max_waiting_in_queue_millis" : 0,"active_shards_percent_as_number" : 64.28571428571429}

集群狀態(tài)通過 綠,黃,紅 來標識:

  • 綠色:集群健康完好,一切功能齊全正常,所有分片和副本都可以正常工作。
  • 黃色:預警狀態(tài),所有主分片功能正常,但至少有一個副本是不能正常工作的。此時集群是可以正常工作的,但是高可用性在某種程度上會受影響。
  • 紅色:集群不可正常使用。某個或某些分片及其副本異常不可用,這時集群的查詢操作還能執(zhí)行,但是返回的結(jié)果會不準確。對于分配到這個分片的寫入請求將會報錯,最終會導致數(shù)據(jù)的丟失。當集群狀態(tài)為紅色時,它將會繼續(xù)從可用的分片提供搜索請求服務,但是你需要盡快修復那些未分配的分片。

二、ES 機制原理

ES的基本概念和基本操作介紹完了之后,我們可能還有很多疑惑

  • 它們內(nèi)部是如何運行的?

  • 主分片和副本分片是如何同步的?

  • 創(chuàng)建索引的流程是什么樣的?

  • ES如何將索引數(shù)據(jù)分配到不同的分片上的?

    以及索引數(shù)據(jù)是如何存儲的?

  • 為什么說ES是近實時搜索引擎而文檔的CRUD(創(chuàng)建-讀取-更新-刪除) 操作是實時的?

  • 以及ES是怎樣保證更新被持久化在斷電時也不丟失數(shù)據(jù)?

  • 為什么刪除文檔不會立刻釋放空間?

帶著這些疑問我們進入接下來的內(nèi)容。

寫索引原理

下圖描述了3個節(jié)點的集群,共擁有12個分片,其中有4個主分片(S0、S1、S2、S3和8個副本分片(R0、R1、R2、R3),每個主分片對應兩個副本分片,節(jié)點1是主節(jié)點(Master節(jié)點)負責整個集群的狀態(tài)。

圖片

寫索引是只能寫在主分片上,然后同步到副本分片。這里有四個主分片,一條數(shù)據(jù) ES 是根據(jù)什么規(guī)則寫到特定分片上的呢?

首先這肯定不會是隨機的,否則將來要獲取文檔的時候我們就不知道從何處尋找了。

實際上,這個過程和之前寫的Hash分片的路由方法,實際根據(jù)下面這個公式?jīng)Q定的:

shard = hash(routing) % number_of_primary_shards

Routing是一個可變值,默認是文檔的_id,也可以設置成一個自定義的值。Routing通過Hash函數(shù)生成一個數(shù)字,然后這個數(shù)字再除以number_of_primary_shards(主分片的數(shù)量)后得到余數(shù)。

這個在0到number_of_primary_shards-1之間的余數(shù),就是我們所尋求的文檔所在分片的位置。

這就解釋了為什么我們要在創(chuàng)建索引的時候就確定好主分片的數(shù)量并且永遠不會改變這個數(shù)量:因為如果數(shù)量變化了,那么所有之前路由的值都會無效,文檔也再也找不到了。

由于在 ES 集群中每個節(jié)點通過上面的計算公式都知道集群中的文檔的存放位置,所以每個節(jié)點都有處理讀寫請求的能力。

在一個寫請求被發(fā)送到某個節(jié)點后,該節(jié)點即為前面說過的協(xié)調(diào)節(jié)點,協(xié)調(diào)節(jié)點會根據(jù)路由公式計算出需要寫到哪個分片上,再將請求轉(zhuǎn)發(fā)到該分片的主分片節(jié)點上。

圖片

  1. 客戶端向 ES1 節(jié)點(協(xié)調(diào)節(jié)點)發(fā)送寫請求,通過路由計算公式得到值為 0,則當前數(shù)據(jù)應被寫到主分片 S0 上。
  2. ES1 節(jié)點將請求轉(zhuǎn)發(fā)到 S0 主分片所在的節(jié)點 ES3,ES3 接受請求并寫入到磁盤。
  3. 并發(fā)將數(shù)據(jù)復制到兩個副本分片 R0 上,其中通過樂觀并發(fā)控制數(shù)據(jù)的沖突。
    一旦所有的副本分片都報告成功,則節(jié)點 ES3 將向協(xié)調(diào)節(jié)點報告成功,協(xié)調(diào)節(jié)點向客戶端報告成功。

存儲原理

上面介紹了在 ES 內(nèi)部索引的寫處理流程,這個流程是在ES的內(nèi)存中執(zhí)行的,數(shù)據(jù)被分配到特定的分片和副本上之后,最終是存儲到磁盤上的,這樣在斷電的時候就不會丟失數(shù)據(jù)。
具體的存儲路徑可在配置文件 ../config/elasticsearch.yml中進行設置,默認存儲在安裝目錄的 Data 文件夾下。建議不要使用默認值,因為若 ES 進行了升級,則有可能導致數(shù)據(jù)全部丟失:


path.data: /path/to/data//索引數(shù)據(jù)path.logs: /path/to/logs//日志記錄

分段存儲

索引文檔以段的形式存儲在磁盤上,何為段?索引文件被拆分為多個子文件,則每個子文件叫作段,每一個段本身都是一個倒排索引,并且段具有不變性,一旦索引的數(shù)據(jù)被寫入硬盤,就不可再修改。

在底層采用了分段的存儲模式,使它在讀寫時幾乎完全避免了鎖的出現(xiàn),大大提升了讀寫性能。

段被寫入到磁盤后會生成一個提交點,提交點是一個用來記錄所有提交后段信息的文件。

一個段一旦擁有了提交點,就說明這個段只有讀的權(quán)限,失去了寫的權(quán)限。相反,當段在內(nèi)存中時,就只有寫的權(quán)限,而不具備讀數(shù)據(jù)的權(quán)限,意味著不能被檢索。

段的概念提出主要是因為:在早期全文檢索中為整個文檔集合建立了一個很大的倒排索引,并將其寫入磁盤中。

如果索引有更新,就需要重新全量創(chuàng)建一個索引來替換原來的索引。這種方式在數(shù)據(jù)量很大時效率很低,并且由于創(chuàng)建一次索引的成本很高,所以對數(shù)據(jù)的更新不能過于頻繁,也就不能保證時效性。

索引文件分段存儲并且不可修改,那么新增、更新和刪除如何處理呢?

  • 新增

很好處理,由于數(shù)據(jù)是新的,所以只需要對當前文檔新增一個段就可以。

  • 刪除

由于不可修改,所以對于刪除操作,不會把文檔從舊的段中移除而是通過新增一個 .del 文件,文件中會列出這些被刪除文檔的段信息。這個被標記刪除的文檔仍然可以被查詢匹配到, 但它會在最終結(jié)果被返回前從結(jié)果集中移除。

  • 更新

不能修改舊的段來進行反映文檔的更新,其實更新相當于是刪除和新增這兩個動作組成。會將舊的文檔在.del文件中標記刪除,然后文檔的新版本被索引到一個新的段中??赡軆蓚€版本的文檔都會被一個查詢匹配到,但被刪除的那個舊版本文檔在結(jié)果集返回前就會被移除。

段被設定為不可修改具有一定的優(yōu)勢也有一定的缺點,優(yōu)勢主要表現(xiàn)在:不需要鎖。如果你從來不更新索引,你就不需要擔心多進程同時修改數(shù)據(jù)的問題。

一旦索引被讀入內(nèi)核的文件系統(tǒng)緩存,便會留在哪里,由于其不變性。只要文件系統(tǒng)緩存中還有足夠的空間,那么大部分讀請求會直接請求內(nèi)存,而不會命中磁盤。這提供了很大的性能提升。

其它緩存(像Filter緩存),在索引的生命周期內(nèi)始終有效。它們不需要在每次數(shù)據(jù)改變時被重建,因為數(shù)據(jù)不會變化。

寫入單個大的倒排索引允許數(shù)據(jù)被壓縮,減少磁盤 I/O 和需要被緩存到內(nèi)存的索引的使用量。

段的不變性的缺點如下:

  • 當對舊數(shù)據(jù)進行刪除時,舊數(shù)據(jù)不會馬上被刪除,而是在.del文件中被標記為刪除。
    而舊數(shù)據(jù)只能等到段更新時才能被移除,這樣會造成大量的空間浪費。
  • 若有一條數(shù)據(jù)頻繁的更新,每次更新都是新增新的標記舊的,則會有大量的空間浪費。
  • 每次新增數(shù)據(jù)時都需要新增一個段來存儲數(shù)據(jù)。
    當段的數(shù)量太多時,對服務器的資源例如文件句柄的消耗會非常大。
  • 在查詢的結(jié)果中包含所有的結(jié)果集,需要排除被標記刪除的舊數(shù)據(jù),這增加了查詢的負擔。

延遲寫策略

介紹完了存儲的形式,那么索引寫入到磁盤的過程是怎樣的?是否是直接調(diào) Fsync物理性地寫入磁盤?

答案是顯而易見的,如果是直接寫入到磁盤上,磁盤的 I/O 消耗上會嚴重影響性能。那么當寫數(shù)據(jù)量大的時候會造成 ES 停頓卡死,查詢也無法做到快速響應。如果真是這樣 ES 也就不會稱之為近實時全文搜索引擎了。

為了提升寫的性能,ES并沒有每新增一條數(shù)據(jù)就增加一個段到磁盤上,而是采用延遲寫的策略。每當有新增的數(shù)據(jù)時,就將其先寫入到內(nèi)存中,在內(nèi)存和磁盤之間是文件系統(tǒng)緩存。

當達到默認的時間(1 秒鐘)或者內(nèi)存的數(shù)據(jù)達到一定量時,會觸發(fā)一次刷新(Refresh),將內(nèi)存中的數(shù)據(jù)生成到一個新的段上并緩存到文件緩存系統(tǒng)上,稍后再被刷新到磁盤中并生成提交點。

這里的內(nèi)存使用的是ES的JVM內(nèi)存,而文件緩存系統(tǒng)使用的是操作系統(tǒng)的內(nèi)存。

新的數(shù)據(jù)會繼續(xù)的被寫入內(nèi)存,但內(nèi)存中的數(shù)據(jù)并不是以段的形式存儲的,因此不能提供檢索功能。

由內(nèi)存刷新到文件緩存系統(tǒng)的時候會生成新的段,并將段打開以供搜索使用,而不需要等到被刷新到磁盤。

在Elasticsearch中,寫入和打開一個新段的輕量的過程叫做 Refresh(即內(nèi)存刷新到文件緩存系統(tǒng))。

默認情況下每個分片會每秒自動刷新一次。這就是為什么我們說Elasticsearch 是近實時搜索,因為文檔的變化并不是立即對搜索可見,但會在一秒之內(nèi)變?yōu)榭梢姟?/span>

我們也可以手動觸發(fā) Refresh:



POST/_refresh //刷新所有索引POST/nba/_refresh //刷新指定的索引

Tips:盡管刷新是比提交輕量很多的操作,它還是會有性能開銷。當寫測試的時候,手動刷新很有用,但是不要在生產(chǎn)>環(huán)境下每次索引一個文檔都去手動刷新。而且并不是所有的情況都需要每秒刷新。

可能你正在使用Elasticsearch索引大量的日志文件,可能想優(yōu)化索引速度而不是>近實時搜索。
這時可以在創(chuàng)建索引時在Settings中通過調(diào)大如下參數(shù)refresh_interval = "30s"的值 , 降低每個索引的刷新頻率,設值時需要注意后面帶上時間單位,否則默認是毫秒。當refresh_interval=-1 時表示關(guān)閉索引的自動刷新。
雖然通過延時寫的策略可以減少數(shù)據(jù)往磁盤上寫的次數(shù)提升了整體的寫入能力,但是我們知道文件緩存系統(tǒng)也是內(nèi)存空間,屬于操作系統(tǒng)的內(nèi)存,只要是內(nèi)存都存在斷電或異常情況下丟失數(shù)據(jù)的危險。
為了避免丟失數(shù)據(jù),Elasticsearch添加了事務日志(Translog),事務日志記錄了所有還沒有持久化到磁盤的數(shù)據(jù)。

圖片

索引寫流程

添加了事務日志后整個寫索引的流程如上圖所示:一個新文檔被索引之后,先被寫入到內(nèi)存中,但是為了防止數(shù)據(jù)的丟失,會追加一份數(shù)據(jù)到事務日志中。
不斷有新的文檔被寫入到內(nèi)存,同時也都會記錄到事務日志中。這時新數(shù)據(jù)還不能被檢索和查詢。
當達到默認的刷新時間或內(nèi)存中的數(shù)據(jù)達到一定量后,會觸發(fā)一次  Refresh,將內(nèi)存中的數(shù)據(jù)以一個新段形式刷新到文件緩存系統(tǒng)中并清空內(nèi)存。這時雖然新段未被提交到磁盤,但是可以提供文檔的檢索功能且不能被修改。
隨著新文檔索引不斷被寫入,當日志數(shù)據(jù)大小超過 512M 或者時間超過 30 分鐘時,會觸發(fā)一次Flush。
內(nèi)存中的數(shù)據(jù)被寫入到一個新段同時被寫入到文件緩存系統(tǒng),文件系統(tǒng)緩存中數(shù)據(jù)通過Fsync刷新到磁盤中,生成提交點,日志文件被刪除,創(chuàng)建一個空的新日志。
通過這種方式當斷電或需要重啟時,ES不僅要根據(jù)提交點去加載已經(jīng)持久化過的段,還需要工具Translog里的記錄,把未持久化的數(shù)據(jù)重新持久化到磁盤上,避免了數(shù)據(jù)丟失的可能。3. 段合并 由于自動刷新流程每秒會創(chuàng)建一個新的段 ,這樣會導致短時間內(nèi)的段數(shù)量暴增。而段數(shù)目太多會帶來較大的麻煩。
每一個段都會消耗文件句柄、內(nèi)存和 CPU 運行周期。更重要的是,每個搜索請求都必須輪流檢查每個段然后合并查詢結(jié)果,所以段越多,搜索也就越慢。
Elasticsearch通過在后臺定期進行段合并來解決這個問題。小的段被合并到大的段,然后這些大的段再被合并到更大的段。
段合并的時候會將那些舊的已刪除文檔從文件系統(tǒng)中清除。被刪除的文檔不會被拷貝到新的大段中。合并的過程中不會中斷索引和搜索。

圖片

segment合并

段合并在進行索引和搜索時會自動進行,合并進程選擇一小部分大小相似的段,并且在后臺將它們合并到更大的段中,這些段既可以是未提交的也可以是已提交的。
合并結(jié)束后老的段會被刪除,新的段被 Flush 到磁盤,同時寫入一個包含新段且排除舊的和較小的段的新提交點,新的段被打開可以用來搜索。
段合并的計算量龐大, 而且還要吃掉大量磁盤 I/O,段合并會拖累寫入速率,如果任其發(fā)展會影響搜索性能。
Elasticsearch在默認情況下會對合并流程進行資源限制,所以搜索仍然有足夠的資源很好地執(zhí)行。

六、ES 的性能優(yōu)化

存儲設備

磁盤在現(xiàn)代服務器上通常都是瓶頸。Elasticsearch重度使用磁盤,你的磁盤能處理的吞吐量越大,你的節(jié)點就越穩(wěn)定。這里有一些優(yōu)化磁盤 I/O 的技巧:

  • 使用SSD。就像其他地方提過的,他們比機械磁盤優(yōu)秀多了。

  • 使用RAID10/RAID5。條帶化RAID會提高磁盤I/O,同時增加數(shù)據(jù)可靠性

  • 使用多塊硬盤,并允許Elasticsearch通過多個 path.data目錄配置把數(shù)據(jù)條帶化分配到它們上面。

  • 不要使用遠程掛載的存儲,比如NFS或者SMB/CIFS。這個引入的延遲對性能來說完全是背道而馳的。

  • 如果你用的是 EC2,當心EBS。即便是基于SSD的EBS,通常也比本地實例的存儲要慢。

內(nèi)部索引優(yōu)化

圖片

索引優(yōu)化

Elasticsearch為了能快速找到某個Term,先將所有的Term排個序,然后根據(jù)二分法查找Term,時間復雜度為logN,就像通過字典查找一樣,這就是Term Dictionary。
現(xiàn)在再看起來,似乎和傳統(tǒng)數(shù)據(jù)庫通過B-Tree的方式類似。但是如果Term 太多,Term Dictionary 也會很大,放內(nèi)存不現(xiàn)實,于是有了 Term Index。
就像字典里的索引頁一樣,A開頭的有哪些Term,分別在哪頁,可以理解 Term Index是一棵樹。
這棵樹不會包含所有的Term,它包含的是Term的一些前綴。通過Term Index可以快速地定位到Term Dictionary的某個Offset,然后從這個位置再往后順序查找。
在內(nèi)存中用FST方式壓縮Term Index,F(xiàn)ST以字節(jié)的方式存儲所有的Term,這種壓縮方式可以有效的縮減存儲空間,使得Term Index足以放進內(nèi)存,但這種方式也會導致查找時需要更多的CPU 資源。
對于存儲在磁盤上的倒排表同樣也采用了壓縮技術(shù)減少存儲所占用的空間。

調(diào)整配置參數(shù)

調(diào)整配置參數(shù)建議如下:

  • 給每個文檔指定有序的具有壓縮良好的序列模式ID,避免隨機的UUID-4 這樣的ID,這樣的ID壓縮比很低,會明顯拖慢Lucene。

  • 對于那些不需要聚合和排序的索引字段禁用Doc values。

    Doc Values 是有序的、基于document=>field value的映射列表。

  • 不需要做模糊檢索的字段使用Keyword類型代替Text類型,這樣可以避免在建立索引前對這些文本進行分詞。

  • 如果你的搜索結(jié)果不需要近實時的準確度,考慮把每個索引的index.refresh_interval改到30s。

  • 如果你是在做大批量導入,導入期間你可以通過設置這個值為-1 關(guān)掉刷新,還可以通過設置 index.number_of_replicas: 0 關(guān)閉副本。別忘記在完工的時候重新開啟它。

  • 避免深度分頁查詢建議使用Scroll進行分頁查詢。普通分頁查詢時,會創(chuàng)建一個from+size的空優(yōu)先隊列,每個分片會返回from+size條數(shù)據(jù),默認只包含文檔ID和得分Score給協(xié)調(diào)節(jié)點。

  • 如果有N個分片,則協(xié)調(diào)節(jié)點再對(from+size)×n條數(shù)據(jù)進行二次排序,然后選擇需要被取回的文檔。當from很大時,排序過程會變得很沉重,占用CPU資源嚴重。減少映射字段,只提供需要檢索,聚合或排序的字段。其他字段可存在其他存儲設備上,例如HBase,在ES中得到結(jié)果后再去HBase 查詢這些字段。

  • 創(chuàng)建索引和查詢時指定路由Routing值,這樣可以精確到具體的分片查詢,提升查詢效率。路由的選擇需要注意數(shù)據(jù)的分布均衡。

JVM 調(diào)優(yōu)

JVM 調(diào)優(yōu)建議如下:
確保堆內(nèi)存最小值( Xms )與最大值( Xmx )的大小是相同的,防止程序在運行時改變堆內(nèi)存大小。
ES默認安裝后設置的堆內(nèi)存是 1GB??赏ㄟ^ ../config/jvm.option文件進行配置,但是最好不要超過物理內(nèi)存的50%和超過32GB。
GC 默認采用 CMS 的方式,并發(fā)但是有 STW 的問題,可以考慮使用 G1 收集器。
ES 非常依賴文件系統(tǒng)緩存(Filesystem Cache),快速搜索。一般來說,應該至少確保物理上有一半的可用內(nèi)存分配到文件系統(tǒng)緩存。


我要咨詢