97色精品视频在线观看免费,日韩欧美亚洲每日更新网,国产精品色婷婷99久久精品,99e热久久免费精品首页

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

2024-11-08 14:11:37 Jinyu
圖片

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

一、ES 的基本使用

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

安裝使用

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

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


















{"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"}

集群健康狀態

要檢查群集運行狀況目前有很多監控比如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}

集群狀態通過 綠,黃,紅 來標識:

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

二、ES 機制原理

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

  • 它們內部是如何運行的?

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

  • 創建索引的流程是什么樣的?

  • ES如何將索引數據分配到不同的分片上的?

    以及索引數據是如何存儲的?

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

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

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

帶著這些疑問我們進入接下來的內容。

寫索引原理

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

圖片

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

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

實際上,這個過程和之前寫的Hash分片的路由方法,實際根據下面這個公式決定的:

shard = hash(routing) % number_of_primary_shards

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

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

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

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

在一個寫請求被發送到某個節點后,該節點即為前面說過的協調節點,協調節點會根據路由公式計算出需要寫到哪個分片上,再將請求轉發到該分片的主分片節點上。

圖片

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

存儲原理

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


path.data: /path/to/data//索引數據path.logs: /path/to/logs//日志記錄

分段存儲

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

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

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

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

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

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

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

  • 新增

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

  • 刪除

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

  • 更新

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

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

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

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

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

段的不變性的缺點如下:

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

延遲寫策略

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

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

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

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

這里的內存使用的是ES的JVM內存,而文件緩存系統使用的是操作系統的內存。

新的數據會繼續的被寫入內存,但內存中的數據并不是以段的形式存儲的,因此不能提供檢索功能。

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

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

默認情況下每個分片會每秒自動刷新一次。這就是為什么我們說Elasticsearch 是近實時搜索,因為文檔的變化并不是立即對搜索可見,但會在一秒之內變為可見。

我們也可以手動觸發 Refresh:



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

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

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

圖片

索引寫流程

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

圖片

segment合并

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

六、ES 的性能優化

存儲設備

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

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

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

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

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

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

內部索引優化

圖片

索引優化

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

調整配置參數

調整配置參數建議如下:

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

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

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

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

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

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

  • 避免深度分頁查詢建議使用Scroll進行分頁查詢。普通分頁查詢時,會創建一個from+size的空優先隊列,每個分片會返回from+size條數據,默認只包含文檔ID和得分Score給協調節點。

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

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

JVM 調優

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


我要咨詢
主站蜘蛛池模板: 五大连池市| 光泽县| 巢湖市| 广灵县| 安岳县| 岳普湖县| 友谊县| 驻马店市| 咸阳市| 渭南市| 垣曲县| 汉沽区| 乌拉特中旗| 康保县| 临猗县| 平陆县| 博客| 恭城| 玉屏| 新疆| 公主岭市| 淮阳县| 新安县| 北安市| 馆陶县| 尼勒克县| 托克逊县| 新营市| 甘泉县| 许昌市| 庄河市| 汶川县| 奉新县| 玉门市| 安化县| 静安区| 眉山市| 德州市| 柞水县| 连城县| 夏河县|