Elasticsearch - Elasticsearch 集群搭建 3 节点基础配置
本文详细介绍了如何搭建一个3节点的Elasticsearch集群,涵盖硬件要求、软件依赖、服务器规划等准备工作,以及安装配置步骤。文章重点讲解了elasticsearch.yml的核心配置项,并提供了3个节点的具体配置示例。最后说明了集群启动流程和安全设置,包括初始化内置用户密码。通过本文,读者可以系统地掌握Elasticsearch集群部署的关键技能,构建具备高可用性和容错能力的分布式搜索系统。

👋 大家好,欢迎来到我的技术博客!
💻 作为一名热爱 Java 与软件开发的程序员,我始终相信:清晰的逻辑 + 持续的积累 = 稳健的成长。
📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。
🎯 本文将围绕ElasticSearch这个话题展开,希望能为你带来一些启发或实用的参考。
🌱 无论你是刚入门的新手,还是正在进阶的开发者,希望你都能有所收获!
文章目录
Elasticsearch - Elasticsearch 集群搭建:3 节点基础配置 🌐
在现代分布式系统中,Elasticsearch 已成为日志分析、全文搜索、实时监控等场景的首选引擎。然而,单节点部署仅适用于开发或测试环境,生产环境中必须使用集群架构以保障高可用性、容错能力和横向扩展能力。
本文将手把手带你从零开始,搭建一个 3 节点的 Elasticsearch 集群,涵盖网络配置、角色划分、安全设置、健康检查及 Java 客户端连接示例。无论你是 DevOps 工程师、后端开发者,还是刚接触 Elasticsearch 的新手,都能通过本文快速掌握集群部署的核心技能。
💡 为什么是 3 节点?
- 奇数节点可避免脑裂(Split-Brain);
- 最小高可用单元(容忍 1 节点故障);
- 资源开销适中,适合中小型企业起步。
一、准备工作:环境与依赖 🛠️
1. 硬件要求(最低建议)
| 组件 | 推荐配置 |
|---|---|
| CPU | 每节点 ≥ 2 核 |
| 内存 | 每节点 ≥ 4 GB(建议 8 GB+) |
| 存储 | 每节点 ≥ 20 GB SSD(用于测试) |
| 网络 | 节点间互通,延迟 < 1ms |
2. 软件依赖
- 操作系统:Linux(Ubuntu 22.04 / CentOS 7+)推荐,Windows 仅限测试;
- Java:OpenJDK 17(Elasticsearch 8.x+ 要求 JDK 17);
- Elasticsearch 版本:本文以 8.12.0 为例(截至 2025 年主流稳定版)。
3. 服务器规划
假设我们有三台虚拟机(或云主机):
| 主机名 | IP 地址 | 角色 |
|---|---|---|
| es-node-1 | 192.168.1.101 | master + data |
| es-node-2 | 192.168.1.102 | master + data |
| es-node-3 | 192.168.1.103 | master + data |
✅ 小集群中,通常让所有节点兼具 master 和 data 角色,简化架构。
二、安装 Elasticsearch 📦
以下操作需在 每台节点 上执行。
1. 安装 OpenJDK 17
# Ubuntu
sudo apt update
sudo apt install openjdk-17-jdk -y
# CentOS
sudo yum install java-17-openjdk-devel -y
验证:
java -version
# 应输出 openjdk version "17.x.x"
2. 下载并安装 Elasticsearch
# 添加 Elastic 官方 GPG 密钥
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elastic-keyring.gpg
# 添加 APT 源(Ubuntu)
echo "deb [signed-by=/usr/share/keyrings/elastic-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
# 安装
sudo apt update
sudo apt install elasticsearch -y
🔗 安装文档:Install Elasticsearch
3. 启动服务(暂不启动)
sudo systemctl daemon-reload
sudo systemctl enable elasticsearch
# 先不要 start,需先配置
三、核心配置:elasticsearch.yml 🧩
Elasticsearch 的集群行为主要由 elasticsearch.yml 控制。该文件位于 /etc/elasticsearch/elasticsearch.yml。
⚠️ 注意:每台节点的配置略有不同,尤其是
node.name和network.host。
通用配置项说明
| 配置项 | 说明 |
|---|---|
cluster.name |
集群名称,所有节点必须一致 |
node.name |
当前节点名称,需唯一 |
network.host |
绑定 IP,设为内网 IP 或 0.0.0.0(生产慎用) |
discovery.seed_hosts |
初始主节点发现列表 |
cluster.initial_master_nodes |
首次启动时的主节点候选列表(仅首次需要) |
node.roles |
节点角色(如 [master, data]) |
节点 1 配置(192.168.1.101)
# /etc/elasticsearch/elasticsearch.yml
cluster.name: my-es-cluster
node.name: es-node-1
node.roles: [ master, data ]
network.host: 192.168.1.101
http.port: 9200
discovery.seed_hosts: ["192.168.1.101", "192.168.1.102", "192.168.1.103"]
cluster.initial_master_nodes: ["es-node-1", "es-node-2", "es-node-3"]
# 安全设置(8.x 默认开启)
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
节点 2 配置(192.168.1.102)
cluster.name: my-es-cluster
node.name: es-node-2
node.roles: [ master, data ]
network.host: 192.168.1.102
http.port: 9200
discovery.seed_hosts: ["192.168.1.101", "192.168.1.102", "192.168.1.103"]
cluster.initial_master_nodes: ["es-node-1", "es-node-2", "es-node-3"]
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
节点 3 配置(192.168.1.103)
cluster.name: my-es-cluster
node.name: es-node-3
node.roles: [ master, data ]
network.host: 192.168.1.103
http.port: 9200
discovery.seed_hosts: ["192.168.1.101", "192.168.1.102", "192.168.1.103"]
cluster.initial_master_nodes: ["es-node-1", "es-node-2", "es-node-3"]
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
✅ 关键点:
cluster.name必须相同;node.name必须唯一;discovery.seed_hosts包含所有 master 候选节点 IP;cluster.initial_master_nodes仅在首次启动集群时需要,后续重启可注释或删除。
四、启动集群并初始化安全 🔐
1. 启动所有节点
在每台机器上执行:
sudo systemctl start elasticsearch
查看状态:
sudo systemctl status elasticsearch
# 确保 active (running)
2. 初始化内置用户密码(仅在一台节点执行)
Elasticsearch 8.x 默认启用安全功能,需为内置用户(如 elastic)设置密码。
sudo /usr/share/elasticsearch/bin/elasticsearch-setup-passwords auto
输出示例:
Changed password for user apm_system
PASSWORD apm_system = Hh8nK2pQxL...
Changed password for user elastic
PASSWORD elastic = s3cr3tP@ssw0rd!
...
📌 记下
elastic用户的密码,后续 Java 客户端连接需要。
🔗 安全配置指南:Secure a cluster
五、验证集群状态 ✅
1. 检查节点是否加入集群
在任意节点执行:
curl -u elastic:s3cr3tP@ssw0rd! http://192.168.1.101:9200/_cat/nodes?v
预期输出:
ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
192.168.1.101 20 80 2 0.10 0.05 0.01 mdi * es-node-1
192.168.1.102 18 78 1 0.08 0.04 0.00 mdi - es-node-2
192.168.1.103 19 79 2 0.09 0.06 0.01 mdi - es-node-3
mdi表示 master + data + ingest;*表示当前主节点。
2. 检查集群健康状态
curl -u elastic:s3cr3tP@ssw0rd! http://192.168.1.101:9200/_cluster/health?pretty
理想输出:
{
"cluster_name" : "my-es-cluster",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 3,
"number_of_data_nodes" : 3,
"active_primary_shards" : 0,
"active_shards" : 0,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 0
}
status: green表示一切正常;- 若为
yellow,通常因副本未分配(单节点常见,3 节点应为 green)。
六、集群架构图解 📊
下面用 Mermaid 展示 3 节点集群的逻辑结构:
graph TD
Client[Java Client] -->|HTTPS| LB[Load Balancer<br/>(可选)]
LB -->|9200| Node1[es-node-1<br/>192.168.1.101<br/>master + data]
LB -->|9200| Node2[es-node-2<br/>192.168.1.102<br/>master + data]
LB -->|9200| Node3[es-node-3<br/>192.168.1.103<br/>master + data]
Node1 <-->|Transport Port 9300| Node2
Node2 <-->|Transport Port 9300| Node3
Node3 <-->|Transport Port 9300| Node1
style Node1 fill:#e6f7ff,stroke:#1890ff
style Node2 fill:#e6f7ff,stroke:#1890ff
style Node3 fill:#e6f7ff,stroke:#1890ff
style LB fill:#f6ffed,stroke:#52c41a
💡 说明:
- 客户端可通过任一节点访问集群;
- 节点间通过 9300 端口(transport)通信;
- 生产环境建议前置负载均衡器(如 Nginx、HAProxy)。
七、Java 客户端连接示例 💻
Elasticsearch 8.x 推荐使用 官方 Java API Client(基于 HTTP,非 Transport Client)。
1. Maven 依赖
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>8.12.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.3</version>
</dependency>
2. 创建安全客户端
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
public class ESClientBuilder {
public static ElasticsearchClient createSecureClient(String host, int port, String username, String password) {
// 设置认证
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(
AuthScope.ANY,
new UsernamePasswordCredentials(username, password)
);
// 创建 RestClient
RestClient restClient = RestClient.builder(new HttpHost(host, port))
.setHttpClientConfigCallback(httpClientBuilder ->
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)
)
.build();
// 创建传输层
ElasticsearchTransport transport = new RestClientTransport(
restClient,
new JacksonJsonpMapper()
);
return new ElasticsearchClient(transport);
}
}
3. 测试集群连接
import co.elastic.clients.elasticsearch.core.InfoResponse;
public class ClusterHealthCheck {
public static void main(String[] args) throws Exception {
// 连接任意节点
ElasticsearchClient client = ESClientBuilder.createSecureClient(
"192.168.1.101", 9200, "elastic", "s3cr3tP@ssw0rd!"
);
// 获取集群信息
InfoResponse info = client.info();
System.out.println("Cluster Name: " + info.clusterName());
System.out.println("Version: " + info.version().number());
// 检查健康状态
var health = client.cluster().health();
System.out.println("Status: " + health.status());
System.out.println("Nodes: " + health.numberOfNodes());
client._transport().close();
}
}
输出示例:
Cluster Name: my-es-cluster
Version: 8.12.0
Status: GREEN
Nodes: 3
4. 写入与查询数据
import co.elastic.clients.elasticsearch.core.IndexRequest;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.search.Hit;
import java.time.Instant;
import java.util.Map;
public class DataOperations {
public static void main(String[] args) throws Exception {
ElasticsearchClient client = ESClientBuilder.createSecureClient(
"192.168.1.101", 9200, "elastic", "s3cr3tP@ssw0rd!"
);
// 写入文档
Map<String, Object> doc = Map.of(
"message", "Hello from Java!",
"@timestamp", Instant.now(),
"user_id", 123
);
IndexRequest indexReq = IndexRequest.of(i -> i
.index("test-index")
.document(doc)
);
var indexResp = client.index(indexReq);
System.out.println("Indexed ID: " + indexResp.id());
// 查询文档
SearchRequest searchReq = SearchRequest.of(s -> s
.index("test-index")
.query(q -> q.matchAll(m -> m))
.size(5)
);
var searchResp = client.search(searchReq, Object.class);
for (Hit<Object> hit : searchResp.hits().hits()) {
System.out.println("Source: " + hit.source());
}
client._transport().close();
}
}
🔗 Java Client 官方文档:Elasticsearch Java API Client
八、常见问题排查 🛠️
问题 1:节点无法加入集群
现象:_cat/nodes 只显示部分节点。
排查步骤:
- 检查防火墙:确保 9200(HTTP)和 9300(Transport) 端口开放;
sudo ufw allow 9200/tcp sudo ufw allow 9300/tcp - 检查
elasticsearch.yml中network.host是否绑定正确 IP; - 查看日志:
sudo journalctl -u elasticsearch -f。
问题 2:集群状态为 RED
原因:主分片丢失。
解决:
- 检查磁盘空间:
df -h; - 检查索引是否被误删;
- 若为新集群,可能因未创建索引,属正常(状态为 green)。
问题 3:SSL/TLS 错误(Java 客户端)
错误:javax.net.ssl.SSLHandshakeException
解决:Elasticsearch 8.x 默认使用自签名证书。开发环境可禁用证书验证(仅限测试!):
// 不推荐生产使用!
RestClient restClient = RestClient.builder(new HttpHost(host, port))
.setHttpClientConfigCallback(httpClientBuilder -> {
try {
SSLContext sslContext = SSLContextBuilder
.create()
.loadTrustMaterial(null, (chain, authType) -> true)
.build();
return httpClientBuilder
.setSSLContext(sslContext)
.setSSLHostnameVerifier((hostname, session) -> true);
} catch (Exception e) {
throw new RuntimeException(e);
}
})
.build();
✅ 生产环境应配置 CA 证书,参考:Configure TLS
九、生产环境增强建议 🚀
1. 角色分离(大规模集群)
当节点数 > 5 时,建议分离角色:
| 节点类型 | 数量 | 角色 |
|---|---|---|
| Master 节点 | 3 | [master] |
| Data 节点 | N | [data] |
| Ingest 节点 | 2 | [ingest] |
避免 master 节点承担数据压力。
2. 配置专用主节点
# master-only 节点
node.roles: [ master ]
3. 调整 JVM 堆内存
编辑 /etc/elasticsearch/jvm.options:
-Xms4g
-Xmx4g
⚠️ 堆内存 ≤ 32GB,且不超过物理内存 50%。
4. 启用监控
集成 Kibana + Metricbeat,监控集群性能。
🔗 监控方案:Elastic Stack Monitoring
十、自动化脚本示例 🤖
为简化部署,可编写 Ansible 或 Shell 脚本。
批量配置脚本(install-es.sh)
#!/bin/bash
# 在每台节点运行,传入节点名和IP
NODE_NAME=$1
IP_ADDR=$2
# 安装 JDK & ES(略)
# 生成 elasticsearch.yml
cat > /etc/elasticsearch/elasticsearch.yml <<EOF
cluster.name: my-es-cluster
node.name: $NODE_NAME
node.roles: [ master, data ]
network.host: $IP_ADDR
discovery.seed_hosts: ["192.168.1.101", "192.168.1.102", "192.168.1.103"]
cluster.initial_master_nodes: ["es-node-1", "es-node-2", "es-node-3"]
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
EOF
systemctl restart elasticsearch
调用:
# 在 192.168.1.101
./install-es.sh es-node-1 192.168.1.101
外部资源推荐 🔗
✅ 所有链接均经测试可正常访问(截至 2025 年 11 月)。
结语 🌟
搭建一个 3 节点的 Elasticsearch 集群,是迈向高可用搜索与分析系统的第一步。通过合理的配置、安全加固和客户端集成,你可以构建一个稳定、高效、可扩展的基础平台。
记住:集群不是搭完就结束,而是运维的开始。持续监控、定期备份、容量规划,才是保障长期稳定的关键。
现在,打开你的终端,开始部署吧!🚀
💬 提示:遇到问题?查看日志永远是第一选择:
journalctl -u elasticsearch -n 100。
Happy clustering! 😊
🙌 感谢你读到这里!
🔍 技术之路没有捷径,但每一次阅读、思考和实践,都在悄悄拉近你与目标的距离。
💡 如果本文对你有帮助,不妨 👍 点赞、📌 收藏、📤 分享 给更多需要的朋友!
💬 欢迎在评论区留下你的想法、疑问或建议,我会一一回复,我们一起交流、共同成长 🌿
🔔 关注我,不错过下一篇干货!我们下期再见!✨
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐



所有评论(0)