以下我們將基于 elasticsearch-6.6.0 版本,在單機上部署 3 個節(jié)點組成的集群。3個節(jié)點都用作候選主節(jié)點,且同時作為數(shù)據(jù)節(jié)點。
集群搭建
下載 elasticsearch-6.6.0 二進制包,解壓,復制 3 份,分別命名為 es1, es2, es3。
分別修改 config/elasticsearch.yml 的配置,
es1 如下:
# 集群名稱,相同集群的節(jié)點名稱一致
cluster.name: my-application
# 節(jié)點名稱
node.name: es1
# 數(shù)據(jù)存儲路徑
path.data: /path/to/es1/data
# 日志存儲路徑
path.logs: /path/to/es1/logs
# 是否用作候選主節(jié)點,默認為 true
node.master: true
# 是否用作數(shù)據(jù)節(jié)點,默認為 true
node.data: true
# HTTP 端口,提供 RESTful 服務交互
http.port: 5201
# TCP 端口,集群節(jié)點之間通信
transport.tcp.port: 5301
# 集群中相互通信的節(jié)點
discovery.zen.ping.unicast.hosts: ["localhost:5301","locahost:5302","locahost:5303"]
# 集群最小主節(jié)點個數(shù)
discovery.zen.minimum_master_nodes: 2
es2 如下:
# 集群名稱,相同集群的節(jié)點名稱一致
cluster.name: my-application
# 節(jié)點名稱
node.name: es2
# 數(shù)據(jù)存儲路徑
path.data: /path/to/es2/data
# 日志存儲路徑
path.logs: /path/to/es2/logs
# 是否用作候選主節(jié)點,默認為 true
node.master: true
# 是否用作數(shù)據(jù)節(jié)點,默認為 true
node.data: true
# HTTP 端口,提供 RESTful 服務交互
http.port: 5202
# TCP 端口,集群節(jié)點之間通信
transport.tcp.port: 5302
# 集群中相互通信的節(jié)點
discovery.zen.ping.unicast.hosts: ["localhost:5301","locahost:5302","locahost:5303"]
# 集群最小主節(jié)點個數(shù)
discovery.zen.minimum_master_nodes: 2
es3 如下:
# 集群名稱,相同集群的節(jié)點名稱一致
cluster.name: my-application
# 節(jié)點名稱
node.name: es3
# 數(shù)據(jù)存儲路徑
path.data: /path/to/es3/data
# 日志存儲路徑
path.logs: /path/to/es3/logs
# 是否用作候選主節(jié)點,默認為 true
node.master: true
# 是否用作數(shù)據(jù)節(jié)點,默認為 true
node.data: true
# HTTP 端口,提供 RESTful 服務交互
http.port: 5203
# TCP 端口,集群節(jié)點之間通信
transport.tcp.port: 5303
# 集群中相互通信的節(jié)點
discovery.zen.ping.unicast.hosts: ["localhost:5301","locahost:5302","locahost:5303"]
# 集群最小主節(jié)點個數(shù),為了防止腦裂,最小主節(jié)點個數(shù)應該為(候選主節(jié)點個數(shù) / 2 + 1)
discovery.zen.minimum_master_nodes: 2
- 分別啟動 3 個節(jié)點
cd /path/to/es1
bin/elasticsearch -d
- 在瀏覽器中查看集群狀態(tài)

可視化管理
通過 elasticsearch-head 可以可視化的管理 es 集群。
elasticsearch-head 項目地址 http://mobz.github.io/elasticsearch-head。
如果本地有 nodejs 環(huán)境,通過以下步驟安裝 elasticsearch-head。
git clone git://github.com/mobz/elasticsearch-head.git
cd elasticsearch-head
npm install
npm run start
安裝完成,在瀏覽器中訪問 http://localhost:9100/

elasticsearch-head 在訪問 es 實例 RESTful API 時會存在跨域問題,es 實例啟動時,配置文件需要添加一下參數(shù)
http.cors.enabled: true
http.cors.allow-origin: "*"
基礎操作
創(chuàng)建索引
PUT /my_index
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 0
}
}
number_of_shards: 主分片數(shù)量,默認為 5
number_of_replicas: 分片副本數(shù)量,默認為 1
動態(tài)更新副本數(shù)量
PUT /my_index/settings
{
"number_of_replicas": 1
}
高可用性驗證
這里以另外一個真實在用的集群來演示集群的高可用性。
步驟一
- 索引
app_jgus_yn與app_jgus都是在單節(jié)點集群情況下創(chuàng)建的,默認主分片數(shù)量為 5,副本數(shù)量為 0。 - 后來,集群擴展到 3 個節(jié)點,我為
app_jgus動態(tài)更新了副本數(shù)量為 1。 - 該集群處于 green 狀態(tài):

步驟二
- 集群中 es3 節(jié)點失敗了,集群處于 red 狀態(tài),有主分片缺失,此時集群不可用。
- 對
app_jgus索引的查詢依然可以正常進行,因為app_jgus的每個主分片都有 1 個副本,剩余 2 個節(jié)點中保存有所有的索引數(shù)據(jù)。 - 索引
app_jgus_yn由于沒有為主分片生成副本,隨 es3 節(jié)點失敗,缺少了 2 個主分片,缺失的分片數(shù)據(jù)將無法被操作。

步驟三
- 重啟 es3 節(jié)點,刷新查看集群狀態(tài)

- 最終,集群狀態(tài)恢復為步驟一中的正常狀態(tài)
步驟四
- 為索引
app_jgus_yn動態(tài)更新副本數(shù)量,將number_of_replicas設為 1,即每個主分片都有 1 份副本。 - 每個分片都擁有了 1 份副本,集群處于 green 狀態(tài)

步驟五
- 原主節(jié)點宕機,es3 被選為新的主節(jié)點。
- 由于原來每個主分片,都有副本,雖然一個節(jié)點宕機了,但其他 2 個節(jié)點有所有的數(shù)據(jù),依賴可以完成所有的數(shù)據(jù)操作。此時,集群狀態(tài)為 yellow。

- 一段時間以后,新的集群將達到 green 狀態(tài)

步驟六
- 恢復原節(jié)點,相當于在已經(jīng)穩(wěn)定的集群中再新增節(jié)點。
- 集群將在新節(jié)點上分配數(shù)據(jù),并最終達到新的 green 狀態(tài)。

問題排查記錄
問題一
在集群搭建完成以后,創(chuàng)建索引過程中,遇到了數(shù)據(jù)分片 unassigned 的異常。大致情況如下:

查看分片 unassigned 原因
GET /_cluster/allocation/explain?pretty

這里是因為空間不夠引起的。
解決方案是調(diào)整集群磁盤水印的參數(shù)。
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.disk.watermark.high": "95%",
"cluster.routing.allocation.disk.watermark.low": "93%"
}
}
問題二
集群搭建過程中,配置文件顯式指定 transport.tcp.port ,但未顯式設置 discovery.zen.ping.unicast.hosts 時,幾個節(jié)點之間無法組成集群,各自獨立。
我在配置時,3 個 es 節(jié)點的 transport.tcp.port 分別為 5301、5302、5303。當沒有顯式設置 discovery.zen.ping.unicast.hosts 時,會自動按照 9300、9301、9302 的端口順序設置這個廣播地址,因此無法與真實的實例端口通信。以上是我通過查看進程占用的端口得出的結(jié)論。
參考
ElasticSearch高可用集群環(huán)境搭建和分片原理
如何在Elasticsearch中解析未分配的分片(unassigned shards)
Elasticsearch 學習筆記 索引創(chuàng)建、插入、查詢、修改、刪除
如果你看完本文有收獲,歡迎關注我的公眾號:精進Java (craft4j)。這是一個專注 于Java 后端與架構(gòu)內(nèi)容學習分享的公眾號。