CentOS 7.9部署Elasticsearch 7.x集群:从环境配置到运维监控全指南

📅 2026/6/16 14:28:53
CentOS 7.9部署Elasticsearch 7.x集群:从环境配置到运维监控全指南
1. 项目概述为什么要在CentOS上部署ES集群最近在梳理公司内部的日志与搜索平台发现单节点的Elasticsearch后面简称ES在数据量上来后性能瓶颈和单点故障问题越来越突出。于是把ES升级为集群部署就成了一个必须完成的技术基建任务。选择CentOS作为部署系统一方面是考虑到其作为企业级Linux发行版的长期稳定性和广泛的社区支持另一方面也是因为现有服务器环境大多基于CentOS 7.x环境统一能减少很多运维上的麻烦。一个ES集群简单说就是把多台服务器上的ES实例组织起来让它们像一个整体一样工作。这样做的好处显而易见数据被分片Shard存储在不同节点上提升了并发处理能力和存储容量副本Replica机制保证了即使某个节点宕机数据也不会丢失服务也不会中断。对于任何对搜索性能、数据可靠性有要求的生产环境集群化都是必经之路。这篇文章我就结合最近一次在CentOS 7.9上部署ES 7.x集群的实际操作把从环境准备、配置调优到安全加固、问题排查的全过程拆解清楚。无论你是运维工程师还是后端开发者只要你想在Linux环境下搭建一个稳定可用的ES集群这篇近万字的实操记录应该能给你提供一份可靠的“抄作业”模板。2. 集群架构设计与核心概念解析在动手敲命令之前我们必须先搞清楚要搭建一个什么样的集群。盲目配置只会导致后期各种诡异问题。2.1 节点角色与规划ES节点有不同的角色合理的角色规划是集群稳定高效的基石。通常我们主要关注以下三种角色主节点Master-eligible Node负责管理集群状态如索引的创建删除、节点的增删、分片的分配等。它不处理用户的数据请求因此负载较轻。生产环境中必须设置至少3个专用的主节点并且数量最好是奇数如3、5以防止“脑裂”Split-brain问题。脑裂是指集群中出现了两个或多个都认为自己是唯一主节点的小集群导致数据不一致。数据节点Data Node负责存储数据、执行数据相关的操作如增删改查、搜索、聚合。这是消耗CPU、内存和IO资源的大户。我们需要根据数据量和吞吐量来规划数据节点的数量。协调节点Coordinating Node接收客户端请求将请求转发到相关的数据节点并对各个数据节点的返回结果进行汇总、排序等处理最终返回给客户端。任何节点默认都具备协调节点的功能。但在大规模集群中设置独立的专用协调节点是个好习惯可以避免用户请求占用数据节点或主节点的资源。对于这次部署我们规划了一个5节点的集群node-master-01,node-master-02,node-master-03: 3个专用主节点。配置可以稍低如2核4G但需要稳定的网络和存储。node-data-01,node-data-02: 2个数据节点。配置较高8核16G以上配备SSD磁盘以获得更好的IO性能。所有节点都默认承担协调节点的角色。初期数据量不大两个数据节点足够后续扩容只需水平增加新的数据节点即可。2.2 分片与副本策略这是影响集群性能和可靠性的核心配置。分片Shard一个索引Index可以分成多个分片分散到不同的数据节点上。这实现了数据的分布式存储和并行处理。主分片Primary Shard的数量在索引创建时指定后续无法更改除非重建索引。因此在创建索引时需要根据数据总量和增长预期来谨慎设置。一个常见的经验法则是确保单个主分片的大小在20GB到50GB之间最大不建议超过100GB。副本Replica每个主分片可以有零个或多个副本分片。副本是主分片的完整拷贝提供了数据高可用性。一旦主分片所在节点故障其副本分片会提升为主分片。同时副本分片也可以处理搜索请求提升查询吞吐量。例如我们为一个日志索引设置number_of_shards: 55个主分片和number_of_replicas: 1每个主分片有1个副本。那么这个索引总共会有5 (5 * 1) 10个分片。这10个分片会尽可能均匀地分布在我们的两个数据节点上。即使其中一个数据节点完全宕机由于每个主分片都有副本在另一个节点上数据依然完整集群仍可正常工作。3. CentOS系统基础环境准备ES运行对系统环境有一定要求尤其是在生产环境以下几项必须提前配置好。3.1 系统参数优化ES进程需要较多的内存映射区域和文件描述符。直接使用root用户启动ES存在安全风险我们需要创建一个专用用户并调整系统限制。创建ES运行用户groupadd elasticsearch useradd -g elasticsearch elasticsearch # 设置密码可选用于sudo或远程登录 echo “your_strong_password” | passwd --stdin elasticsearch修改系统限制配置文件/etc/security/limits.conf在文件末尾添加elasticsearch soft nofile 65536 elasticsearch hard nofile 65536 elasticsearch soft nproc 4096 elasticsearch hard nproc 4096 elasticsearch soft memlock unlimited elasticsearch hard memlock unlimitednofile: 最大打开文件数。ES需要同时处理很多连接和数据文件。nproc: 最大进程数。memlock: 锁定内存防止ES使用的内存被交换Swap到磁盘上否则会严重拖慢性能。unlimited表示不限制。修改系统内核参数/etc/sysctl.conf添加或确认以下参数vm.max_map_count262144 vm.swappiness1 net.ipv4.tcp_retries25vm.max_map_count: 定义了一个进程能拥有的最大内存映射区域数量。ES使用内存映射文件来高效访问索引这个值需要调大。vm.swappiness: 控制系统使用Swap的倾向。设为1最小倾向仅在内存不足时使用Swap有助于提升性能。使配置生效# 重新加载limits.conf对新建会话生效 # 对于已登录的会话可能需要重新登录elasticsearch用户 sysctl -p # 使sysctl.conf的修改立即生效3.2 安装Java环境ES是基于Java开发的必须安装合适的JDK。ES 7.x推荐使用JDK 11或更高版本。这里我们选择安装OpenJDK 11。# 查看可用的JDK包 yum search openjdk # 安装OpenJDK 11包括JRE yum install -y java-11-openjdk java-11-openjdk-devel # 验证安装 java -version注意强烈建议使用与ES版本官方兼容的JDK。从ES 7.0开始安装包已自带捆绑的JDK在jdk目录下如果你使用官方tar.gz包安装并且希望使用自带的JDK可以在elasticsearch启动脚本中通过JAVA_HOME环境变量指定路径这样可以避免因系统全局JDK版本不同带来的兼容性问题。3.3 防火墙与SELinux配置为了让集群节点间以及客户端与节点间能正常通信需要开放相关端口。同时SELinux可能会阻止ES进程的一些操作。防火墙Firewalld配置假设我们使用默认的端口9300节点间通信9200HTTP REST API。# 开放端口 firewall-cmd --permanent --add-port9200/tcp firewall-cmd --permanent --add-port9300/tcp # 如果使用kibana还需开放5601 # firewall-cmd --permanent --add-port5601/tcp # 重新加载防火墙规则 firewall-cmd --reload # 查看已开放端口 firewall-cmd --list-portsSELinux配置对于生产环境建议在充分测试后可以临时设置为宽容模式或禁用。但更安全的方式是配置SELinux策略。# 临时设置为宽容模式重启后失效 setenforce 0 # 永久禁用需修改配置文件并重启 sed -i ‘s/^SELINUXenforcing/SELINUXdisabled/’ /etc/selinux/config实操心得在测试环境为了方便可以先禁用SELinux。但在严格的安全合规生产环境中建议先设置为permissive模式然后根据ES日志中的AVC拒绝信息使用audit2allow工具生成并安装自定义策略模块这才是长治久安之道。4. Elasticsearch集群部署与配置详解基础环境搞定后就可以开始安装和配置ES本身了。4.1 软件包获取与安装从Elastic官网下载对应版本的tar.gz包是最直接的方式。也可以配置yum源进行安装这里我们使用tar.gz包便于自定义安装路径。# 切换到root用户或使用sudo # 进入安装目录例如/opt cd /opt # 下载ES安装包以7.17.12为例请替换为最新稳定版 wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.12-linux-x86_64.tar.gz # 解压 tar -zxvf elasticsearch-7.17.12-linux-x86_64.tar.gz # 重命名目录可选 mv elasticsearch-7.17.12 elasticsearch-cluster # 将目录所有者改为elasticsearch用户 chown -R elasticsearch:elasticsearch /opt/elasticsearch-cluster4.2 核心配置文件解析与定制ES的配置文件位于安装目录下的config文件夹中核心是elasticsearch.yml和jvm.options。1. JVM堆内存配置 (config/jvm.options):这是最关键的性能调优点之一。ES默认的堆内存是1GB对于生产环境远远不够。原则将最小堆内存 (Xms) 和最大堆内存 (Xmx) 设置为相同的值避免堆内存扩容收缩带来的性能开销。堆内存大小不应超过物理内存的50%并且绝对不要超过32GB超过32GB会使得JVM启用压缩对象指针失效反而浪费内存。剩余内存留给操作系统缓存索引文件Lucene使用。建议对于一台16G内存的数据节点可以设置-Xms8g -Xmx8g。修改jvm.options:-Xms8g -Xmx8g注意事项jvm.options文件中可能有两处配置一处是## JVM configuration注释块下的默认配置另一处是## GC configuration等后面的配置。建议直接在文件开头附近找到-Xms和-Xmx行进行修改确保生效。2. 集群主配置文件 (config/elasticsearch.yml):这个文件定义了集群和节点的核心身份。以下配置需要在每个节点上根据其角色进行修改。# ------------------------ 集群全局配置 ------------------------ # 集群名称所有节点必须相同 cluster.name: my-production-cluster # ------------------------ 节点身份配置 ------------------------ # 节点名称每个节点必须唯一建议使用有意义的名称如角色-序号-主机名 node.name: node-master-01 # 节点角色配置 node.roles: [ master ] # 主节点配置 # node.roles: [ data ] # 数据节点配置 # node.roles: [ master, data ] # 同时充当主节点和数据节点不推荐用于生产 # 如果不显式指定节点默认具有 master, data, ingest 角色。 # ------------------------ 网络与发现配置 ------------------------ # 绑定地址设置为0.0.0.0以监听所有网络接口或指定具体IP network.host: 0.0.0.0 # HTTP API端口客户端访问 http.port: 9200 # 节点间通信端口 transport.port: 9300 # 初始主节点列表这是集群组建的关键 # 新节点通过联系这个列表中的节点来加入集群。 # 列出所有具备master角色的节点至少3个 discovery.seed_hosts: [“node-master-01:9300”, “node-master-02:9300”, “node-master-03:9300”] # 在首次启动集群时需要配置一个初始的主节点候选列表。 # 这个列表来自 discovery.seed_hosts用于进行第一次主节点选举。 cluster.initial_master_nodes: [“node-master-01”, “node-master-02”, “node-master-03”] # ------------------------ 其他重要配置 ------------------------ # 数据存储路径可以配置多个路径用逗号分隔ES会在它们之间均衡数据 path.data: /data/elasticsearch/data # 日志存储路径 path.logs: /var/log/elasticsearch # 启动时进行安全检查生产环境应为true bootstrap.system_call_filter: true # 确保至少N个节点启动后才开始分配分片防止数据在单个节点上形成“脑裂”假象 gateway.recover_after_nodes: 3 # 设置节点离开集群后等待多久才开始重新分配其上的分片对于临时重启可以调大以避免不必要的分片移动 # 默认是1m (1分钟) # indices.recovery.retry_delay_state_sync: 10s踩坑记录cluster.initial_master_nodes仅在集群第一次启动时需要使用。一旦集群成功组建并选出了主节点这个配置就应该从elasticsearch.yml文件中注释掉或删除。否则在后续重启整个集群时如果严格按照这个列表顺序启动可能会导致问题。很多人在集群重启故障时栽在这里。4.3 数据与日志目录规划生产环境的数据和日志不应放在安装目录或系统盘下。# 创建数据和日志目录例如在独立的大容量磁盘上 mkdir -p /data/elasticsearch/{data,logs} # 修改所有者 chown -R elasticsearch:elasticsearch /data/elasticsearch然后在elasticsearch.yml中配置path.data和path.logs指向这些目录。4.4 启动服务与加入集群首次启动顺序至关重要首先启动cluster.initial_master_nodes列表中所有的主节点。最好逐个启动间隔十几秒观察日志。待所有主节点启动完毕并成功选举出活跃主节点后再启动数据节点。最后启动协调节点如果有。使用systemd管理服务推荐创建服务文件/etc/systemd/system/elasticsearch.service[Unit] DescriptionElasticsearch Documentationhttps://www.elastic.co Wantsnetwork-online.target Afternetwork-online.target [Service] Typenotify RuntimeDirectoryelasticsearch PrivateTmptrue EnvironmentES_HOME/opt/elasticsearch-cluster EnvironmentES_PATH_CONF/opt/elasticsearch-cluster/config EnvironmentPID_DIR/var/run/elasticsearch EnvironmentES_SD_NOTIFYtrue EnvironmentJAVA_HOME/opt/elasticsearch-cluster/jdk # 如果使用自带JDK WorkingDirectory/opt/elasticsearch-cluster Userelasticsearch Groupelasticsearch ExecStart/opt/elasticsearch-cluster/bin/elasticsearch -p ${PID_DIR}/elasticsearch.pid --quiet # StandardOutput is configured to redirect to journalctl since # some error messages may be logged in standard output before # elasticsearch logging system is initialized. Elasticsearch # stores its logs in /var/log/elasticsearch and does not use # journalctl by default. If you also want to enable journalctl # logging, you can simply remove the “quiet” option from ExecStart. StandardOutputjournal StandardErrorinherit # Specifies the maximum file descriptor number that can be opened by this process LimitNOFILE65536 # Specifies the maximum number of processes LimitNPROC4096 # Specifies the maximum size of virtual memory LimitASinfinity # Specifies the maximum file size LimitFSIZEinfinity # Disable timeout logic and wait until process is stopped TimeoutStopSec0 # SIGTERM signal is used to stop the Java process KillSignalSIGTERM # Send the signal only to the JVM rather than its control group KillModeprocess # Java process is never killed SendSIGKILLno # When a JVM receives a SIGTERM signal it exits with code 143 SuccessExitStatus143 [Install] WantedBymulti-user.target启用并启动服务systemctl daemon-reload systemctl enable elasticsearch systemctl start elasticsearch # 查看状态和日志 systemctl status elasticsearch journalctl -u elasticsearch -f验证集群状态在所有节点启动后通过任意节点的HTTP API检查集群健康状态curl -X GET “localhost:9200/_cluster/health?pretty”关键指标看status:green: 所有主分片和副本分片都已分配。健康。yellow: 所有主分片已分配但部分副本分片未分配。数据完整但高可用性有风险。red: 有主分片未分配。数据可能已丢失。同时可以查看节点列表curl -X GET “localhost:9200/_cat/nodes?v”5. 集群运维、监控与问题排查实录集群跑起来只是第一步日常的监控和问题处理才是重头戏。5.1 基础监控与API使用ES提供了丰富的API用于监控。查看集群详细状态GET /_cluster/state?pretty和GET /_cluster/stats?pretty查看索引状态GET /_cat/indices?v查看所有索引的分片、文档数、存储大小。查看节点状态GET /_cat/nodes?vhname,role,heap.percent,ram.percent,cpu,load_1m,disk.used_percent可以定制化输出关键指标。查看热点线程GET /_nodes/hot_threads当集群响应变慢时用于分析哪些线程占用了大量CPU。查看分片分配情况GET /_cat/shards?v查看每个分片的状态STARTED, UNASSIGNED, RELOCATING等、位于哪个节点。5.2 常见问题与解决方案速查表以下是我在运维中遇到的一些典型问题及解决方法。问题现象可能原因排查命令与解决方案节点无法加入集群日志显示master_not_discovered_exception1. 网络不通防火墙/安全组未开放9300端口。2.discovery.seed_hosts配置错误主机名或IP无法解析。3. 首次启动时cluster.initial_master_nodes未配置或配置错误。4. 集群名称 (cluster.name) 不一致。1. 使用telnet或nc命令测试节点间9300端口连通性。2. 检查/etc/hosts或DNS确保主机名可解析。建议在配置中直接使用IP地址。3. 确认首次启动流程检查主节点配置文件。4. 核对所有节点的elasticsearch.yml中的cluster.name。集群状态为red或yellow1. 有节点离线导致其上的主分片或副本分片丢失。2. 磁盘空间不足导致分片无法分配。3. 分片分配设置问题如副本数设置过高没有足够节点容纳。1.GET /_cat/shards?v查看UNASSIGNED状态的分片。2.GET /_cat/allocation?v查看磁盘使用情况。3. 清理磁盘或增加节点。对于副本问题可以临时降低副本数PUT /my_index/_settings {“number_of_replicas”: 0}待节点恢复后再改回。节点频繁脱离又加入集群1. 网络不稳定丢包率高。2. GC垃圾回收停顿时间过长导致节点心跳超时。3. 节点负载过高CPU、IO、内存响应迟钝。1. 使用ping和mtr检查网络质量。2. 查看GC日志 (jvm.options中配置-Xlog:gc*)优化JVM堆大小和GC策略如考虑使用G1GC。3. 监控节点资源使用率考虑扩容或优化查询/索引压力。索引或搜索性能缓慢1. 分片过大或过小。2. 查询语句未优化如深度分页、通配符查询开头、未使用过滤器缓存。3. 硬件瓶颈磁盘IO慢、内存不足。4. 段合并Merge操作占用大量IO。1. 使用_cat/indices查看分片大小。过大考虑拆分索引Reindex过小考虑合并Shrink。2. 使用Profile API(GET /my_index/_search?prettyprofiletrue) 分析查询耗时。3. 监控iostat,vmstat。为数据节点配置SSD。4. 调整合并策略 (index.merge.*)或安排在业务低峰期强制合并 (_forcemerge)。启动时报错max file descriptors [4096] for elasticsearch process is too low系统对elasticsearch用户的文件描述符限制未生效。1. 确认已修改/etc/security/limits.conf并重启会话或服务器。2. 检查是否被/etc/security/limits.d/下的其他文件覆盖。3. 对于systemd服务必须在服务文件[Service]段中显式设置LimitNOFILE因为systemd会忽略全局的limits.conf设置。5.3 性能调优与安全加固建议性能调优索引层面根据数据特性合理设置Mapping选择合适的分析器Analyzer。对于不需要分词的字段使用keyword类型对于数值范围查询频繁的字段使用integer或date类型。查询层面尽量使用过滤器Filter代替查询Query因为过滤器结果可以被缓存。避免使用script查询除非必要。写入优化使用批量BulkAPI进行写入并调整批量大小如5-15MB。增加索引的刷新间隔 (index.refresh_interval)默认1s对于日志类可调整为30s甚至更长减少段合并压力。安全加固启用安全特性X-PackES从7.x开始基础安全功能TLS加密、用户认证已免费包含。务必配置步骤包括生成证书、配置elasticsearch.yml中的xpack.security.*相关项并为内置用户如elastic设置密码。网络隔离将ES集群部署在内网仅向协调节点或负载均衡器暴露9200端口。节点间通信端口9300严格限制在内网访问。定期备份使用快照SnapshotAPI将索引备份到共享文件系统、S3或HDFS等仓库中。这是数据安全的最后一道防线。6. 集群扩容与版本升级策略业务在增长集群也需要随之成长。水平扩容增加节点这是最常见的扩容方式尤其适用于数据节点。准备新服务器完成上述所有系统环境准备步骤。安装相同版本的ES软件。修改其elasticsearch.ymlcluster.name必须相同discovery.seed_hosts指向现有集群的若干节点主节点或数据节点均可不要设置cluster.initial_master_nodes。启动新节点。观察集群日志和_cat/nodes新节点会自动加入集群。ES会自动将现有索引的部分分片迁移到新节点上以达到数据均衡。可以通过PUT /_cluster/settings调整分片分配策略和平衡阈值。垂直扩容升级节点配置通常指增加现有节点的CPU、内存、磁盘。对于数据节点增加内存后需要同步调整jvm.options中的堆内存设置并重启节点。重启单个节点流程 a. 临时禁用分片分配PUT /_cluster/settings { “persistent”: { “cluster.routing.allocation.enable”: “none” } }。 b. 停止待重启节点上的ES服务。 c. 升级硬件/修改配置。 d. 启动该节点的ES服务。 e. 等待该节点完全加入集群并恢复状态查看_cat/health。 f. 重新启用分片分配PUT /_cluster/settings { “persistent”: { “cluster.routing.allocation.enable”: “all” } }。 g. 集群会开始重新平衡分片。依次对其他节点进行此操作。版本升级ES支持滚动升级相邻主要版本内如7.17.x到7.18.y。大版本升级如6.x到7.x需要完全重启集群。仔细阅读官方升级文档检查废弃的API和Breaking Changes。备份备份备份使用快照功能对全集群数据进行备份。滚动升级步骤禁用分片分配 - 升级并重启一个非主节点 - 等待该节点恢复 - 重复直到所有非主节点升级完毕 - 最后逐个升级主节点可能需要手动切换主节点角色。升级后务必进行全面功能测试。整个部署和运维过程最深的体会就是“细节决定成败”。一个参数配置不当、一个启动顺序错误都可能让集群陷入异常状态。尤其是在生产环境任何操作前做好备份和预案变更时遵循“灰度”、“可观测”、“可回滚”的原则才能让这个强大的搜索和分析引擎真正稳定、高效地为我们服务。最后分享一个小技巧善用_catAPI它返回的是纯文本表格格式结合grep、awk等命令行工具可以非常方便地编写监控脚本比看JSON格式的响应直观多了。