<漫談ElasticSearch>關於ES性能調優幾件必須知道的事

来源:http://www.cnblogs.com/guguli/archive/2016/02/25/5218297.html
-Advertisement-
Play Games

原創博客,轉載請聯繫博主! (零)ElasticSearch架構概述 ElasticSearch是現在技術前沿的大數據引擎,常見的組合有ES+Logstash+Kibana作為一套成熟的日誌系統,其中Logstash是ETL工具,Kibana是數據分析展示平臺。ES讓人驚艷的是他強大的搜索相關能力和


原創博客,轉載請聯繫博主!

 

 

 

(零)ElasticSearch架構概述

 

ElasticSearch是現在技術前沿的大數據引擎,常見的組合有ES+Logstash+Kibana作為一套成熟的日誌系統,其中Logstash是ETL工具,Kibana是數據分析展示平臺。ES讓人驚艷的是他強大的搜索相關能力和災備策略,ES開放了一些介面供開發者研發自己的插件,ES結合中文分詞的插件會給ES的搜索和分析起到很大的推動作用。ElasticSearch是使用開源全文檢索庫ApacheLucene進行索引和搜索的,說架構必須和Lucene的一些東西打交道。

 

關於Lucene:

ApacheLucene將寫入索引的所有信息組織成一種倒排索引(Inverted Index)的結構之中,該結構是種將詞項映射到文檔的數據結構。其工作方式與傳統的關係資料庫不同,大致來說倒排索引是面向詞項而不是面向文檔的。且Lucene索引之中還存儲了很多其他的信息,如詞向量等等,每個Lucene都是由多個構成的,每個段只會被創建一次但會被查詢多次,段一旦創建就不會再被修改。多個段會在段合併的階段合併在一起,何時合併由Lucene的內在機制決定,段合併後數量會變少,但是相應的段本身會變大。段合併的過程是非常消耗I/O的,且與之同時會有些不再使用的信息被清理掉。在Lucene中,將數據轉化為倒排索引,將完整串轉化為可用於搜索的詞項的過程叫做分析。文本分析由分析器(Analyzer)來執行,分析其由分詞器(Tokenizer),過濾器(Filter)和字元映射器(Character Mapper)組成,其各個功能顯而易見。除此之外,Lucene有自己的一套完整的查詢語言來幫助我們進行搜索和讀寫。

 

 [註]ES中的索引指的是查詢/定址時URI中的一個欄位如:[host]:[port(9200)]/[index]/[type]/[ID]?[option],而Lucene中的索引更多地和ES中的分片的概念相對應。

 

回到ElasticSearch,ES的架構遵循的設計理念有以下幾個特征:

 

1. 合理的預設配置:只需修改節點中的Yaml配置文件,就可以迅捷配置。這和Spring4中對配置的簡化有相似的地方。

2. 分散式工作模式:ES強大的Zen發現機制不僅支持組廣播也支持點單播,且有“知一點即知天下”之妙。

3. 對等架構:節點之間自動備份分片,且使分片本身和樣本之間儘量”遠離“,可以避免單點故障。且Master節點和Data節點幾乎完全等價。

4. 易於向集群擴充新節點:大大簡化研發或運維將新節點加入集群所需的工作。

5. 不對索引中的數據結構增加任何限制:ES支持在一個索引之中存在多種數據類型。

6. 準實時:搜索和版本同步,由於ES是分散式應用,一個重大的挑戰就是一致性問題,無論索引還是文檔數據,然而事實證明ES表現優秀。

 

 

(一)分片策略

 

選擇合適的分片數和副本數ES的分片分為兩種,主分片(Primary Shard)和副本(Replicas)。預設情況下,ES會為每個索引創建5個分片,即使是在單機環境下,這種冗餘被稱作過度分配(Over Allocation),目前看來這麼做完全沒有必要,僅在散佈文檔到分片和處理查詢的過程中就增加了更多的複雜性,好在ES的優秀性能掩蓋了這一點。假設一個索引由一個分片構成,那麼當索引的大小超過單個節點的容量的時候,ES不能將索引分割成多份,因此必須在創建索引的時候就指定好需要的分片數量。此時我們所能做的就是創建一個新的索引,併在初始設定之中指定這個索引擁有更多的分片。反之如果過度分配,就增大了Lucene在合併分片查詢結果時的複雜度,從而增大了耗時,所以我們得到了以下結論:

我們應該使用最少的分片!

主分片,副本和節點最大數之間數量存在以下關係:

節點數<=主分片數*(副本數+1)

 

 控制分片分配行為。以上是在創建每個索引的時候需要考慮的優化方法,然而在索引已創建好的前提下,是否就是沒有辦法從分片的角度提高了性能了呢?當然不是,首先能做的是調整分片分配器的類型,具體是在elasticsearch.yml中設置cluster.routing.allocation.type屬性,共有兩種分片器even_shard,balanced(預設)。even_shard是儘量保證每個節點都具有相同數量的分片,balanced是基於可控制的權重進行分配,相對於前一個分配器,它更暴漏了一些參數而引入調整分配過程的能力。

每次ES的分片調整都是在ES上的數據分佈發生了變化的時候進行的,最有代表性的就是有新的數據節點加入了集群的時候。當然調整分片的時機並不是由某個閾值觸發的,ES內置十一個裁決者來決定是否觸發分片調整,這裡暫不贅述。另外,這些分配部署策略都是可以在運行時更新的,更多配置分片的屬性也請大家自行Google。

 

 

(二)路由優化

 

ES中所謂的路由和IP網路不同,是一個類似於Tag的東西。在創建文檔的時候,可以通過欄位為文檔增加一個路由屬性的Tag。ES內在機制決定了擁有相同路由屬性的文檔,一定會被分配到同一個分片上,無論是主分片還是副本。那麼,在查詢的過程中,一旦指定了感興趣的路由屬性,ES就可以直接到相應的分片所在的機器上進行搜索,而避免了複雜的分散式協同的一些工作,從而提升了ES的性能。於此同時,假設機器1上存有路由屬性A的文檔,機器2上存有路由屬性為B的文檔,那麼我在查詢的時候一旦指定目標路由屬性為A,即使機器2故障癱瘓,對機器1構不成很大影響,所以這麼做對災況下的查詢也提出瞭解決方案。所謂的路由,本質上是一個分桶(Bucketing)操作。當然,查詢中也可以指定多個路由屬性,機制大同小異。

 

 

(三)ES上的GC調優

 

ElasticSearch本質上是個Java程式,所以配置JVM垃圾回收器本身也是一個很有意義的工作。我們使用JVM的Xms和Xmx參數來提供指定記憶體大小,本質上提供的是JVM的堆空間大小,當JVM的堆空間不足的時候就會觸發致命的OutOfMemoryException。這意味著要麼記憶體不足,要麼出現了記憶體泄露。處理GC問題,首先要確定問題的源頭,一般有兩種方案:

 

1. 開啟ElasticSearch上的GC日誌

2. 使用jstat命令

3. 生成記憶體Dump

 

關於第一條,在ES的配置文件elasticsearch.yml中有相關的屬性可以配置,關於每個屬性的用途這裡當然說不完。

第二條,jstat命令可以幫助我們查看JVM堆中各個區的使用情況和GC的耗時情況。

第三條,最後的辦法就是將JVM的堆空間轉儲到文件中去,實質上是對JVM堆空間的一個快照。

想瞭解更多關於JVM本身GC調優方法請參考:http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html

另外,通過修改ES節點的啟動參數,也可以調整GC的方式,但是實質上和上述方法是等同的。

 

 

(四)避免記憶體交換

 

這一點很簡單,由於操作系統的虛擬記憶體頁交換機制,會給性能帶來障礙,如數據寫滿記憶體會寫入Linux中的Swap分區。

可以通過在elasticsearch.yml文件中的bootstrap.mlockall設置為true來實現,但是需要管理員許可權,需要修改操作系統的相關配置文件。

 

 

(五)控制索引合併

 

上文提到過,ES中的分片和副本本質上都是Lucene索引,而Lucene索引又基於多個索引段構建(至少一個),索引文件中的絕大多數都是只被寫一次,讀多次,在Lucene內在機制控制下,當滿足某種條件的時候多個索引段會被合併到一個更大的索引段,而那些舊的索引段會被拋棄並移除磁碟,這個操作叫做段合併。 

Lucene要執行段合併的理由很簡單充分:索引段粒度越小,查詢性能越低且耗費的記憶體越多。頻繁的文檔更改操作會導致大量的小索引段,從而導致文件句柄打開過多的問題,如修改系統配置,增大系統允許的最大文件打開數。總的來講,當索引段由多一個合併為一個的時候,會減少索引段的數量從而提高ES性能。對於研發者來講,我們所能做的就是選擇合適的合併策略,儘管段合併完全是Lucene的任務,但隨著Lucene開放更多配置藉口,新版本的ES還是提供了三種合併的策略tiered,log_byte_size,log_doc。另外,ES也提供了兩種Lucene索引段合併的調度器:concurrent和serial。其中各者具體區別,這裡暫不贅述,只是拋磚引玉。

 

 

 

打字好累,大家晚安。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 作為一名iOS開發者,我經歷過幾個沒有設計師的項目,結果就是,痛苦的一逼。做這種類型的項目,設計是非常重要的,特別是迭代設計。 在每個項目最開始的時候,客戶其實並不知道自己想要什麼。直接堆碼之前我們還是有點小小的設計知識更有助於你跟客戶撕逼的時候占上風,其實我們只是想更完美,難道不是嗎? 這裡我更推
  • 什麼是SQLite SQLite是一款輕型的嵌入式資料庫 它占用資源非常的低,在嵌入式設備中,可能只需要幾百K的記憶體就夠了 它的處理速度比Mysql、PostgreSQL這兩款著名的資料庫都還快 什麼是資料庫 資料庫(Database)是按照數據結構來組織、存儲和管理數據的倉庫 資料庫可以分為2大種
  • 當我看到這周的每周一文的題目是“關於對資料庫的認識和理解”的時候,我突然覺得無從下手,因為我不知道寫什麼,自己對資料庫的理解和接觸過的資料庫,僅僅限於課堂上老師講過的微軟公司的SQLServer2008,對於其他的資料庫自己也只是道聽途說。於是乎我瘋狂的在網上找資料,從不同的方面瞭解了當前的幾種主流
  • https://support.microsoft.com/en-us/kb/904803 Character data is represented incorrectly when the code page of the client computer differs from the cod
  • 昨天下午快下班的時候 因為公司需要折騰了下sql server 2000,先不說這麼古老的版本,而且安裝的也是醉了... 首先sql server 2000是基於32位的系統開發的,那時候據說還沒有64位的系統...所以是X86的,網上就找不到64 位! 的我的電腦是win7 64的,安裝的時候果然
  • 該文章主要作為Hadoop技巧系列文章的索引,方便大家閱覽。
  • PostgreSQL的AVG函數是用來找出各種記錄中的一個欄位的平均值。 為了理解AVG函數考慮表COMPANY 有如下記錄: testdb# select * from COMPANY; id | name | age | address | salary ----+-------+-----+-
  • Oracle連接odbc數據源 說明 oracle連接ODBC數據源有兩種方式,hsodbc和dg4odbc,簡單說dg4odbc是hsodbc的升級。兩種連接方法大致一樣,現將連接步驟說明如下: 檢查DG4ODBC驅動是否已經安裝 方法如下: 在Oracle伺服器上,cmd視窗中執行命令(dg4o...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...