Elasticsearch的部署要比Solr友善很多: Solr要通過Tomcat/Jetty等Web容器釋出服務, 并使用ZooKeeper作為注冊中心進行選舉、配置檔案的管理等工作.
而ES隻需要啟動一個服務, 其内部已實作注冊和選舉, 因而更加輕量化.
本篇博文以Elasticsearch 6.6.0版本為例, 從0開始搭建一個3節點的生産叢集, 并對搭建過程中可能出現的問題及解決方法做個記錄.
目錄
- 1 配置環境
- 1.1 伺服器IP映射
- 1.2 配置各節點的ssh免密通信
- 1.3 安裝JDK并配置環境變量
- 2 部署單節點服務
- 3 部署叢集服務
- 4 啟動叢集中的所有節點
- 4.2 啟動各個節點中的ES服務
- 4.2 檢視叢集狀态
- 5 常見問題及解決方法
- 5.1 新節點不能加入叢集
- 5.2 反序列化失敗
- 5.3 其他問題
- 版權聲明
開始之前:
關于ES單機服務的部署, 可參考博文: ES 02 - 部署Elasticsearch單機服務 + 部署中的常見問題
關于叢集的服務配置建議, 可以參考上一篇博文: ES 30 - Elasticsearch生産叢集的伺服器配置建議
配置伺服器IP位址與主機名稱的映射, 友善維護與遷移.
依次編輯三台伺服器的
伺服器IP 映射的主機名 172.16.22.131 es-1 172.16.22.132 es-2 172.16.22.133 es-3 檔案, 添加映射内容:
/etc/hosts
[root@localhost ~]# vim /etc/hosts # 添加下述内容: 172.16.22.131 es-1 172.16.22.132 es-2 172.16.22.133 es-3
Elasticsearch叢集中各個節點之間需要通信, 配置免密通信是必須的.
參考博文 Linux - 配置SSH免密登入 - “ssh-keygen”的基本用法 完成相關免密通信的配置.
學習使用ES的前提是成功安裝JDK —— 很基礎的一項步驟, 這裡省略.
此處學習示範所用的JDK版本為:
[root@localhost ~]# java -version
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)
請參照博文 ES 02 - 部署Elasticsearch單機服務 + 部署中的常見問題 進行操作, 如果過程中遇到不可知的問題, 可在評論區留言, 部落客會在看到後的第一時間回複.
與部署單機服務不同的地方 —— 修改配置檔案
/data/elk-6.6.0/es-node/config/elasticsearch.yml
:
# 大約17行, 修改叢集名稱, 同一個叢集中此名稱必須相同, 才能組成一個邏輯叢集:
cluster.name: heal_es
# 大約23行, 修改節點名稱, 可以設定為與主機名稱相同:
node.name: es-1
# 大約55行, 指定可通過外部伺服器通路本地ES服務:
network.host: 0.0.0.0
# 并指定通路的端口号, 預設是9200, 為了防止沖突, 這裡修改為9301:
http.port: 9301
# 大約68行, 指定初始的主機清單, 用來在新節點啟動時執行發現功能:
discovery.zen.ping.unicast.hosts: ["es-1", "es-2", "es-3"]
注意: 修改完配置後, 先不要啟動服務, 所有節點中的安裝包都整理完畢, 再依次啟動.
—— 因為ES服務一旦啟動, 就會在
${ES_HOME}/data/
下生成叢集資料, 包括節點id、節點鎖(node lock)等, 不同節點的這些資料都不同, 如果相同則會導緻啟動異常.
(1) 将配置好的安裝包分發到節點es-2和es-3上:
# 切換回root使用者
[elastic@localhost data]$ su root
Password:
# 輸入密碼後, 分發安裝包:
[root@localhost data]# scp -r elk-6.6.0/ es-2:/data
[root@localhost data]# scp -r elk-6.6.0/ es-3:/data
(2) 向es-2和es-3中添加elastic使用者群組, 并修改檔案權限:
[root@localhost data]# useradd elastic -s /bin/bash
[root@localhost data]# chown -R elastic:elastic /data/elk-6.6.0/
(3) 修改es-2和es-3節點的配置檔案:
同樣的, 修改
elasticsearch.yml
檔案, 這時隻修改node名稱即可:
[root@localhost ~]# vim /data/elk-6.6.0/es-node/config/elasticsearch.yml
# 大約23行, 修改節點名稱, 可以設定為與主機名稱相同. 分别修改為es-2和es-3
node.name: es-...
(4) 如有必要-删除從es-1拷貝而來的data目錄下的檔案:
如果在從es-1節點分發安裝包時, 已經啟動了es-1上的ES服務, 那麼還要删除es-2和es-3節點中
${ES_HOME}/data/
下的所有檔案, 防止後續啟動失敗.
啟動順序沒有要求:
# 切換為elastic使用者:
[root@localhost ~]# su elastic
# 進入到啟動指令所在的目錄:
[elastic@localhost root]$ cd /data/elk-6.6.0/es-node/bin/
# 背景啟動服務:
[elastic@localhost bin]$ sh elasticsearch -d
(1) 隻啟動一個節點時的叢集狀态:

(2) 啟動全部節點後的叢集狀态:
(1) 問題描述:
啟動叢集中的第二、三個節點時可能出現下述異常中的一種:
① 擷取node lock失敗:
[2019-06-24T22:04:06,665][WARN ][o.e.b.ElasticsearchUncaughtExceptionHandler] [es-3] uncaught exception in thread [main] org.elasticsearch.bootstrap.StartupException: java.lang.IllegalStateException: failed to obtain node locks, tried [[/data/elk-6.6.0/es-node/data]] with lock id [0]; maybe these locations are not writable or multiple nodes were started without increasing [node.max_local_storage_nodes] (was [1])? at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:163) ~[elasticsearch-6.6.0.jar:6.6.0] at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:150) ~[elasticsearch-6.6.0.jar:6.6.0] at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86) ~[elasticsearch-6.6.0.jar:6.6.0] at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124) ~[elasticsearch-cli-6.6.0.jar:6.6.0] at org.elasticsearch.cli.Command.main(Command.java:90) ~[elasticsearch-cli-6.6.0.jar:6.6.0] at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:116) ~[elasticsearch-6.6.0.jar:6.6.0] at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:93) ~[elasticsearch-6.6.0.jar:6.6.0] ... 6 more
② 加入叢集的請求發送失敗:
# 節點[es-3]向master節點[es-1]發送加入叢集的請求失敗. [es-3] failed to send join request to master [{es-1}{jcmbr9dgRgaAWUE7xq5xAw}{wxvCc19lQvmc3xmcRHdbqA}{172.16.22.131}{172.16.22.131:9300}{ml.machine_memory=134908342272, ml.max_open_jobs=20, xpack.installed=true, ml.enabled=true}], reason [RemoteTransportException[[es-1][172.16.22.131:9300][internal:discovery/zen/join]]; # 内部原因是: 節點id相同, 但并不是同一個節點執行個體. nested: IllegalArgumentException[can't add node {es-3}{jcmbr9dgRgaAWUE7xq5xAw}{WXjlsD1zTWCm6YaWAAUoOg}{172.16.22.133}{172.16.22.133:9300}{ml.machine_memory=135220408320, ml.max_open_jobs=20, xpack.installed=true, ml.enabled=true}, found existing node {es-1}{jcmbr9dgRgaAWUE7xq5xAw}{wxvCc19lQvmc3xmcRHdbqA}{172.16.22.131}{172.16.22.131:9300}{ml.machine_memory=134908342272, xpack.installed=true, ml.max_open_jobs=20, ml.enabled=true} with the same id but is a different node instance]; ]
(2) 問題分析:
節點二、三的安裝包都是從節點一分發而來的, 由于分發時節點一已經啟動, 其
${ES_HOME}/data/
目錄下已生成node相關的資料, 這些資料應該由目前節點自動生成, 不能共用. 如果這些資料相同就會出現上述異常.
(3) 問題解決:
删除節點二、三的資料目錄
${ES_HOME}/data/
下的所有檔案, 然後重新啟動即可.
(1) 問題說明:
節點啟動過程中抛出如下錯誤:
org.elasticsearch.transport.RemoteTransportException: Failed to deserialize exception response from stream
各個Elasticsearch節點中的服務所使用的JDK版本不一緻, 在 ES 30 - Elasticsearch生産叢集的伺服器配置建議 的第5節
5 JVM的參數配置
中有相關說明:
ES中用到了很多與JVM版本相關的特性, 比如本地序列化機制 (包括IP位址、異常資訊等等), 而JVM在不同的minor版本中可能會修改序列化機制, 版本不同可能會導緻序列化異常.
更換JDK版本, 并更新環境變量配置, 保證各節點使用的JDK版本一緻.
更多問題可以參考博文: ES 02 - 部署Elasticsearch單機服務 + 常見問題的解決 中第5節内容
5 常見問題及解決方法
.
作者: 馬瘦風(https://healchow.com)
出處: 部落格園 馬瘦風的部落格(https://www.cnblogs.com/shoufeng)
感謝閱讀, 如果文章有幫助或啟發到你, 點個[好文要頂👆] 或 [推薦👍] 吧😜
本文版權歸部落客所有, 歡迎轉載, 但 [必須在文章頁面明顯位置标明原文連結], 否則部落客保留追究相關人員法律責任的權利.