1. 从单点到集群:为什么你的下一个搜索服务必须是分布式的?
最近在帮一个做内容平台的朋友做技术架构升级,他们原来的站内搜索用的是单节点的 Elasticsearch,平时查询量不大倒也相安无事。直到上个月搞了一次大促活动,用户激增,搜索接口的响应时间直接从几十毫秒飙到了两三秒,后台监控一看,CPU和内存直接打满,整个搜索服务几乎瘫痪。这场景太典型了——单点架构的性能和可用性天花板,在业务量稍微起来一点之后,就成了最脆弱的那个环节。
所以,当你的数据量开始以GB甚至TB计,当你的QPS(每秒查询率)从几十上升到几百上千,当你的业务无法容忍因为一次服务器重启或网络抖动就导致搜索服务不可用时,部署一个Elasticsearch集群就不再是“可选项”,而是“必选项”。这不仅仅是把一份数据复制到多台机器那么简单,它背后是一整套关于数据分片、负载均衡、故障自动转移和高可用的设计哲学。简单来说,集群化部署的核心目标就两个:扛住更大的数据量和更高的并发,以及确保服务在部分节点挂掉时依然能活下来。
基于这个目标,一个典型的Elasticsearch生产集群会包含几种角色节点:负责处理读写请求的主节点(Master-eligible nodes)、真正存储数据和执行搜索的数据节点(Data nodes),以及专门处理搜索请求、减轻数据节点压力的协调节点(Coordinating nodes)。在实际部署中,我们往往会根据服务器资源,采用混合部署或角色分离的策略。这次,我们就以最经典的三节点集群为例,手把手走一遍在Linux环境下的部署、配置和核心调优全过程。你会发现,从零搭建一个稳定可靠的ES集群,远没有想象中那么复杂,但其中的每一个细节,都决定了它未来是“稳如老狗”还是“坑你无数”。
2. 集群部署前的核心规划:避开“想当然”的配置陷阱
在动手敲下任何安装命令之前,规划是决定成败的第一步。很多新手容易犯的错误就是,找三台机器,把同样的配置复制三份,然后启动,以为集群就建好了。结果往往在运行一段时间后,出现脑裂、数据不平衡、性能瓶颈等各种诡异问题。所以,我们先来理清几个关键规划点。
2.1 节点角色与服务器规划
首先,我们需要明确集群的拓扑结构。对于一个三节点的起步集群,常见的角色分配有两种方案:
方案一:全能型节点(混合角色)这是最简单直接的方案,每个节点同时具备主节点资格、存储数据和协调请求的能力。它的优点是部署简单,资源利用率高,适合资源有限或测试环境。
- 优点:配置简单,无需复杂网络规划,任意节点都能接收请求。
- 缺点:角色耦合,一旦某个节点负载过高(比如密集的写入操作),可能会影响集群管理(主节点选举)或搜索性能。生产环境数据量大或查询复杂时,这种相互干扰会比较明显。
方案二:角色分离这是生产环境的推荐做法,尤其当服务器资源相对充足时。我们可以将角色分开,甚至使用专用服务器。
- 专用主节点:只参与集群管理(如索引创建、分片分配、节点状态维护),不存储数据。这能保证集群管理的稳定性和响应速度。通常3个专用主节点就能满足高可用,它们对CPU、内存和磁盘要求都不高。
- 专用数据节点:只负责存储索引分片、执行数据的增删改查(CRUD)和搜索、聚合操作。它们是资源消耗大户,需要强大的CPU、大内存(尤其是JVM Heap和文件系统缓存)以及高速磁盘(推荐SSD)。
- 专用协调节点:作为客户端请求的入口,负责接收请求、将请求路由到相关数据节点、合并结果并返回给客户端。它们是无状态的,可以水平扩展以应对高并发查询。
对于我们的三节点起步集群,如果资源允许,我强烈建议采用一个折中但更稳健的方案:三个节点都具备主节点资格,但同时承担数据和协调角色,但在配置上为未来分离留出余地。这样既保证了主节点的高可用(至少3个以防止脑裂),又能利用所有节点的存储和计算资源。
服务器硬件建议:
- CPU:现代多核处理器,数据节点建议16核以上。
- 内存:至关重要。需要分配两部分:
- JVM堆内存:官方建议不超过物理内存的50%,且不超过32GB(超过32GB会由于JVM指针压缩失效反而可能降低性能)。对于16G内存的机器,设置
-Xms8g -Xmx8g是合理的起点。 - 操作系统缓存:剩下的内存留给Lucene(ES底层搜索引擎)使用,它依赖文件系统缓存来加速读取。内存越大,缓存越多,搜索越快。
- JVM堆内存:官方建议不超过物理内存的50%,且不超过32GB(超过32GB会由于JVM指针压缩失效反而可能降低性能)。对于16G内存的机器,设置
- 磁盘:使用SSD!HDD在ES的大量随机IO面前会成为巨大瓶颈。建议使用本地SSD,如果使用云盘,选择高IOPS的SSD云盘。
- 网络:节点间通信频繁,确保内网带宽充足(千兆或万兆),并且延迟要低。
2.2 关键参数预计算与系统调优
Linux系统默认参数并不适合运行ES这类高IO、高内存占用的Java应用,必须在部署前调整。
1. 虚拟内存映射数 (vm.max_map_count)Elasticsearch 使用内存映射文件来高效访问索引,这个值需要调高。
# 临时生效 sudo sysctl -w vm.max_map_count=262144 # 永久生效,编辑 /etc/sysctl.conf,添加 vm.max_map_count=262144 # 然后执行 sudo sysctl -p2. 文件描述符与线程数ES会打开大量文件(每个分片、每个段都是文件),并发操作也会创建很多线程。
- 文件描述符:建议设置为65535或更高。
- 用户进程最大线程数:也需要适当调高。
可以通过修改/etc/security/limits.conf文件为运行ES的用户(例如我们即将创建的elasticsearch用户)增加限制:
elasticsearch soft nofile 65535 elasticsearch hard nofile 65536 elasticsearch soft nproc 4096 elasticsearch hard nproc 4096修改后需要重新登录该用户生效。
3. 禁用交换分区 (Swap)交换分区会导致磁盘IO,严重拖慢ES性能,甚至导致节点不稳定而被集群踢出。最彻底的方法是直接禁用。
# 临时禁用 sudo swapoff -a # 永久禁用,注释掉 /etc/fstab 中所有包含 swap 的行如果由于某些原因不能禁用,可以退而求其次,在ES配置中设置bootstrap.memory_lock: true,并确保运行ES的用户有memlock权限。
4. JVM参数规划不要直接使用ES自带的jvm.options默认配置。关键是根据你的机器内存来调整堆大小。假设我们有一台16GB内存的服务器:
- 堆内存 (
Xms和Xmx):设置为8GB(即8192m),各占50%。必须设置成一样大,避免运行时调整堆大小带来的性能开销。 - 垃圾回收器:对于ES这种注重低延迟的应用,JDK 8及以上版本默认的G1GC是很好的选择,通常无需更改。但在某些大内存、高写入场景下,可以评估ZGC或Shenandoah。
规划好这些,我们相当于为集群搭建打好了地基。接下来,就是实际的安装和配置环节。
3. 步步为营:三节点Elasticsearch集群安装与配置实战
假设我们有三台CentOS 7服务器,IP地址分别为192.168.1.101,192.168.1.102,192.168.1.103。我们将以elasticsearch用户运行服务。
3.1 基础环境准备与用户创建
在三台服务器上分别执行以下操作:
# 1. 创建运行ES的用户和组(ES不能以root运行) sudo groupadd elasticsearch sudo useradd -g elasticsearch -m elasticsearch sudo passwd elasticsearch # 设置一个密码,或使用密钥认证 # 2. 安装必要的依赖,如Java # Elasticsearch 8.x 需要 JDK 17 或更高版本。这里以安装OpenJDK 17为例。 sudo yum install -y java-17-openjdk-devel # 验证Java版本 java -version # 3. 下载并解压Elasticsearch # 前往 https://www.elastic.co/cn/downloads/elasticsearch 获取最新稳定版的Linux tar包链接 cd /opt sudo wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.13.0-linux-x86_64.tar.gz sudo tar -zxvf elasticsearch-8.13.0-linux-x86_64.tar.gz sudo mv elasticsearch-8.13.0 elasticsearch sudo chown -R elasticsearch:elasticsearch /opt/elasticsearch3.2 核心配置文件elasticsearch.yml详解与差异化配置
这是集群配置的核心。三台机器的配置大部分相同,但有几个关键项必须不同。
首先,编辑每台机器的/opt/elasticsearch/config/elasticsearch.yml文件。
通用配置部分(所有节点相同):
# 集群名称,所有节点必须一致,这是它们找到彼此的唯一标识 cluster.name: my-production-cluster # 节点名称,每个节点必须唯一,建议使用主机名或IP标识 node.name: node-101 # 在102和103机器上分别改为 node-102, node-103 # 数据存储路径和日志路径 path.data: /opt/elasticsearch/data # 确保该目录存在且elasticsearch用户有写权限 path.logs: /opt/elasticsearch/logs # 网络绑定地址,设置为0.0.0.0以监听所有网络接口,方便其他节点和客户端访问 network.host: 0.0.0.0 # 设置同时具备主节点和数据节点资格(这是我们规划的折中方案) node.roles: [ master, data ] # 显式声明角色 # 启动时进行一系列安全检查(生产环境建议开启,但初次启动可能因系统设置不符而失败,可暂时设为false以通过检查,但后续务必解决) bootstrap.memory_lock: true # 尝试锁定内存,禁用交换 discovery.type: single-node # **初次启动单节点时使用,集群配置时需要注释掉或删除** # 安全功能(Elasticsearch 8.x默认开启),初期搭建可先禁用以简化流程,后续再配置 xpack.security.enabled: false差异化配置部分(每个节点不同):这是让节点发现彼此并形成集群的关键。
# 在 192.168.1.101 (node-101) 上: # 主节点选举的初始列表,列出所有具备主节点资格的节点 cluster.initial_master_nodes: ["node-101", "node-102", "node-103"] # 本节点IP和传输端口(节点间通信) network.host: 192.168.1.101 http.port: 9200 # REST API端口 transport.port: 9300 # 节点间通信端口 # 种子主机列表,节点通过这个列表来发现集群中的其他节点 discovery.seed_hosts: ["192.168.1.101:9300", "192.168.1.102:9300", "192.168.1.103:9300"] # 在 192.168.1.102 (node-102) 上: cluster.initial_master_nodes: ["node-101", "node-102", "node-103"] network.host: 192.168.1.102 http.port: 9200 transport.port: 9300 discovery.seed_hosts: ["192.168.1.101:9300", "192.168.1.102:9300", "192.168.1.103:9300"] # 在 192.168.1.103 (node-103) 上: cluster.initial_master_nodes: ["node-101", "node-102", "node-103"] network.host: 192.168.1.103 http.port: 9200 transport.port: 9300 discovery.seed_hosts: ["192.168.1.101:9300", "192.168.1.102:9300", "192.168.1.103:9300"]重要提示:
cluster.initial_master_nodes参数仅在集群首次启动时生效。它指定了哪些节点有资格在第一次选举中成为主节点。一旦集群成功形成并选出了主节点,这个配置就不再被使用。后续重启集群时,节点会通过discovery.seed_hosts发现现有集群并加入。因此,这个配置必须一次性在所有初始主节点上正确设置,且后续不能随意更改节点名,否则可能导致集群无法恢复。
3.3 JVM堆内存配置
编辑/opt/elasticsearch/config/jvm.options。找到-Xms和-Xmx参数,根据之前规划进行修改:
-Xms8g -Xmx8g确保这两个值相等,并且不超过物理内存的50%。
3.4 启动集群与验证
按顺序启动节点:建议先启动规划中的第一个主节点(如node-101),等它完全启动并完成单节点集群的初始化后,再依次启动其他节点。这可以避免一些初始化竞争问题。
在每台服务器上,切换到elasticsearch用户并后台启动:
sudo su - elasticsearch cd /opt/elasticsearch ./bin/elasticsearch -d # -d 表示后台运行检查日志,确认没有错误:
tail -f logs/my-production-cluster.log看到类似published_address {192.168.1.101:9300}和master node changed ...等日志,表示节点启动成功并在尝试组建集群。
验证集群状态: 在任意节点,使用curl或浏览器访问其HTTP API:
curl -X GET "192.168.1.101:9200/_cluster/health?pretty"关键看返回的JSON中的几个字段:
status:green(所有主分片和副本分片都正常)、yellow(所有主分片正常,但部分副本分片未分配)、red(有主分片未分配)。number_of_nodes: 应该为3。active_primary_shards/active_shards: 活动的分片数。unassigned_shards: 未分配的分片数,应为0。
还可以查看节点信息:
curl -X GET "192.168.1.101:9200/_cat/nodes?v"这个命令会以表格形式列出集群中所有节点,包括IP、角色、负载等信息,非常直观。
如果_cluster/health状态不是green且number_of_nodes不是3,就需要根据日志排查问题,常见问题包括网络不通、防火墙阻止了9300端口、节点配置不一致(尤其是集群名、节点名)等。
4. 集群调优、监控与日常运维避坑指南
集群跑起来只是第一步,让它稳定、高效地运行才是真正的挑战。下面这些调优项和运维经验,很多都是我在实际生产环境中踩过坑才总结出来的。
4.1 必须调整的关键集群参数
默认配置很保守,不适合生产环境。我们需要在集群形成后,通过API动态更新一些设置(这些设置也可以写在elasticsearch.yml中,但动态更新更灵活)。
1. 分片分配感知与平衡默认情况下,ES不知道你的服务器在哪个机架、哪个可用区。如果三台服务器都在同一个物理机柜,一旦机柜断电,整个集群就挂了。因此,需要配置“感知”属性。
# 告诉ES每个节点属于哪个机架(rack)或可用区(zone) # 首先,在每个节点的 elasticsearch.yml 中添加节点属性: node.attr.rack_id: rack1 # 在101服务器上,假设属于rack1 # node.attr.rack_id: rack2 # 在102服务器上 # node.attr.rack_id: rack3 # 在103服务器上 # 然后,配置分片分配规则,强制同一个索引的主分片和副本分片不能分配在同一个rack上 PUT /_cluster/settings { "persistent": { "cluster.routing.allocation.awareness.attributes": "rack_id", "cluster.routing.allocation.awareness.force.rack_id.values": "rack1,rack2,rack3" } }这样配置后,ES会尽量将同一个分片的副本分布到不同的rack_id上,提高了容灾能力。在云环境,这个属性可以设置为zone。
2. 避免“脑裂”的最小主节点数脑裂是指集群中出现了两个或多个都认为自己是主节点的子集群,导致数据不一致。为了防止脑裂,需要设置discovery.zen.minimum_master_nodes(在7.x之后,该设置已被更优雅的cluster.initial_master_nodes和法定人数机制取代,但理解其原理很重要)。对于3个主节点资格的集群,法定人数是(3/2) + 1 = 2。这意味着至少需要2个主节点在线,集群才能正常运作。ES 7.x 之后版本内置了对此的优化,但确保你的主节点数量是奇数(3,5,7)是一个黄金法则,因为奇数个节点总能产生明确的多数派。
3. 索引分片数与副本数设置这是影响集群性能和恢复能力最重要的参数之一。在创建索引时指定:
PUT /my_index { "settings": { "number_of_shards": 3, # 主分片数,一旦设置不可更改(除非reindex) "number_of_replicas": 1 # 每个主分片的副本数,可以动态调整 } }- 主分片数:决定了索引数据的最大并行处理能力和数据分布。分片过多会增加管理开销和资源消耗;分片过少则无法利用多节点资源。一个常见的经验法则是:确保每个节点上的分片总数(包括副本)保持在较低水平。对于三节点集群,每个索引设置3个主分片是合理的,这样每个节点恰好承载一个主分片。
- 副本分片数:提供了数据冗余和高可用。
number_of_replicas: 1意味着每个主分片有一个副本,数据有两份拷贝。这允许一个节点故障而不丢失数据。副本还可以服务读请求,提升查询吞吐量。你可以根据数据重要性和查询负载动态调整它,例如在业务低峰期设置为0以节省资源,在高峰期或节点维护前调整为1或2。
4.2 监控与告警:如何知道你的集群“健康”与否?
不能等用户投诉了才发现集群有问题。必须建立监控体系。
1. 使用 Elasticsearch 自带 API
_cluster/health: 整体健康度。_cat/indices?v: 所有索引的状态、文档数、存储大小、分片状态。_cat/allocation?v: 查看分片在节点上的分配情况,是否有未分配的分片。_nodes/stats: 详细的节点统计信息,包括JVM堆内存使用、GC情况、线程池、文件系统、索引操作等。_cluster/stats: 集群级别的统计信息。
2. 集成专业监控系统
- Elastic Stack 自家的方案:使用Metricbeat采集ES的指标,发送到另一个Elasticsearch集群(监控集群)进行存储,然后用Kibana进行可视化。这是最原生、功能最全的方案。你可以看到丰富的仪表盘,包括索引速率、查询延迟、节点负载、磁盘使用率等。
- Prometheus + Grafana:这是云原生领域的事实标准。通过
elasticsearch-exporter将ES指标暴露给Prometheus,再用Grafana制作炫酷的仪表盘。社区有大量成熟的ES监控看板模板可以直接导入使用。 - 关键监控项:
- 集群状态:持续非
green状态告警。 - 节点离线:有节点从集群中消失。
- 未分配分片:持续存在未分配的分片。
- JVM堆内存使用率:长期高于75%或频繁发生GC。
- 磁盘使用率:超过80%需要预警,超过90%可能触发只读锁。
- 索引延迟:写入延迟显著增加。
- 搜索延迟:查询响应时间超过阈值。
- 集群状态:持续非
4.3 常见故障排查与修复实录
场景一:集群状态为yellow或red这是最常见的问题。首先检查_cat/shards,找到状态是UNASSIGNED的分片。
- 原因1:副本数设置过高,但没有足够节点容纳。比如你设置了
number_of_replicas: 2,但只有3个节点。对于3主分片的索引,它需要9个分片位置(3主 + 3*2副本),但3个节点最多提供9个位置,这要求分片完美均衡,有时ES的分配器无法满足。解决:临时降低副本数PUT /my_index/_settings {"number_of_replicas": 1},或者增加节点。 - 原因2:节点磁盘空间不足。ES有一个默认的水位线(85%),超过后新分片无法分配到该节点。解决:清理磁盘数据(删除旧索引、关闭不用的索引、扩容磁盘),或者临时调高水位线(不推荐)。
- 原因3:节点重启后,分片因数据损坏无法恢复。解决:这是一个危险操作,需要手动重新分配分片。首先尝试
POST /_cluster/reroute?retry_failed。如果不行,且确认主分片数据是好的,可以强制分配一个空副本分片,让其从主分片复制数据:POST /_cluster/reroute { "commands": [ { "allocate_empty_primary": { "index": "my_index", "shard": 0, "node": "node-102", "accept_data_loss": true } } ] }。注意:accept_data_loss意味着可能丢失该分片上的数据,务必谨慎!
场景二:写入或查询变慢
- 检查线程池:
GET /_cat/thread_pool?v。观察write或search队列是否堆积(queue字段)。如果队列长期不为0,说明节点处理不过来,需要优化查询、增加节点或升级硬件。 - 检查GC:
GET /_nodes/stats/jvm。如果old区GC频繁且耗时长,说明堆内存可能不足或存在内存泄漏,需要优化JVM配置或分析内存使用。 - 检查索引段合并:大量小段(segment)会影响查询性能。观察
_cat/indices中的segments.count和segments.memory。可以尝试在业务低峰期强制合并段POST /my_index/_forcemerge?max_num_segments=1,但这是一个IO密集型操作,会影响性能。
场景三:节点频繁脱离集群
- 检查网络:使用
ping、traceroute或telnet检查节点间9300端口是否通畅。 - 检查防火墙:确保9300和9200端口在节点间是开放的。
- 检查日志:查看脱离节点的日志,常见原因是GC时间过长,导致节点心跳超时(默认是30秒)。可以适当调高超时设置
discovery.zen.fd.ping_timeout,但根本解决方法是优化JVM和查询,减少GC停顿。
5. 从集群到生产:安全加固、备份与滚动升级
一个裸奔的、没有备份的集群,无异于在悬崖边跳舞。在生产环境,我们必须补上安全和数据可靠性这最后两块拼图。
5.1 启用安全特性(TLS与用户认证)
Elasticsearch 8.0 开始默认开启安全功能。如果你在配置中禁用了它(xpack.security.enabled: false),现在是时候打开了。安全配置包括传输层加密(节点间)和HTTP层加密(客户端到集群),以及用户角色认证。
1. 生成节点证书首先,在每个节点上,使用elasticsearch-certutil工具生成证书。最简单的方法是让一个节点生成证书,然后分发到其他节点。
# 在第一个节点(如node-101)上操作 cd /opt/elasticsearch ./bin/elasticsearch-certutil ca # 创建CA,生成 elastic-stack-ca.p12 文件 ./bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12 # 用CA签发节点证书,生成 elastic-certificates.p12将生成的elastic-certificates.p12文件复制到所有节点的/opt/elasticsearch/config/certs/目录下(需创建该目录)。
2. 配置安全设置修改所有节点的elasticsearch.yml:
xpack.security.enabled: true xpack.security.transport.ssl.enabled: true xpack.security.transport.ssl.verification_mode: certificate xpack.security.transport.ssl.keystore.path: certs/elastic-certificates.p12 xpack.security.transport.ssl.truststore.path: certs/elastic-certificates.p12 # 为HTTP层也启用SSL(可选但推荐) xpack.security.http.ssl.enabled: true xpack.security.http.ssl.keystore.path: certs/elastic-certificates.p12 xpack.security.http.ssl.truststore.path: certs/elastic-certificates.p123. 设置内置用户密码重启所有节点后,在其中一个节点上执行:
./bin/elasticsearch-setup-passwords auto这个命令会为elastic、kibana_system等内置用户生成随机密码并打印出来。务必保存好!之后访问集群API就需要使用用户名密码了:
curl -u elastic:your_password -X GET "https://192.168.1.101:9200/_cluster/health?pretty" -k # 注意协议变成了 https,且需要-k忽略证书验证(因为用的是自签名证书)5.2 制定可靠的备份与恢复策略
“没有备份,一切都是空谈”。ES提供了快照(Snapshot)和恢复(Restore)API,可以将整个集群或指定索引的状态备份到共享文件系统、S3、HDFS等仓库中。
1. 创建共享文件系统仓库(以NFS为例)假设我们在192.168.1.100上搭建了一个NFS服务器,路径为/data/es_backup,并挂载到了所有ES节点的/mnt/es_backup。 首先,在所有ES节点上配置仓库路径权限,确保elasticsearch用户可读写。 然后,通过API注册这个仓库:
PUT /_snapshot/my_backup_repository { "type": "fs", "settings": { "location": "/mnt/es_backup", "compress": true } }2. 创建快照可以创建整个集群的快照,也可以只备份特定的索引。
# 创建一次性快照 PUT /_snapshot/my_backup_repository/snapshot_20240527?wait_for_completion=true # wait_for_completion=true 会阻塞直到快照完成,对于大集群可能耗时很长,可以设为false,然后通过API查询状态。 # 创建仅包含特定索引的快照 PUT /_snapshot/my_backup_repository/snapshot_myindex_20240527 { "indices": "my_index,another_index", "ignore_unavailable": true, "include_global_state": false # 通常不备份集群全局状态,只备份索引数据 }3. 制定备份计划使用Cron定时任务调用ES的API进行定期备份。例如,每天凌晨2点进行一次增量快照(快照是增量的,节省空间)。 更复杂的策略可以是:保留最近7天的每日快照、最近4周的每周快照、以及最近3个月的每月快照。这需要自己写脚本管理快照的创建和删除。
4. 从快照恢复当需要恢复数据时(如误删除、数据损坏):
# 查看仓库中的快照列表 GET /_snapshot/my_backup_repository/_all # 恢复一个快照(默认恢复所有索引) POST /_snapshot/my_backup_repository/snapshot_20240527/_restore # 可以指定恢复哪些索引,以及重命名索引(常用于数据克隆) POST /_snapshot/my_backup_repository/snapshot_20240527/_restore { "indices": "my_index", "rename_pattern": "my_index", "rename_replacement": "restored_my_index" }5.3 进行平滑的滚动升级
业务不能停,但ES版本需要升级。滚动升级允许你一次升级一个节点,而不中断服务。
前提条件:确保你要升级到的版本支持从当前版本滚动升级。请查阅官方文档的升级路径说明。
步骤:
- 禁用分片分配:防止在节点重启期间,ES将其上的分片自动迁移到其他节点,造成不必要的网络和磁盘IO。
PUT /_cluster/settings { "persistent": { "cluster.routing.allocation.enable": "none" } } - 停止单个节点上的ES服务。
- 升级该节点:备份配置和数据目录,安装新版本的ES软件,将旧的
config、data、logs目录(或其中的配置文件)复制/移动到新版本目录下。注意:data目录通常可以直接复用,但务必先备份! - 启动升级后的节点,并等待它加入集群。可以通过
_cat/nodes查看节点版本和状态。 - 重新启用分片分配:
PUT /_cluster/settings { "persistent": { "cluster.routing.allocation.enable": "all" } } - 等待集群状态恢复
green。这可能需要一些时间,因为ES会进行分片恢复和数据同步。 - 对集群中的下一个节点,重复步骤1-6。
在整个过程中,集群始终可以提供服务,只是某个节点离线时,其上的副本分片会提升为主分片继续工作。务必在测试环境充分演练整个流程后再在生产环境操作。
走到这一步,你的Elasticsearch集群已经从一个简单的数据存储,变成了一个具备高可用、可监控、有安全、能备份、可平滑升级的生产级基础设施。这其中的每一步配置和每一个决策,都源于对线上流量、数据可靠性以及运维成本的综合考量。记住,没有一劳永逸的配置,随着业务增长和数据模式的变化,持续观察、测量和调整,才是让集群保持最佳状态的唯一法门。