1. 整体设计思路与集群规划
1.1 为什么是3主2从,而不是其他组合
先说结论:3主2从这个组合,是在数据可靠性和硬件成本之间相当务实的一个平衡点。我见过不少团队第一次搭ELK,上来就无脑三主三从,实际上中小规模日志量根本用不到那么重的配置,运维成本还直线上升。反过来,也有图省事搞“单节点闯天下”的,一段时间后数据一多,节点一挂,整个日志系统直接瘫痪,排查问题连历史日志都翻不出来,非常被动。
选3个主节点,首先是为了解决“脑裂”问题。Elasticsearch的选主机制依赖“多数派”原则,3个主节点意味着集群可以容忍任意1个主节点宕机而依旧保持可用。如果只有2个主节点,其中一个挂了,剩下的那个凑不出多数派,集群会进入只读状态甚至完全不可用。这是硬性要求,不是靠配置绕得过去的。再加上默认的minimum_master_nodes设置为2,3主配置就是标准姿势。
2个从节点则承担实际的数据存储和查询负载。为什么不是1个从节点?因为数据副本(replica)至少得有1份才谈得上高可用,而副本是跨节点分布的,2个数据节点意味着每个分片的主副本和从副本可以落在不同节点上,任何一个数据节点挂掉,另一个还能顶上继续服务。1个从节点也不是不行,但副本只能和主分片挤在同一台机器上,一旦那台机器宕机,数据就真丢了,等于高可用形同虚设。
我这里把“主节点”和“从节点”的逻辑再明确一下:在Elasticsearch里,“主节点”负责集群状态管理、索引创建删除、分片分配这些元数据操作,并不是说主节点的机器就一定要存数据;“从节点”则主要负责数据存储和检索。实际部署时,主节点机器通常配置为不存储数据(node.data: false),专职做管理,避免因数据读写压力影响集群稳定性。7.17.9版本里这类节点通常叫“Master-eligible node”和“Data node”,配置上主要靠node.roles区分。
1.2 版本选型:锁定7.17.9的考量
Elasticsearch 7.17.9是7.x系列的最后一个维护版本,这一点非常关键。很多团队至今仍大量使用7.x生态,插件、监控、上下游对接都基于7.x验证过。8.x版本虽然功能更新,但引入了不少破坏性变更,比如默认开启安全认证、REST API结构调整、客户端兼容性变化,迁移成本并不低。7.17.9作为7.x的“收尾版本”,修复了大量已知Bug和CVE漏洞,稳定性在7.x里属于比较能打的。
另外,Kibana必须和Elasticsearch保持主版本一致,这是官方强制要求。7.17.9配7.17.9,是合规且稳妥的组合。后期如果升级,两个组件也应当是同步升级,避免出现版本不一致导致的兼容性问题。Logstash、Filebeat等周边组件同理,尽量用7.17.x配套版本,减少不必要的兼容性排查。
1.3 硬件配置与网络规划参考
3主2从共5台机器,主从的硬件配置策略我个人建议是:主节点不需要太高的存储配置,重点保证CPU和内存稳定,因为集群管理操作和选主过程对响应时间敏感;从节点则要大内存、大磁盘,数据读写和聚合查询主要消耗在这里。
| 角色 | CPU | 内存 | 磁盘 | 系统 |
|---|---|---|---|---|
| 主节点(3台) | 4核 | 8G | 100G系统盘 | CentOS 7.x / Ubuntu 20.04 |
| 从节点(2台) | 8核 | 16G | 1T数据盘 | CentOS 7.x / Ubuntu 20.04 |
如果日志量特别大,从节点的磁盘建议直接上SSD,机械盘在大量聚合查询时会明显拖慢响应。内存方面,Elasticsearch有一个重要规则:给JVM堆内存的配置不要超过系统内存的一半,且单节点堆内存上限建议32G,留出的系统内存给Lucene做文件缓存,实际查询性能很大程度依赖这个Lucene缓存。
网络方面,5台机器建议处于同一内网或同一可用区,节点间通信延迟控制在毫秒级。跨地域组集群不是不可以,但对网络稳定性要求非常高,一旦网络抖动频繁,主节点之间的选主交互和数据节点的副本同步都会受影响,轻则产生告警,重则触发集群脑裂。生产环境我一般建议节点间内网带宽至少千兆。
2. 部署前的系统配置与基础环境准备
2.1 操作系统基础调优
Elasticsearch对系统的要求不算苛刻,但有几项基础配置不对,后面运行会非常折腾。我把实践中踩过坑的地方集中列一下,这些是在安装Elasticsearch之前就要处理好的。
文件句柄数限制。Elasticsearch会同时打开大量文件,特别是数据节点,索引分片越多,文件句柄占用越大。默认的1024肯定不够,我一般直接改到65535。修改方式是编辑/etc/security/limits.conf,加上:
es_user soft nofile 65535 es_user hard nofile 65535注意这里的es_user要替换成你实际创建的用户,后面会详细说用户创建的事。生效需要重新登录或者重启终端。
虚拟内存参数。Elasticsearch的Lucene底层用了大量mmap映射文件,默认的虚拟内存映射数量上限通常不够用,运行时会报“max virtual memory areas vm.max_map_count [65530] is too low”的错误。执行:
sysctl -w vm.max_map_count=262144同时写入/etc/sysctl.conf让它永久生效。这个参数我在第一次部署时忽略过,结果启动集群后数据节点日志疯狂报错,排查了很久才发现是这个问题。
关闭交换分区(swap)。Elasticsearch官方建议关闭swap,或者至少将swap使用降到最低,因为内存交换会导致JVM性能急剧下降。稳妥操作:
swapoff -a如果是云服务器,还要注意实例本身的swap配置。这一步做完,再配合/etc/fstab注释掉交换分区条目,避免重启后swap自动恢复。
2.2 专用用户与目录规划
Elasticsearch明确禁止使用root用户运行,这是官方硬性要求,因为root启动会直接报错退出。我的做法是创建一个专用用户,并且把数据、日志、配置目录的属主都切到该用户下:
useradd -m es_user mkdir -p /opt/elasticsearch/{data,logs} mkdir -p /opt/elasticsearch/config chown -R es_user:es_user /opt/elasticsearch目录规划上有个经验:数据和日志尽量分盘存放。如果只有一块数据盘,至少也要分目录。数据盘如果被日志写满,Elasticsearch会自动将索引设置为只读,这是保护机制,但会导致业务日志写入失败,非常坑。我遇到过磁盘满了之后,Filebeat还在持续生产数据,结果Elasticsearch拒绝写入,再去看时一大片索引都是read-only状态,处理起来很麻烦。所以日志目录和数据目录分开,甚至给系统盘也留够空间,是值得提前规划的事。
2.3 JDK版本确认
Elasticsearch 7.17.9自带OpenJDK,如果你不想折腾,直接用自带的就行。但不少团队机器上已经有自己的JDK环境,需要注意版本兼容。7.17.9要求Java 11或Java 17,我建议优先使用Java 11的长期支持版本。如果机器上默认JDK版本不对,可以用环境变量强制指定:
export JAVA_HOME=/opt/jdk-11 export PATH=$JAVA_HOME/bin:$PATH也可以在elasticsearch启动脚本对应的环境配置里指定,但生产环境我倾向于在启动ES之前先echo $JAVA_HOME确认一遍,避免启动后才发现用的JVM版本不对,日志里报UnsupportedJavaVersionError,非常浪费时间。
3. Elasticsearch 7.17.9集群配置详解
3.1 配置文件核心参数解读
Elasticsearch的配置集中在config/elasticsearch.yml,集群能否健康运行,大部分关键决策都在这个文件里。我直接给出一份经过生产验证的配置模板,然后逐个解释为什么这么设。
以主节点(node-1)为例:
cluster.name: es-prod-cluster node.name: node-1 node.roles: [ master ] network.host: 0.0.0.0 http.port: 9200 transport.port: 9300 discovery.seed_hosts: - node-1:9300 - node-2:9300 - node-3:9300 - node-4:9300 - node-5:9300 cluster.initial_master_nodes: - node-1 - node-2 - node-3 path.data: /opt/elasticsearch/data path.logs: /opt/elasticsearch/logs discovery.zen.minimum_master_nodes: 2对从节点(node-4)来说,主要是node.roles不同:
cluster.name: es-prod-cluster node.name: node-4 node.roles: [ data ] network.host: 0.0.0.0 http.port: 9200 transport.port: 9300 discovery.seed_hosts: - node-1:9300 - node-2:9300 - node-3:9300 - node-4:9300 - node-5:9300 path.data: /opt/elasticsearch/data path.logs: /opt/elasticsearch/logs关键参数逐个说:
cluster.name:同一个集群的所有节点必须同名。这个不解释,但经常有人搭好了发现节点之间互相发现不了,最后发现是某台机器上的cluster.name抄错了,排查了很久。
node.name:每个节点必须不同。建议用有规律的命名,node-1到node-5,方便日志定位。
node.roles:7.x之前是用node.master和node.data两个布尔值控制,7.x开始建议用node.roles数组。主节点只写master角色,从节点只写data角色。有一点要注意:如果node.roles配置为空或者不配置,默认这个节点可以担任所有角色,包括master和data,在5节点架构里这就违背了角色分离的初衷。
discovery.seed_hosts:这个参数是节点启动后用来发现集群中其他节点的地址列表。填的是transport端口(9300)而非http端口(9200),很多人第一次配置容易搞混。我建议把5台节点全部写进去,虽然主节点理论上只需要发现其他主节点,但写全了后续加节点不用再改配置,省事。
cluster.initial_master_nodes:这是集群首次启动时用于引导选主的节点列表,只在第一次集群启动时需要,后续重启会自动忽略。如果首次启动时漏配,集群会选不出主节点,一直处于yellow或red状态。这里建议填写所有主节点。
discovery.zen.minimum_master_nodes:防止脑裂的关键参数,值设置为“主节点数/2 + 1”,即3/2+1=2。有了这个配置,一个节点想成为主节点,需要至少拿到2个主eligible节点的投票才能完成选主,从机制上避免网络分区时出现两个主节点。这个参数在7.x里已经默认继承到discovery的配置里,但手动显式写上更稳妥。
3.2 JVM参数与内存分配
在config/jvm.options里,最核心的两个参数是堆内存的初始值和最大值:
-Xms8g -Xmx8g官方强烈建议Xms和Xmx设置为相同值,避免运行过程中JVM动态伸缩堆大小带来的性能损耗。上面提到过,堆内存不要超过物理内存的50%。以16G内存的数据节点为例,堆设8G,剩下8G留给Lucene。如果物理内存只有8G,堆设到4G以内比较合适,否则系统自身都会因为内存不足开始swap,性能反而下降。
另外,如果单个节点内存超过32G,建议不要继续往上调堆大小,而是通过增加节点数来扩展,因为JVM在堆超过32G时会默认启用压缩指针失效机制,对象头变大,GC效率反而降低,这是JVM层面的一个经典经验值。
3.3 集群启动顺序与验证
首次启动集群,顺序很重要。先把3个主节点全部启动,确认主节点之间互相发现并选出主节点之后,再启动数据节点。如果数据节点先启动,它们会因为找不到主节点而不断重试,虽然最终也能恢复,但日志里会多出一堆无意义的警告信息,干扰后续排查。
启动命令很简单:
su - es_user -c "/opt/elasticsearch/bin/elasticsearch -d"-d表示后台守护进程方式运行。启动后先看日志有没有报错:
tail -f /opt/elasticsearch/logs/es-prod-cluster.log然后确认集群状态:
curl -s http://127.0.0.1:9200/_cluster/health?pretty一个健康的集群,status字段应该是green。对3主2从的架构来说,green意味着所有索引的主分片和副本分片都分配到了可用节点上。如果出现yellow,说明有副本分片未分配,常见原因是数据节点数不够,无法满足副本分布要求;如果出现red,说明存在主分片未分配的情况,需要进一步排查故障节点或磁盘空间。
再看节点列表确认5个节点都注册成功:
curl -s http://127.0.0.1:9200/_cat/nodes?v展示结果里应该能看到5行节点信息,IP列为各自的地址,node.role列明确标识了m(master)和d(data)角色。如果这里缺了某个节点,优先检查该节点日志,常见原因是network.host配置不一致或transport端口被占用。
4. Kibana 7.17.9部署与接入集群
4.1 安装步骤与基础配置
Kibana的安装包下载方式和Elasticsearch一致,解压后主要关心config/kibana.yml。它本身不存储数据,只是一个展示和查询界面,所以部署在任意一台能访问集群的机器上都可以。我的习惯是部署在一台主节点机器上,或者独立一台机器,看团队机器资源情况。
一份可用的kibana.yml配置:
server.port: 5601 server.host: "0.0.0.0" elasticsearch.hosts: ["http://node-1:9200", "http://node-2:9200", "http://node-3:9200"] kibana.index: ".kibana" logging.dest: /opt/kibana/logs/kibana.logelasticsearch.hosts这里填所有主节点的HTTP地址,Kibana会自动做负载均衡,单点故障时自动切换,体验比只填一个地址好很多。
server.host如果只在本机访问可以填127.0.0.1,但如果是内网环境多人需要访问Kibana界面,就要监听内网IP或0.0.0.0,然后通过防火墙或安全组限制来源IP。
启动Kibana:
su - es_user -c "/opt/kibana/bin/kibana"生产环境建议用systemd管理进程,方便开机自启和崩溃自动拉起。systemd配置网上有很多模板,但有几个细节容易被忽略:User指定为es_user,ExecStart写Kibana的bin目录绝对路径,Restart=on-failure。
4.2 可视化与索引管理的必要设置
Kibana首次访问,界面会引导创建Index Pattern。这里要注意,Index Pattern的正则匹配是基于索引名称的,如果日志索引按天命名,比如logstash-2024.08.26,建议直接把pattern设为logstash-*,这样所有按天生成的索引都会自动被匹配到。
日常使用Kibana,有几个地方值得花时间设置:
索引生命周期管理(ILM)。如果日志数据量级可观,强烈建议在Elasticsearch侧配置ILM策略,比如保留30天自动删除旧索引,或者按容量触发滚动。这个不配的话,日志索引会无限增长,磁盘很快就满了。配置策略后在Kibana的Stack Management里给对应索引模板绑定策略即可。
Discover页面时区。Kibana默认时区是UTC,国内环境下会发现日志时间比本地时间晚8小时。在Kibana的Advanced Settings里把dateFormat:tz设为本地时区,或者直接在界面右上角切换,这个不算技术难题,但几乎每个团队第一次用时都会踩。
Dashboard权限。如果团队人多,建议在Kibana里创建不同Space或通过用户角色隔离视图,避免有人误删索引或修改系统配置。Kibana 7.17.9的告警、异常检测等功能也值得试,但正式使用前先小范围验证,不要直接全量启用。
5. 安全与防火墙策略落地
5.1 端口规划与防火墙最小化原则
ELK集群涉及多个端口,Elasticsearch的9200是HTTP接口,9300是节点间通信的Transport接口,Kibana的5601是Web访问端口。生产环境的防火墙策略,我的原则是“能不开就不开,能限制就限制”。
以Linux防火墙举例,先添加必要端口:
firewall-cmd --permanent --add-port=9200/tcp firewall-cmd --permanent --add-port=9300/tcp firewall-cmd --permanent --add-port=5601/tcp firewall-cmd --reload但这只是第一步。9200端口如果对所有来源开放,知道IP的人可以直接访问Elasticsearch的REST接口,删索引、改配置都很容易,非常危险。我的做法是在Firewalld里针对来源IP做白名单限制,只允许采集端(比如Filebeat所在服务器)访问9200,只允许运维网段访问5601:
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port protocol="tcp" port="9200" accept' firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.10.0.0/16" port protocol="tcp" port="5601" accept'9300端口主要给集群内部节点通信用,建议只在5台ES节点之间放通,不要暴露到外部。我见过有人把所有端口都裸奔在公网,然后数据被勒索的情况,虽然Elasticsearch默认没有认证机制,但配合防火墙和网络隔离完全可以规避大部分风险。
5.2 认证与加密的基本方案
7.17.9默认是关闭安全认证的。如果你的集群只在内网运行,且网络隔离做得足够好,短期用默认配置问题不大。但只要集群有可能被更多人访问,或者你不想因为日志泄露背锅,就建议在部署阶段就把安全功能打开。
Elasticsearch 7.17.9自带的安全功能包括TLS加密和用户名密码认证。开启的流程大致是:为每个节点生成证书,在elasticsearch.yml里配置xpack.security.enabled: true和xpack.security.transport.ssl相关配置,然后通过elasticsearch-setup-passwords命令为内置账号设置密码,最后在Kibana配置里指定elasticsearch账号密码。
这一步如果在集群搭建完成后再做,会牵扯到滚动重启和证书分发,比部署初期做麻烦好几倍。所以我的建议是:如果你有任何可能开启安全功能的计划,请在部署阶段就做好规划。即使暂时不启用,也要在架构和配置上留好扩展位,比如证书目录提前规划、账号体系提前设计。
5.3 系统安全与基线加固
除了防火墙和ES自带的认证,几个基础的安全加固也值得做:
按需开放端口,定期用ss或netstat检查端口监听情况;
控制文件权限,Elasticsearch配置目录权限设为750,es_user属主,避免其他用户读取配置文件里的密码信息;
系统补丁及时更新,这个不用多讲,但确实容易被忽略;
备份策略,Elasticsearch的备份通常用snapshot接口打到对象存储或NAS,建议在部署完成后就做一次完整快照测试恢复,不要等到数据丢了才开始研究备份方案。
6. 日志采集与Filebeat接入配置
6.1 Filebeat配置与输出到Elasticsearch
整个ELK链路中,采集端通常用Filebeat,轻量、资源占用小。它的配置文件核心是定位日志文件路径和定义输出目标。
一个典型的Java应用日志采集配置:
filebeat.inputs: - type: filestream enabled: true paths: - /data/logs/app/*.log fields: log_type: java-app fields_under_root: true output.elasticsearch: hosts: ["http://node-1:9200", "http://node-2:9200", "http://node-3:9200"] index: "java-app-%{+yyyy.MM.dd}" setup.template.name: "java-app" setup.template.pattern: "java-app-*"这里有个经验:如果日志文件会有多个来源,建议在fields里增加log_type标识,后续在Kibana里按字段过滤不同服务的日志,体验会好很多。
6.2 索引模板统一管理
如果采集端直接写Elasticsearch,建议先把索引模板配好。索引模板负责约束索引的mapping设置、分片数量、副本数量等,避免每个索引都套默认配置。
一个基础的模板配置:
curl -X PUT "http://node-1:9200/_index_template/java-app-template" -H 'Content-Type: application/json' -d '{ "index_patterns": ["java-app-*"], "template": { "settings": { "number_of_shards": 3, "number_of_replicas": 1 } } }'分片数量这里特意提一下。5节点的集群,3个数据分片配1个副本,总共就是6个分片副本分散在2台数据节点上。分片数量不宜过多,过多会让每个分片内的数据量过小,查询效率反而下降;也不宜过少,过少则单分片数据量太大,影响均衡分布。具体需要结合数据量估算,但默认3个分片对中等规模日志量是比较稳妥的起点。
6.3 Logstash是否一定需要接进来
我的观点是:除非有复杂的数据清洗需求,否则能直接用Filebeat写Elasticsearch就别先上Logstash。Filebeat本身可以做简单的字段提取和基础清洗,Logstash引入后虽然处理能力强,但部署一个Java运行时、配置过滤规则、维护Pipeline,都是在增加架构复杂度和资源消耗。
如果确实需要Logstash,建议单独部署,不要和ES节点抢资源。Logstah比较吃内存,尤其是grok正则解析复杂日志时,CPU消耗也不低。架构上可以让Filebeat输出到Logstash,Logstash处理后再输出到Elasticsearch,形成完整管道。但在日志量级不大、清洗需求简单的场景下,这层管道完全可以暂缓。
7. 常见问题与排查技巧实录
7.1 集群状态异常问题速查
| 现象 | 可能原因 | 处理方法 |
|---|---|---|
| 集群状态为yellow | 副本分片未分配 | 检查数据节点数量是否足够,检查节点磁盘是否达到水位线,手动触发reroute |
| 集群状态为red | 主分片未分配 | 查看未分配原因,检查节点是否掉线、索引配置是否有误 |
| 节点之间互不可见 | network.host配置错误或transport端口不通 | 逐台检查elasticsearch.yml,测试9300端口连通性,如nc -vz node-2 9300 |
| 内存使用过高导致OOM | 堆内存设置过大或查询负载过高 | 调低Xmx,检查是否有大批量聚合查询,增加节点分担压力 |
| 磁盘写满后索引只读 | 磁盘水位线触发保护 | 清理旧索引或扩容,执行PUT _settings恢复读写 |
| 脑裂(集群出现多个主节点) | network分区或minimum_master_nodes配置错误 | 修正minimum_master_nodes为2,检查网络抖动 |
7.2 启动失败类问题排查
“max virtual memory areas vm.max_map_count”错误:前面已提,sysctl设置后必须确认已写入/etc/sysctl.conf并执行sysctl -p生效。重启服务器后这个参数如果没做持久化,还会再报。
端口被占用:9200或9300被其他进程抢占,尤其是9300,注意排查其他服务是否占用,比如某些应用框架的RPC端口。
JVM内存分配失败:启动时报“Could not reserve enough space for object heap”,一般是机器可用内存小于jvm.options里配置的Xmx值,改小内存配置后再启动。
引导检查未通过:可能因为系统账号权限不对、文件句柄限制未修改,启动时日志会明确提示具体哪项check失败,按日志处理即可。
7.3 数据采集链路问题
Filebeat能正常启动但Kibana搜不到数据,这种问题排查优先级最高的环节依次是:Filebeat输出端是否连通、索引是否生成、索引字段是否符合预期。
先看Filebeat状态:
filebeat test output看output.es.hosts的连通性。然后查Elasticsearch侧有没有生成对应索引:
curl -s http://node-1:9200/_cat/indices?v | grep java-app如果索引存在但没数据,大概率是Filebeat的日志路径没匹配到文件,或者fields配置把日志过滤掉了。检查字段名和路径名时要仔细,这类问题多数是路径写错或文件名写错。
7.4 重启集群的注意事项
集群需要重启时,尤其是5个节点都要重启,建议按“先数据节点、后主节点”的顺序滚动执行,并且在重启任一个节点前先确认集群状态为green。如果直接一次性全部宕机再启动,由于是全新冷启动,主节点需要重新选主并恢复分片分配,耗时更长,且如果其中有节点数据未同步,恢复过程可能触发分片重平衡,非常慢。
滚动重启期间要留意集群状态变化,如果重启过程中出现red或yellow,不用慌,等所有节点起来后再观察,分片会自动迁移。但如果长时间不恢复,就要检查是否有分片被卡在“UNASSIGNED”状态,用:
curl -s http://node-1:9200/_cluster/allocation/explain?pretty可以看到具体原因,比如磁盘空间不足、分配策略限制、或者分片数据损坏。
8. 部署后的监控、备份与运维配套
8.1 集群健康监控方案
Elasticsearch自身提供_cat/health等REST接口,适合做基础监控。最简单的做法是用crontab定时curl采集健康状态,状态非green时告警。但如果团队已有监控体系,我更建议让Prometheus通过elasticsearch_exporter抓取指标,再配Grafana看板,可以实时看到分片数、堆内存、JVM GC、磁盘水位等关键指标。
几个必须盯紧的指标:
集群状态(green/yellow/red),每次变化都要告警;
堆内存使用率,长期超过85%要考虑扩容或优化查询;
磁盘使用率,ES的磁盘水位线默认是85%写入水位线,到达后不会自动清理,必须主动处理;
分片数量与状态,分片长时间处于initializing或relocating状态,说明集群正在做大量迁移,要关注是不是有节点不稳定。
8.2 数据备份与恢复演练
Elasticsearch的数据备份用的是快照接口。配置一个仓库(repository),然后定期快照。以本地NAS目录为例:
curl -X PUT "http://node-1:9200/_snapshot/my_backup" -H 'Content-Type: application/json' -d '{ "type": "fs", "settings": { "location": "/opt/es-backup" } }'创建快照:
curl -X PUT "http://node-1:9200/_snapshot/my_backup/snapshot_20240826?wait_for_completion=true"这里有个坑:备份仓库的路径需要在elasticsearch.yml里通过path.repo配置白名单放行,否则创建仓库会报错。另外,做快照恢复演练时,我建议准备一台独立的恢复环境,不要在正式集群上直接测试恢复操作,避免误覆盖线上数据。
恢复命令:
curl -X POST "http://node-1:9200/_snapshot/my_backup/snapshot_20240826/_restore"恢复后检查索引状态和文档条数,和备份时记录的数量比对,确认没有数据丢失。
8.3 索引生命周期与容量管理
日志类索引的增长速度非常快,建议在部署完成的第一天就制定清理策略。可以用Elasticsearch的ILM功能实现按时间或按容量自动滚动、删除。以30天生命周期为例:
curl -X PUT "http://node-1:9200/_ilm/policy/log_ilm_policy" -H 'Content-Type: application/json' -d '{ "policy": { "phases": { "hot": { "actions": { "rollover": { "max_size": "50GB", "max_age": "1d" } } }, "delete": { "min_age": "30d", "actions": { "delete": {} } } } } }'再把策略绑定到索引模板上,之后生成的索引都会自带这个生命周期策略。这样做的好处是,磁盘空间预警和清理工作不用每天手动处理。
9. 经验体会与补充建议
9.1 节点角色分离带来的运维变化
3主2从的架构跑起来之后,最大的感受是“角色职责清晰”。主节点专职管集群状态,数据节点专职管存储索引,排查问题时直接看对应角色的日志就行,不用在一堆日志里区分这个节点到底干了什么。特别是集群发生故障时,主节点日志里关于分片分配、选主的过程非常清晰,数据节点日志则主要围绕分片恢复、段落合并这些操作,定位问题快很多。
9.2 从这次部署中总结的实战心得
部署过程中有几点让我印象比较深。第一,系统参数一定在安装软件之前配好,否则Elasticsearch安装完启动时报错,又要回头改系统配置再重启,来回折腾浪费大量时间。第二,Kibana的时区设置虽然只是界面配置,但第一次看日志时发现时间差8小时,可能让你误判问题发生顺序,非常影响排障效率。第三,集群第一次启动的选主配置非常重要,必须一次性配好,否则后面改配置要重启节点、可能触发分片重分配,风险更大。
9.3 最后再分享一个小技巧
如果你用systemd管理Elasticsearch,启动脚本里记得加上TimeoutStopSec,否则集群节点在停机时要等分片自动迁移完才能退出,可能长时间卡在“stopping”状态。我一般设置:
TimeoutStopSec=120配合优雅停机流程,每次重启节点都很顺滑,不会出现被迫kill进程导致分片损坏的情况。这个细节看起来不起眼,但在大规模索引场景下能少踩很多坑。