Elasticsearch Two-node Cluster
双节点集群 Two-node cluster
- 实际是主从结构,集群自动同步保持数据一致性
- 从节点宕机了,主依然可读写;health 会变为 yellow ;
- 主节点宕机了,从只能读;部分集群相关 path 接口不可用,因为要查询 主,但主宕机了;
- 每个分片数据冗余存储到另一个节点上;
- 客户端需要通过 load balance 访问集群,或设置失败重试轮写另一个,避免写固定一个节点;
- 不推荐在生产环境使用此结构;
从零开始搭建步骤
测试环境
- ES 版本 8.18.2
- 虚拟机系统
如果每个 ES 节点部署在不同主机上,注意:
- 各个主机之间可互相访问 9200 (HTTP 默认 http.port )和 9300 (transport 默认 transport.port )端口
- 各个 ES 节点数据目录为空,不能已初始化或加入过其他集群
下载二进制包
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.18.2-darwin-x86_64.tar.gz
tar -xzf elasticsearch-8.18.2-darwin-x86_64.tar.gz
cd elasticsearch-8.18.2配置 es01 节点
mkdir es01
cp -a config es01/修改 es01/config/elasticsearch.yml
bootstrap.memory_lock: true
xpack.security.enabled: false
xpack.security.enrollment.enabled: false
xpack.security.http.ssl.enabled: false
xpack.security.transport.ssl.enabled: false
path.data: es01/data
path.logs: es01/logs
http.port: 9201
transport.port: 9301
cluster.name: my-cluster
node.name: es01
network.host: 0.0.0.0
cluster.initial_master_nodes: ["es01"]
# 多个 ES 节点部署在不同主机上时需要设置
network.publish_host: "10.0.0.1"
discovery.seed_hosts: ["10.0.0.1", "10.0.0.2"]启动 es01 节点 ES_PATH_CONF=es01/config bin/elasticsearch
INFO
默认通过 bin/elasticsearch 启动 ES 实例时,它会强制使用和 bin/ 目录同一层级的 config/ 目录作为配置目录。如果想使用同一个二进制包,启动多个 ES 实例,可通过指定环境 ES_PATH_CONF 值修改配置目录。
修改 es02/config/elasticsearch.yml
bootstrap.memory_lock: true
xpack.security.enabled: false
xpack.security.enrollment.enabled: false
xpack.security.http.ssl.enabled: false
xpack.security.transport.ssl.enabled: false
path.data: es02/data
path.logs: es02/logs
http.port: 9202
transport.port: 9302
cluster.name: my-cluster
node.name: es02
network.host: 0.0.0.0
cluster.initial_master_nodes: ["es01"]
# 多个 ES 节点部署在不同主机上时需要设置
network.publish_host: "10.0.0.2"
discovery.seed_hosts: ["10.0.0.1", "10.0.0.2"]如果开发环境两个节点部署在同一个机器上(如 es01 10.0.0.1:9200/9300, es02 10.0.0.1:9202/9302 ),需修改以下选项:
# 指定 node 具体的 ip:port
cluster.initial_master_nodes: ["10.0.0.1:9200"]
network.publish_host: "10.0.0.1"
# 指定 node 具体的 ip:port
discovery.seed_hosts: ["10.0.0.1:9300", "10.0.0.1:9302"]启动 es02 节点 ES_PATH_CONF=es02/config bin/elasticsearch
(可选)启动 kibana 实例
- 在任意一个节点上重置 kibana_system 用户密码,如
ES_PATH_CONF=es02/config bin/elasticsearch-reset-password -u kibana_system -i - 修改 kibana 配置文件后启动 kibana 实例
kibana 配置文件参考:
elasticsearch.hosts: ["http://localhost:9200", "http://localhost:9201"]
# optional
elasticsearch.username: "kibana_system"
elasticsearch.password: "kibana_system"实验 1: 集群(green)可用时,可同时读写主或从节点
写 es01 curl -XPOST -H 'Content-Type: application/json' 'localhost:9201/myidx/_doc/1?pretty' -d '{"id":"1","title":"hello"}'
分别读 es01 es02
curl -H 'Content-Type: application/json' 'localhost:9201/myidx/_search?pretty'curl -H 'Content-Type: application/json' 'localhost:9202/myidx/_search?pretty'
输出结果一致
实验 2: 仅从节点宕机,主节点可读写
停止 es02, 写 es01 curl -XPOST -H 'Content-Type: application/json' 'localhost:9201/myidx/_doc/2?pretty' -d '{"id":"2","title":"world"}'
读 es01 curl -H 'Content-Type: application/json' 'localhost:9201/myidx/_search?pretty'
输出说明主节点可读写
启动 es02,读 es02
curl -H 'Content-Type: application/json' 'localhost:9202/myidx/_search?pretty'
输出说明从节点恢复后自动同步保持一致性。
实验 3: 仅主节点宕机,从节点只读
停止 es01, 写 es02 curl -XPOST -H 'Content-Type: application/json' 'localhost:9202/myidx/_doc/3?pretty' -d '{"id":"3","title":"foo"}'
es02 客户端堵塞直到超时报错。
读 es02 文档 curl -H 'Content-Type: application/json' 'localhost:9202/myidx/_search?pretty'
输出说明从节点仅可只读。
读 es02 集群相关 path curl 'localhost:9202/_cluster/stats?human&pretty'
输出说明从节点 集群相关接口 path 不可用。
启动 es01,写 es02 curl -XPOST -H 'Content-Type: application/json' 'localhost:9202/myidx/_doc/4?pretty' -d '{"id":"4","title":"bar"}'
分别读 es01 es02
curl -H 'Content-Type: application/json' 'localhost:9201/myidx/_search?pretty'curl -H 'Content-Type: application/json' 'localhost:9202/myidx/_search?pretty'curl 'localhost:9201/_cluster/stats?human&pretty'curl 'localhost:9202/_cluster/stats?human&pretty'
输出说明集群可用后,又可同时读写主从。
将单个节点集群扩容为两个
原有节点 1 的数据保留,修改 ES 节点 1 配置后,重启节点实例:
- 去掉
discovery.type: single-node或新建容器实例去掉启动参数discovery.type=single-node - 新增或修改以下集群相关参数,每个节点的
node.namenetwork.host和network.publish_host选项值不一样,其他应该一样
参考配置:
cluster.name: my-cluster
node.name: es01
network.host: 0.0.0.0
cluster.initial_master_nodes: ["es01"]
# 多个 ES 节点部署在不同主机上时需要设置
network.publish_host: "10.0.0.1"
discovery.seed_hosts: ["10.0.0.1", "10.0.0.2"]参考以上,新增数据目录为空、未加入过其他集群的新 ES 节点 2 的配置,并启动新实例。
访问集群
查看集群健康状态(人读表格格式) curl 'localhost:9200/_cat/health?v'
查看集群健康状态(JSON 格式) curl localhost:9200/_cluster/health
查看集群统计信息 curl "localhost:9200/_cluster/stats"
使用 ES SDK 或 第三方库访问 ES 时自定义 hosts 字符串数组参数,指定多个 node ["http://lcoalhsot:9201","http://lcoalhsot:9202"]; 默认库通过 round-robin 算法轮流读写每个 node ,避免只有一个节点过载。
