Elasticsearch 5.x 生產環境和節點配置
Elasticsearch中擁有大量的自定義配置項,除了以下一些官方不能統一進行配置的選項(與環境,使用者情況有關),大多數最好不要自行配置,因為會引起很多不必要的麻煩(不好排查),並且es的很多預設項的已經是比較優的配置(包括效能方面)。
Elasticsearch有兩個主要的配置檔案:elasticsearch.yml用於elasticsearch主配置(還有jvm.options),log4j2.properties為其日誌檔案。
1) 、配置檔案位置
Elasticsearch有兩個主要的配置檔案:
1、elasticsearch.yml
用於elasticsearch主配置(還有jvm.options)若使用Debian或RPM安裝,該檔案位於/etc/elasticsearch/目錄下;
2、log4j2.properties
log4j2.properties為其日誌檔案,位於es的安裝目錄下的config資料夾下,如:$ES_HOME/config/
3、動態載入配置項
啟動時可以在配置檔案中進行載入,也可以動態進行引數設定,如下是設定path.conf屬性:
./bin/elasticsearch -Epath.conf=/path/to/my/config/
2) 、配置檔案格式
配置檔案為YAML格式,索引可以使用一下兩種方式進行設定,如:
或者path: data: /var/lib/elasticsearch logs: /var/log/elasticsearch
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
3) 、環境變數替換
使用環境變數替換配置中的值,如:
node.name: ${HOSTNAME}
network.host: ${ES_NETWORK_HOST}
4) 、提示設定
當在配置中使用${prompt.text} 或 ${prompt.secret} 設定某一屬性值時,如下(節點名稱):
node:
name: ${prompt.text}
如下(需要輸入節點的名稱,則繼續後面的啟動步驟):則該服務作為一個後臺啟動服務啟動,但是需要在服務啟動時提示輸入動態的屬性值,
Enter value for [node.name]:
5)、日誌配置
Es使用Log4j 2作為日誌記錄,使用log4j2.properties進行日誌配置,但是es使用了三個屬性配置方式暴露日誌檔案的配置(日誌配置到哪個位置嗎,檔案的名稱等),分別為:${sys:es.logs.base_path}, ${sys:es.logs.cluster_name}, and ${sys:es.logs.node_name}。由於一般建議配置日誌node.name屬性,所以一直配置說明如下(比如):
若path.logs配置為預設值/var/log/elasticsearch,叢集名稱屬性cluster.name配置為production,則按照日誌模板${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}.log,生產的日誌為/var/log/elasticsearch/production.log
可以載入多個配置檔案(在這種情況下,它們將被合併),只要它們被命名為log4j2.properties並es的配置目錄下;這對於暴露額外記錄者的外掛非常有用。
更多詳細陪參見log4j2。
6) 、日誌等級
有四種配置日誌級別的方法,每種方法都有適合使用的情況:
1、命令列方式
-E <name of logging hierarchy>=<level> ,當您臨時除錯單個節點上的問題時(例如,啟動或開發期間的問題),這是最合適的。如:
service elasticsearch start -E logger.org.elasticsearch.transport=trace
2、elasticsearch.yml中格式配置
配置格式為<name of logging hierarchy>:<level>,適用場景如你更持久的基礎上進行日誌記錄級別的調整,可以在配置檔案中載入如下設定:
logger.org.elasticsearch.transport: trace
動態地調整活動叢集上的日誌級別時,可以使用該方式,格式為:
PUT /_cluster/settings
{
"transient": {
"<name of logging hierarchy>": "<level>"
}
}
例如:
PUT /_cluster/settings
{
"transient": {
"logger.org.elasticsearch.transport": "trace"
}
}
4、log4j2.properties方式設定
使用場景:對日誌記錄器進行細粒度控制時,這是最合適的(例如,您希望將日誌記錄器傳送到另一個檔案,或者以不同的方式管理日誌記錄器;這是一個罕見的用例),格式如下:
logger.<unique_identifier>.name = <name of logging hierarchy>
logger.<unique_identifier>.level = <level>
例如:
logger.transport.name = org.elasticsearch.transport
logger.transport.level = trace
7) 、開啟禁用日誌級別
預設情況下的日誌基本為error,但是某些情況下(如es版本升級時)需要檢視更多的日誌基本資訊,可以檢視已經棄用的warm基本日誌,則可以將log4j2.properties檔案中的基本進行修改,如下:
logger.deprecation.level = warn
並且預設情況下,已經為棄用日誌級別開啟了滾動策略,在日誌到達1G之後進行滾動和壓縮,並保留最大的5個日誌檔案(4個卷日誌和活動日誌)。
二、elasticsearch.yml常用配置
1)、cluster.name
配置es的叢集名稱,預設是elasticsearch,es會自動發現在同一網段下的es,如果在同一網段下有多個叢集,就可以用這個屬性來區分不同的叢集,入elasticsearch_production。
2)、node.name
配置叢集節點名,若不配置預設隨機指定一個name列表中名字,該列表在es的jar包中config資料夾裡name.txt檔案中,其中有很多作者新增的有趣名字。該名字最好自行配置,建議自行配置如:node-1等。
3)、node.master
指定該節點是否有資格被選舉成為master node,預設是true,es是預設叢集中的第一臺機器為master,如果這臺機掛了就會重新選舉master。
4)、node.data
指定該節點是否儲存索引資料,預設為true。
Master node(主節點): node.master:true node.data:false
Data node(資料節點): node.master:false node.data:true
Client node(客戶端節點): node.master:false node.data:false
5)、index.number_of_shards
設定預設索引分片個數,預設為5片,一般使用預設即可。
6)、index.number_of_replicas
設定預設索引副本個數,預設為1個副本,一般使用預設即可,即5個主分片5個副本分片。
以下三個配置項:可以配置多個位置,並且配置多個位置擁有更好的效能和安全性。並且自定義配置路徑可以避免重新安裝 Elasticsearch的時候不小心把安裝目錄覆蓋了,照成不必要的影響。
7)、path.data: /path/to/data1,/path/to/data2
配置索引分片資料的位置
8)、path.plugins: /path/to/plugins
安裝外掛的位置
9)、path.logs: /path/to/logs
設定日誌檔案的儲存路徑,預設是es根目錄下的logs資料夾。儲存了大量我們關係的生產日誌資料。
10)、bootstrap.memory_lock: true
在比較早的版本中使用配置引數bootstrap.mlockall,設定為true來鎖住記憶體。詳細參見配置中的swapping模組。
11)、discovery.zen.minimum_master_nodes
叢集選舉最小的最小節點數,為防止腦裂的設定引數。由於網路的不確定性,可能存在一個叢集存在兩個或者多個主節點(擁有最高許可權,可以決定新的索引的建立,分片是如何移動等資訊),則會照成資料的不完整等情況。
該引數的設定一般為叢集中的可選擇為主節點的節點數決定,與資料節點的個數無關,即與每個節點的node.master和node.data引數設定有關,計算公式如下:
( master 候選節點個數 / 2) + 1
由於該欄位設定的重要性,所以可以在叢集執行中動態進行設定,這將成為一個永久的配置,並且無論你配置項裡配置的如何,這個將優先生效。當你新增和刪除 master 節點的時候,你需要更改這個配置。設定方式如下:
PUT /_cluster/settings
{
"persistent" : {
"discovery.zen.minimum_master_nodes" : 2
}
}
12)、network.host
節點ip設定(並且設定後將會從development模式轉換為production模式)
13)、http.port: 9200
埠設定http埠範圍[9200-9300),一般使用預設9200。http埠可用於http叢集外掛的使用,但是同時需要配置以下項:
14)、http.cors.enabled: true
15)、http.cors.allow-origin: "*"
16)、transport.tcp.port: 9300
設定節點間互動的tcp埠,即節點通訊埠,預設是9300。node-to-node埠設定範圍[9300-9400)
17)、discovery.zen.ping.unicast.hosts: ["host1", "host2:port"]
Es的Discover模組提供了單播和組播的方式發現叢集中的其他節點以組成叢集,但是生產環境中應該只能使用單播發現的方式,所以5.x後es只提供了外掛方式的組播發現方式。為防止其他不可控的因素將節點加點到叢集,可以設定單播發現的叢集列表單,可以配置ip或埠(預設9200)。
三、安全設定
對應某些敏感的資訊,完全依賴於檔案系統的許可權來保護它們的值是不夠的,需要使用elasticsearch的elasticsearch-keystore工具的引入。引入後所有的命令都需要使用該使用者許可權執行。
工具的建立(開啟):
./bin/elasticsearch-keystore create
敏感的字串設定,比如雲外掛的身份驗證憑證:
bin/elasticsearch-keystore add the.setting.name.to.set
移除:
bin/elasticsearch-keystore remove the.setting.name.to.remove
四、啟動檢查
1)、全域性啟動檢查
在之前的版本中,將某些啟動配置設定為warm級別很容易被忽略,為了確保這些資訊被關注,現在需要在啟動時進行檢查。並且很多生成情況下遇到的很多奇怪的問題都是因為下面第五點中的重要啟動配置而照成,所以需要特別關注。很多檢查在development模式下僅為warm級別,但是在production模式下,檢查不通過則不允許啟動。以下是一些在兩種模式下都需要檢查的設定。
1、Development 和 production模式
叢集節點的http通訊和節點間通訊使用http.host和transport.host在es的配置檔案中進行配置,並且也是通過判斷通訊方式是否通過外網介面進行暴露,以判斷es是否為生產模式狀態。預設情況下,當下載了Es包進行安裝則為開發模式,該模式可以方便的使用single-node discovery。
2、single-node Discovery
有時候需要將傳輸繫結到一個外部介面,以測試他們對傳輸客戶機的使用情況。並且節點將自行選擇主節點,並且不會與任何其他節點一起連線叢集。則需要在配置檔案中新增:
discovery.type:single-node
3、生產中強制禁用啟動檢查
有時候需要在生成環境中只啟動單節點(這種情況下,可以將IP設定為外網或內網介面暴露但是一定需要將single-node開啟),則需要開啟強制不檢查啟動的開關。可以在jvm.options中進行配置:
es.enforce.bootstrap.checks:true
還可以使用環境變數ES_JAVA_OPTS中增加-Des.enforce.bootstrap.checks=true進行設定。
2) 、Heap size check(堆大小檢查)
如果JVM的Heap的初始值和最大堆大小是不相等的,那麼當JVM堆在系統使用期間被調整時,它很容易出現停頓。為了避免出現該情況,需要將兩個值設定一致。如果bootstrap.memory_lock 設定為true,則不允許記憶體交換,在該情況下,如果初始堆大小不等於最大堆大小,那麼在重新調整大小之後,就不是所有的JVM堆都被鎖定在記憶體中了。
在Unix(Linux)中一切都是一個檔案,而Es需要大量的檔案描述符,因為es的shard是由大量的檔案(document)組成。所以es啟動前需要檢查系統配置的檔案描述符號大小。
當Jvm在進行GC操作時,會觸及堆的每一個頁面。如果這些頁面中的任何一個被交換到磁碟上它們就必須被交換到記憶體中。為了防止涉及的記憶體與磁碟之前的轉換,需要將堆記憶體進行鎖定(不予許轉換為磁碟形式),鎖定方式有很多種,一種是使用jvm鎖定記憶體。但是不同的作業系統是不同的,即mlockall (Unix) 和virtual lock (Windows),並且該操作需要特殊的執行許可權。需要在es中設定bootstrap.memory_lock屬性的設定需要檢查許可權等,所以mlockall 設定時,可能導致es不能正常啟動。
Elasticsearch將請求分為不同的階段,並將不同的階段任務交給不同的執行緒池完成。所以在es內部需要建立不同種類的執行緒池,並且在Linux系統中必須配置,以允許es程序能夠建立至少2048個執行緒。可以在/etc/security/limits.conf配置中,使用nproc 進行配置(當然讓該使用者擁有root許可權)。
Elasticsearch和Lucene利用mmap將索引的部分對映到Elasticsearch的地址空間。這樣就可以將某些索引資料從JVM堆中保留下來,但在記憶體中可以快速訪問,則Elasticsearch需要無限的地址空間。最大的虛擬記憶體檢查要求Elasticsearch程序具有無限的地址空間,並且只在Linux上進行檢查。可以在/etc/security/limits.conf 配置 as 為 unlimited進行設定,或者也可以給使用者root許可權。
Ealsticsearch的分片是由大量的檔案組成的,並且有些檔案可能會超過千兆位元組,所以在Es執行時可能會因為需要建立或寫的檔案過大而失敗,所以啟動時需要檢查系統是否設定建立大檔案的許可權。可以通過/etc/security/limits.conf 配置的fsize 為 unlimited進行設定,當然還是可以給使用者root許可權。
在Linux系統下,Elasticsearch同樣需要建立足夠多(至少262,144)的memory-mapped(mmap)空間,可以使用vm.max_map_count 通過 sysctl進行配置。
9) 、Client JVM check(OpenJdk的client Jvm檢查)
OpenJDK提供了兩種jvm,分別為client和server的jvm,由於兩者需要做的事和效能要求是完全不同的,即提供的位元組碼也是不同的。所以在啟動時需要檢查一定為server型別的jvm。
Serial的垃圾回收器主要使用者單核cpu或者比較小的堆(heap)的伺服器,但是對於Elasticsearch來說這是致命的,確保你沒有配置顯示的配置serial的垃圾回收器如:-XX:+UseSerialGC,相對而言使用預設的CMS垃圾回收器對於Elasticsearch是比較友好的。
Elasticsearch被安裝在不同的作業系統上,而作業系統會安裝不同的System call filters系統呼叫過濾器,以防止安裝的程式(現為Elasticsearch)執行forking 相關的操作,建立程式碼執行攻擊的防禦機制。如在Centos 6中由於沒有seccomp ,所以直接導致es不能正常的啟動。可以使用bootstrap.system_call_filter 為 false進行設定。
說明:Seccomp(secure computing)是Linux kernel(自從2.6.23版本之後)所支援的一種簡潔的sandboxing機制。它能使一個程序進入到一種“安全”執行模式,該模式下的程序只能呼叫4種系統呼叫(system calls),即read(), write(), exit()和sigreturn(),否則程序便會被終止。
OnError 和OnOutOfMemoryError配置執行Jvm在遭遇到大量的錯誤或者記憶體溢位時能正常的執行,但是預設情況下作業系統的系統呼叫過濾器是開啟的,而兩者配置是不相容的,索引Es啟動時需要檢查兩者不能同時進行配置。當然8u92版本jdk後使用ExitOnOutOfMemoryError。
OpenJDK 提供了比較新的snapshots (快照)版本,這不適用於生產環境,所以要求在生產上使用合適的版本以通過該檢查。
14)、G1GC check(HotSpot JVM的G1GC垃圾回收器檢查)
使用JDK 8自帶的HotSpot JVM的早期版本有一些問題,在啟用G1GC收集器時可能會導致索引損壞,這也是致命的,所以需要檢查這些版本中沒有開啟G1GC垃圾回收器。
五、重要的啟動配置
最理想的情況是將Elasticsearch部署在單獨的伺服器上,但是非要和其他服務一起部署則要求es能夠分配到足夠多的資源。並且在開發模式和生成模式下的日誌基本是完全不一樣的,則下面的配置的重要性則尤為重要,可能直接影響到Es叢集的效能。並且下面的配置完全針對於Centos系統。
1、配置系統設定
配置系統的unlimit限制屬性,可以使用臨時設定(會話範圍內有效),當然該配置一般需要root許可權,所以一般配置步驟如下(可以使用ulimit -a進行查詢):
-- 使用elasticsearch使用者進行操作
sudo su
ulimit -n 65536
su elasticsearch
當然我們應該是需要永久的設定(會在使用者下一次開啟會話時生效),在/etc/security/limits.conf配置中增加或修改(以下是elasticsearch使用者的許可權,可以修改為*則對所有使用者生效):
elasticsearch - nofile 65536
// 可以修改為 * - nofile 65536
2、Systemd配置
如果使用rpm或者Debian 安裝es,則可以使用systemd方式進行配置,limit配置在/usr/lib/systemd/system/elasticsearch.service中作為預設配置生效。但是可以修改或新增檔案/etc/systemd/system/elasticsearch.service.d/override.conf(可以使用sudo systemctl edit elasticsearch命令修改),配置如下:
[Service]
LimitMEMLOCK=infinity
並且執行以下操作以生效:
sudo systemctl daemon-reload
3、設定Jvm選項
jvm引數最好在jvm.options配置中進行設定,設定規則為在設定引數前加上-符號。
堆記憶體大小設定可以使用ES_HEAP_SIZE方式,或者在啟動時使用(如:./bin/elasticsearch -Xmx10g -Xms10g),當前建議使用jvm.options方式進行設定,如:
-Xms2g
-Xmx2g
預設情況下,5.x版本的Elasticsearch的預設最大和最小記憶體都為2g,但是在生成環境下該引數的設定尤為重要,但是一般需要遵守以下幾個設定原則:
1、Xms和Xmx的值大小一致以防止程式在執行時改變堆記憶體大小,這是一個很耗系統資源的過程。
2、設定的堆越多,它用於快取的記憶體就越多,但是過多的堆可能會使您面臨長時間的gc暫停。
3、一般設定實體記憶體的一半為堆記憶體
一個常見的問題是給 Elasticsearch 分配的記憶體 太 大了。 假設你有一個 64 GB 記憶體的機器, 天啊,我要把 64 GB 記憶體全都給 Elasticsearch。因為越多越好啊!
當然,記憶體對於 Elasticsearch 來說絕對是重要的,它可以被許多記憶體資料結構使用來提供更快的操作。但是說到這裡, 還有另外一個記憶體消耗大戶 非堆記憶體 (off-heap):Lucene。
Lucene 被設計為可以利用作業系統底層機制來快取記憶體資料結構。 Lucene 的段是分別儲存到單個檔案中的。因為段是不可變的,這些檔案也都不會變化,這是對快取友好的,同時作業系統也會把這些段檔案快取起來,以便更快的訪問。
Lucene 的效能取決於和作業系統的相互作用。如果你把所有的記憶體都分配給 Elasticsearch 的堆記憶體,那將不會有剩餘的記憶體交給 Lucene。 這將嚴重地影響全文檢索的效能。
標準的建議是把 50% 的可用記憶體作為 Elasticsearch 的堆記憶體,保留剩下的 50%。當然它也不會被浪費,Lucene 會很樂意利用起餘下的記憶體。
如果你不需要對分詞字串做聚合計算(例如,不需要 fielddata )可以考慮降低堆記憶體。堆記憶體越小,Elasticsearch(更快的 GC)和 Lucene(更多的記憶體用於快取)的效能越好。
4、堆記憶體大小不要超過32g
這裡有另外一個原因不分配大記憶體給 Elasticsearch。事實上 , JVM 在記憶體小於 32 GB的時候會採用一個記憶體物件指標壓縮技術。
在 Java 中,所有的物件都分配在堆上,並通過一個指標進行引用。 普通物件指標(OOP)指向這些物件,通常為CPU 字長 的大小:32位或64位,取決於你的處理器。指標引用的就是這個OOP值的位元組位置。
對於 32 位的系統,意味著堆記憶體大小最大為4 GB。對於64位的系統, 可以使用更大的記憶體,但是64位的指標意味著更大的浪費,因為你的指標本身大了。更糟糕的是, 更大的指標在主記憶體和各級快取(例如LLC,L1等)之間移動資料的時候,會佔用更多的頻寬。
Java 使用一個叫作 記憶體指標壓縮(compressed oops)的技術來解決這個問題。它的指標不再表示物件在記憶體中的精確位置,而是表示 偏移量 。這意味著 32 位的指標可以引用 40億個 物件 , 而不是40 億個位元組。最終, 也就是說堆記憶體增長到32 GB的實體記憶體,也可以用32位的指標表示。
一旦你越過那個神奇的 ~32 GB 的邊界,指標就會切回普通物件的指標。 每個物件的指標都變長了,就會使用更多的 CPU記憶體頻寬,也就是說你實際上失去了更多的記憶體。事實上,當記憶體到達40–50 GB的時候,有效記憶體才相當於使用記憶體物件指標壓縮技術時候的32 GB記憶體。
這段描述的意思就是說:即便你有足夠的記憶體,也儘量不要 超過 32 GB。因為它浪費了記憶體,降低了 CPU的效能,還要讓GC應對大記憶體。
那麼怎麼知道有沒有超越該臨界值,可以在日誌中查詢以下資訊:
heap size [1.9gb], compressed ordinary object pointers [true]
5、壓縮的閾值確認
既然要求堆記憶體為少於實體記憶體的一半,並且不超過閾值,而且在改範圍內越大越好,那麼知道系統的閾值是多少就顯得特別重要,一般來說只要不超過26G就在閾值以下,但是有的閾值可以到達30g,所以需要顯示的告訴我們系統的閾值。可以通過在配置中增加以下:
-XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode
並且在日誌中查詢以下資訊:
heap address: 0x000000011be00000, size: 27648 MB, zero based Compressed Oops
或
heap address: 0x0000000118400000, size: 28672 MB, Compressed Oops with base: 0x00000001183ff000
大多數作業系統都儘量使用盡可能多的記憶體來儲存檔案系統快取,並在超過一定值時自然的交換未使用的應用程式記憶體。這可能導致JVM堆的某些部分,甚至它的可執行頁面被交換到磁碟(個人理解為當查過一定設定值時,記憶體中的資料被持久化或者說序列化),這樣的方式對於一般的程式來說是很好的預設方式,但是對於需要效能的Elasticsearch來說是致命的。
應該不惜一切代價避免記憶體交換,它可以導致垃圾收集持續數分鐘,而不是毫秒,並且可能導致節點響應緩慢,甚至斷開與叢集的連線。在es叢集中的影響比作業系統殺死節更致命。
以下有三種方式用於完全禁用或者將記憶體交換控制在一定範圍內:
1、系統級別的完全禁止記憶體交換
由於作業系統中可能不止es服務,該操作為系統級別的禁止記憶體交換,會對所有的應用生效,臨時禁用可以使用以下命令:
sudo swapoff -a
完全禁用需要註釋掉/etc/fstab檔案中將所有包含swap的行(但是我並沒有在我的伺服器上找到該配置)。
2、為記憶體交換設定一個指定的值(不建議)
這降低了核心交換的傾向,並且不應該在正常情況下導致交換,同時仍然允許整個系統在緊急情況下交換。設定方式如下sysctl 中這樣配置(設定為0等可能會有問題):
vm.swappiness = 1
3、設定es的bootstrap.memory_lock的屬性
使用 mlockall 在 Linux/Unix 作業系統中禁用記憶體交換,在elasticsearch.yml中增加配置(該配置啟用後mlockall 會試圖分配更多記憶體,mlockall可能會導致JVM或shell會話退出。我有遇到這樣的問題,就是服務啟動後通過service elasticsearch status檢視是ok的,過幾秒鐘就發現沒有啟動起來):
bootstrap.memory_lock: true
可以通過以下方式檢視是否啟動禁用記憶體交換(false標識沒有啟動):
GET _nodes?filter_path=**.mlockall
不能正常啟動有以下兩個主要原因:
沒有許可權
使用其他方式安裝就不進行說了,有以下兩種方式進解決:1、在/etc/security/limits.conf中增加配置MAX_LOCKED_MEMORY 為 unlimited 2、systemd方式,在中配置LimitMEMLOCK為infinity(最後使用該配置成功,生產環境中/etc/fstab下沒有swap相關配置項,/etc/security/limits.conf中配置也不生效)詳細如下:
查詢結果,在kibana的DevTools中查詢
GET _nodes?filter_path=**.mlockall
結果為:
{
"nodes": {
"tXfBk9rwQzi8pPhrFGlxJw": {
"process": {
"mlockall": true
}
},
"_EuJzUMlSCqwiHDXLh6aDA": {
"process": {
"mlockall": true
}
}
}
}
臨時目錄(通常是/tmp)與noexec選項一起掛載
可以通過使用esjava選用環境變數指定一個新的臨時目錄來解決這一問題,如下:
export ES_JAVA_OPTS="$ES_JAVA_OPTS -Djava.io.tmpdir=/path/to/temp/dir"
./bin/elasticsearch
Elasticsearch使用大量的檔案描述符或檔案控制代碼。耗盡檔案描述符可能是災難性的,並且很可能導致資料丟失。一般需要設定65536或者更大,若使用RPM或者 Debian安裝包則預設已經將該引數調整為65536.調整方式:將/etc/security/limits.conf配置檔案的nofile 引數調整為 65536,可以使用es的Node Stats進行檢視,如下:
GET _nodes/stats/process?filter_path=**.max_file_descriptors
結果如下:
{
"nodes": {
"tXfBk9rwQzi8pPhrFGlxJw": {
"process": {
"max_file_descriptors": 65536
}
},
"_EuJzUMlSCqwiHDXLh6aDA": {
"process": {
"max_file_descriptors": 65536
}
}
}
}
在預設情況下,Es使用mmapfs目錄來儲存它的索引,作業系統預設的mmap計數限制可能過低,這可能導致記憶體異常。當然RPM和Debian軟體包將自動配置此設定,不需要進一步的配置。可以使用以下方式臨時設定:
sysctl -w vm.max_map_count=262144
當然一般需要在配置檔案/etc/sysctl.conf修改vm.max_map_count屬性的值,並且需要長期伺服器並且使用sysctl vm.max_map_count命令查詢。
Elasticsearch的各種型別的操作需要交給不同的執行緒池完成,要求能夠在需要的時候建立新的執行緒,至少2048。可以使用ulimit -u 2048臨時設定,若需要永久調整,需要也在配置檔案/etc/security/limits.conf.中將nproc引數修改為不小於 2048
那麼具體的執行緒應該設定多大,這個也是需要關注的,描述如下:
執行緒池
許多人 喜歡 調整執行緒池。 無論什麼原因,人們都對增加執行緒數無法抵抗。索引太多了?增加執行緒!搜尋太多了?增加執行緒!節點空閒率低於 95%?增加執行緒!
Elasticsearch 預設的執行緒設定已經是很合理的了。對於所有的執行緒池(除了 搜尋 ),執行緒個數是根據 CPU 核心數設定的。 如果你有 8 個核,你可以同時執行的只有 8 個執行緒,只分配 8 個執行緒給任何特定的執行緒池是有道理的。
搜尋執行緒池設定的大一點,配置為 int(( 核心數 * 3 )/ 2 )+ 1 。
你可能會認為某些執行緒可能會阻塞(如磁碟上的 I/O 操作),所以你才想加大執行緒的。對於 Elasticsearch 來說這並不是一個問題:因為大多數 I/O 的操作是由 Lucene 執行緒管理的,而不是 Elasticsearch。
此外,執行緒池通過傳遞彼此之間的工作配合。你不必再因為它正在等待磁碟寫操作而擔心網路執行緒阻塞, 因為網路執行緒早已把這個工作交給另外的執行緒池,並且網路進行了響應。
最後,你的處理器的計算能力是有限的,擁有更多的執行緒會導致你的處理器頻繁切換執行緒上下文。 一個處理器同時只能執行一個執行緒。所以當它需要切換到其它不同的執行緒的時候,它會儲存當前的狀態(暫存器等等),然後載入另外一個執行緒。 如果幸運的話,這個切換髮生在同一個核心,如果不幸的話,這個切換可能發生在不同的核心,這就需要在核心間總線上進行傳輸。
這個上下文的切換,會給 CPU 時鐘週期帶來管理排程的開銷;在現代的 CPUs 上,開銷估計高達 30 μs。也就是說執行緒會被堵塞超過 30 μs,如果這個時間用於執行緒的執行,極有可能早就結束了。
人們經常稀裡糊塗的設定執行緒池的值。8 個核的 CPU,我們遇到過有人配了 60、100 甚至 1000 個執行緒。 這些設定只會讓 CPU 實際工作效率更低。
所以,下次請不要調整執行緒池的執行緒數。如果你真 想調整 , 一定要關注你的 CPU 核心數,最多設定成核心數的兩倍,再多了都是浪費。
六、Elasticsearch升級
七、Elasticsearch stop
Es的啟動方式有很多種,當然停止的方式也相對應,但是建議使用service elasticsearch stop進行停止。但是當服務執行的時候可以回遇到一些不期而遇的問題導致服務不可用,那麼服務本身會嘗試將錯誤日誌進行記錄,下面是常見的錯誤的其編碼對比: