4428 字
22 分钟
ELK系列(一):ElasticSearch 介绍与安装(RPM / 二进制 / 多实例全攻略)

引言与背景#

日志是系统排障的第一手证据,但当服务器数量从一台变成几十台,“逐台登录 + grep” 的排查方式就会彻底失效。本章作为系列开篇,先讲清 ElasticSearch 在 ELK 技术栈中的定位,再说明阅读本文所需的准备与最终收获。

问题场景:为什么需要 ElasticSearch#

传统日志排查的典型困境:

  • 分散存储:日志散落在多台服务器本地磁盘,排查一次故障需要反复 SSH 跳转
  • 检索低效:只能依赖 grep / awk 逐文件翻找,无法跨主机聚合与模糊检索
  • 无法实时:事后分析靠人肉翻日志,缺乏实时索引与可视化分析能力

而 ELK 技术栈(ElasticSearch + Logstash + Kibana)正是为此而生:

组件职责类比
Logstash日志采集、清洗、转运搬运工
ElasticSearch存储、索引、检索地基与仓库
Kibana可视化与交互查询展示窗口
为什么先学安装

ElasticSearch 是整个日志平台的核心存储与检索引擎,相当于地基。而安装恰恰是运维 ES 的第一道门槛——部署方式多样、内核参数与配置坑极多,新手极易踩雷,本文会把这些坑逐一填平。

目标读者与前置知识#

本文面向运维工程师与日志平台 / ELK 搭建初学者。开始之前,请确认你已具备:

  • Linux 基础操作(文件编辑、权限管理)
  • systemd 服务管理(systemctl 常用子命令)
  • 基础网络概念(IP、端口、防火墙)

本文实战效果#

读完全文并动手跟练后,你将能够:

  • 用 RPM 方式完成单机与集群部署,理解每一个核心配置项
  • 用 二进制方式完成生产级部署(内核调优 + JDK + 堆内存 + systemd 托管)
  • 在单机上部署多实例组成集群,并掌握一套通用排错三板斧

ElasticSearch 核心概念与基础认知#

在动手安装之前,先用最短的时间建立对 ES 的整体认知:它由哪些角色组成、数据如何组织、对外暴露哪些端口。这些概念将直接决定后文配置文件中每一行的含义。

术语定义#

ES 的核心术语可以用一张表快速建立印象:

术语定义要点
Cluster(集群)一个或多个节点的集合,对外提供统一的索引与检索服务通过 cluster.name 标识
Node(节点)集群中的单个 ES 实例通过 node.name 标识
Index(索引)数据存储的逻辑单元,类似数据库的”表”一类文档的集合
Document(文档)数据的最小单元,JSON 格式类似表中的一行记录
Shard(分片)索引的水平拆分单元实现水平扩展
Replica(副本)分片的冗余拷贝提供高可用与读扩展
Master 节点负责集群元数据管理、分片分配由选举产生
数据节点负责数据存储与检索计算消耗磁盘与内存
TIP

一个索引 = 多个主分片 + 若干副本。分片数量在创建索引时确定,副本数量可随时调整。

版本与环境说明#

本文的实验环境与软件获取渠道如下:

  • 示例版本:ElasticSearch 7.17.x(7.x 系列最后一个大版本,长期维护)
  • 操作系统:CentOS 7.x
  • 安装包统一从官方仓库获取:
    • RPM 包:elasticsearch-7.17.x-x86_64.rpm
    • 二进制包:elasticsearch-7.17.x-linux-x86_64.tar.gz
JDK 的取舍

ES 7.17 安装包已自带 bundled JDK,开箱即用;但生产环境常统一使用外部 Oracle JDK,便于集中管理 Java 版本。二选一即可,后文二进制部署将演示外部 JDK 的配置方法。

架构与端口认知#

一个典型的三节点集群,其请求流转与角色关系如下:

graph TD
    Client["客户端 :9200 发起读写"] --> N1["Node-1(Master*)"]
    Client --> N2["Node-2(Data)"]
    Client --> N3["Node-3(Data)"]
    N1 -. "Transport :9300" .- N2
    N2 -. "Transport :9300" .- N3
    N1 -. "Transport :9300" .- N3
    N2 --> S[("数据落盘<br/>Shard + Replica")]

数据流向可概括为:写入请求 → 协调节点路由 → 目标分片落盘 → 副本同步。

必须提前记住的两个关键端口:

端口协议 / 用途暴露范围
9200HTTP REST 接口,对外提供增删改查服务对客户端开放
9300Transport 协议,节点间通信与 Master 选举仅集群内部

这两个端口是后文多实例端口规划与集群组网配置的基础。1


RPM 方式安装 ElasticSearch(单机 + 集群)#

RPM 是官方为 RHEL/CentOS 系发行版提供的封装包,目录布局与服务脚本开箱即用,适合快速搭建。本章先完成单机部署跑通最小闭环,再扩展为三节点集群,讲清 Master 选举的配置要点。

RPM 包获取与安装#

下载并安装(可直接复制执行):

安装 ES RPM 包
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.x-x86_64.rpm
rpm -ivh elasticsearch-7.17.x-x86_64.rpm

验证安装结果:

验证安装
rpm -qa | grep elasticsearch
终端输出
elasticsearch-7.17.x-1.x86_64

RPM 安装后的目录布局需要熟记,后续所有操作都围绕它们展开:

用途路径
配置文件/etc/elasticsearch
数据目录/var/lib/elasticsearch
日志目录/var/log/elasticsearch

单机部署:elasticsearch.yml 网络与节点配置#

编辑核心配置文件 vim /etc/elasticsearch/elasticsearch.yml,修改以下四项:

/etc/elasticsearch/elasticsearch.yml
cluster.name: my-es-cluster # 集群标识,同一集群必须一致
node.name: node-1 # 节点标识,集群内唯一
network.host: 0.0.0.0 # 监听所有网卡,确保外部可访问
http.port: 9200 # HTTP 服务端口
NOTE

network.host: 0.0.0.0 表示监听本机所有网卡地址,单机实验最省事;集群场景必须改为本机内网 IP,见下一小节。

启动并验证:

启动并验证单机 ES
systemctl start elasticsearch
curl http://127.0.0.1:9200

预期返回如下 JSON,看到 "tagline" : "You Know, for Search" 即代表单机部署成功:

终端输出
{
"name" : "node-1",
"cluster_name" : "my-es-cluster",
"version" : { "number" : "7.17.x", "build_type" : "rpm" },
"tagline" : "You Know, for Search"
}

集群部署:多节点组网与指定 Master 选举#

集群部署是在单机基础上的扩展,核心差异在于节点寻址与首次选举。以三节点为例(192.168.1.11/12/13),各节点分别修改 elasticsearch.yml:

/etc/elasticsearch/elasticsearch.yml(以 192.168.1.11 为例)
cluster.name: my-es-cluster
node.name: node-1 # 各节点依次为 node-1/2/3
network.host: 192.168.1.11 # 绑定本机内网 IP,禁止用 0.0.0.0
http.port: 9200
transport.port: 9300 # 节点间通信端口
discovery.seed_hosts: ["192.168.1.11", "192.168.1.12", "192.168.1.13"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]

高亮的两行是集群组网的关键:

  • discovery.seed_hosts:候选节点列表,节点启动后据此发现彼此
  • cluster.initial_master_nodes:仅首次启动集群时生效,指定初始 Master 候选,保证首次选举成功
启动集群前必须清理数据

首次组建集群前,务必在所有节点上清理数据目录与日志目录,否则旧的集群脏数据会导致节点无法加入,甚至引发脑裂:

清理脏数据
rm -rf /var/lib/elasticsearch/* /var/log/elasticsearch/*

逐台启动后,验证集群状态:

验证集群
curl http://192.168.1.11:9200/_cat/nodes?v
curl http://192.168.1.11:9200/_cluster/health?pretty

预期输出节点数量为 3,带 * 号者为当选 Master:

终端输出
ip heap.percent ram.percent cpu node.role master name
192.168.1.11 25 95 1 cdfhilmrstw * node-1
192.168.1.12 30 95 1 cdfhilmrstw - node-2
192.168.1.13 28 95 1 cdfhilmrstw - node-3

健康检查中重点关注 "status" : "green",表示所有主分片与副本均已就绪。

开机自启与端口监听检查#

最后收尾两项:

设置开机自启并检查端口
systemctl enable --now elasticsearch
ss -lntp | grep -E '9200|9300'

预期输出中 9200 与 9300 双端口均处于 LISTEN 状态,RPM 部署即全部完成。2


二进制方式安装 ElasticSearch(生产推荐)#

相比 RPM 的”开箱即用”,二进制 tar.gz 方式把安装路径、运行用户、JVM 参数、服务托管全部交还给运维人员掌控,是生产环境的主流选择。本章按”解压部署 → 内核调优 → JDK 配置 → 堆内存 → systemd 托管”的顺序,完成一套可直接落地的生产级部署。

二进制包部署与目录规划#

下载并解压部署(可直接复制执行):

解压部署 ES
tar -xf elasticsearch-7.17.x-linux-x86_64.tar.gz -C /usr/local/
ln -s /usr/local/elasticsearch-7.17.x /usr/local/es7
TIP

通过软链接 /usr/local/es7 指向真实版本目录,后续升级版本时只需切换软链接,配置文件与脚本中的路径无需改动。

禁止 root 直接启动

ES 出于安全设计,拒绝以 root 用户启动。必须创建普通用户并授权目录:

创建运行用户
useradd es
chown -R es:es /usr/local/es7 /usr/local/elasticsearch-7.17.x

解压后的目录结构速览:

目录用途
bin/启动脚本与工具(elasticsearch 等)
config/配置文件(elasticsearch.yml、jvm.options)
data/数据目录(建议迁移到大磁盘)
logs/日志目录
plugins/插件目录(如 IK 分词器)

内核调优:文件描述符与虚拟内存映射#

ES 需要同时打开大量文件(分片、段文件)并建立大量内存映射(Lucene 的 mmap 机制),Linux 默认限制远远不够,必须在启动前完成调优,否则 bootstrap 检查会直接拒绝启动。

调整资源限制前,可先用 ulimit -n(查看文件描述符上限)和 ulimit -a(查看全部限制)确认当前值。编辑 /etc/security/limits.d/es.conf(可直接复制):

/etc/security/limits.d/es.conf
es soft nofile 65535
es hard nofile 65535
es soft nproc 4096
es hard nproc 4096
es soft memlock unlimited
es hard memlock unlimited

再调整内核参数。sysctl 常用子命令先混个眼熟:

用法作用
sysctl -w key=value临时写入,立即生效但重启丢失
sysctl -p [文件]加载配置文件(默认 /etc/sysctl.conf)
sysctl -q key静默查询某个键的当前值

编辑 /etc/sysctl.d/es.conf:

/etc/sysctl.d/es.conf
vm.max_map_count = 262144

使其生效并验证:

加载并验证内核参数
sysctl -p /etc/sysctl.d/es.conf
sysctl -q vm.max_map_count
终端输出
vm.max_map_count = 262144
为什么必须调这两项
  • 文件描述符不足 → 运行中报 too many open files,索引写入直接失败
  • vm.max_map_count 过低(默认 65530)→ bootstrap 检查失败,进程拒绝启动

注意:limits.d 配置需要重新登录会话才会对新 shell 生效。

Oracle JDK 环境配置#

解压 Oracle JDK 至 /usr/local/jdk 后,写入环境变量(可直接复制,建议追加到 /etc/profile):

/etc/profile 追加内容
export JAVA_HOME=/usr/local/jdk
export PATH=$JAVA_HOME/bin:$PATH

执行 source /etc/profile 后验证:

验证 JDK
java -version
终端输出
java version "1.8.0_xxx"
Java(TM) SE Runtime Environment (build 1.8.0_xxx-bxx)
Java HotSpot(TM) 64-Bit Server VM (build 25.xxx-bxx, mixed mode)
JAVA_HOME 优先级

ES 查找 JDK 的顺序为:ES_JAVA_HOME → 自带 bundled JDK(jdk/ 目录)→ 系统 JAVA_HOME。若需强制指定外部 JDK,设置 ES_JAVA_HOME 最稳妥。

JVM 堆内存调整(jps / jmap 验证)#

堆内存是 ES 性能的第一杠杆,修改 config/jvm.options(可直接复制):

config/jvm.options
-Xms2g
-Xmx2g

配置原则:

  • 堆内存设为物理内存的一半(另一半留给 Lucene 页缓存)
  • 不超过 32G(超过后 JVM 指针压缩失效,反而浪费内存)
  • Xms 与 Xmx 保持一致,避免运行时堆伸缩带来的性能抖动

启动后验证是否真正生效:

验证堆内存
jps -l # 确认 ES 进程存在,获取 PID
jmap -heap <PID> # 查看堆配置实际生效值
终端输出(截取关键行)
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 2147483648 (2048.0MB) # 与 Xmx 设置一致

预期输出中 MaxHeapSize 与 jvm.options 中的设置值一致,即调整生效。

Systemd 托管二进制 ES 服务#

二进制包不附带服务脚本,需要手写 unit 文件交给 systemctl 统一管理。管理思路:所有服务单元由 systemctl 控制,完整配置可随时用 systemctl cat es7 复核。

创建 /usr/lib/systemd/system/es7.service(可直接复制):

/usr/lib/systemd/system/es7.service
[Unit]
Description=Elasticsearch 7
After=network.target
[Service]
Type=simple
User=es
Group=es
Environment=JAVA_HOME=/usr/local/jdk
ExecStart=/usr/local/es7/bin/elasticsearch
LimitNOFILE=65535
LimitMEMLOCK=infinity
Restart=on-failure
[Install]
WantedBy=multi-user.target
WARNING

unit 文件中的 LimitNOFILE / LimitMEMLOCK 与 limits.d 配置二选一即可生效,但 systemd 托管的服务以 unit 文件为准——写在两处做双保险,是生产环境的常见习惯。

加载并管理服务:

启动托管服务
systemctl daemon-reload
systemctl enable --now es7
systemctl status es7

预期输出关键行:

终端输出
● es7.service - Elasticsearch 7
Active: active (running) since ...
Main PID: xxxxx (java)

最后通过 systemctl cat es7 复核完整单元内容,确认与实际编写一致,二进制生产级部署即告完成。


ElasticSearch 多实例安装#

单台高配服务器只跑一个 ES 实例,是对内存与 CPU 的浪费。多实例部署通过在同一台机器上运行多个互相隔离的 ES 进程,既能充分利用硬件资源,也能在测试环境快速模拟多节点集群。本章讲解目录与端口的隔离规划,并完成双实例组网验证。

多实例目录与端口规划#

适用场景主要有两类:

  • 生产环境:单台大内存服务器跑多个实例,分摊 GC 压力、提升资源利用率
  • 测试环境:只有一台机器时,模拟真实多节点集群行为

多实例的核心原则是一切资源隔离。每个实例必须拥有独立的数据目录与日志目录(可直接复制):

config/elasticsearch.yml(实例 es1)
path.data: /data/es1
path.logs: /logs/es1

端口规划必须提前设计,避免冲突:

实例HTTP 端口Transport 端口数据目录日志目录
es192009300/data/es1/logs/es1
es292019301/data/es2/logs/es2
WARNING

目录创建后务必执行 chown -R es:es /data/es* /logs/es*,否则 es 用户无权限写入,启动直接报错。

多实例配置与启动验证#

以二进制部署的 es1 为基础,复制配置目录生成 es2:

复制 es2 实例配置
cp -r /usr/local/es7/config /usr/local/es7/config-es2
chown -R es:es /usr/local/es7/config-es2

修改 es2 的 config-es2/elasticsearch.yml,与 es1 的关键差异仅五项:

config-es2/elasticsearch.yml
node.name: node-es2 # 1. 节点名唯一
cluster.name: my-es-cluster # 集群名保持一致,才能自动组网
http.port: 9201 # 2. HTTP 端口
transport.port: 9301 # 3. Transport 端口
path.data: /data/es2 # 4. 独立数据目录
path.logs: /logs/es2 # 5. 独立日志目录
discovery.seed_hosts: ["127.0.0.1:9300", "127.0.0.1:9301"]

多实例本质上与二进制部署完全一致,重点仅在于目录与端口隔离。启动时通过 ES_PATH_CONF 指定各自的配置目录:

分别启动两个实例
su - es -c '/usr/local/es7/bin/elasticsearch -d'
su - es -c 'ES_PATH_CONF=/usr/local/es7/config-es2 /usr/local/es7/bin/elasticsearch -d'

同机多实例自动组成集群,验证:

验证双节点集群
curl http://127.0.0.1:9200/_cat/nodes?v
终端输出
ip heap.percent ram.percent cpu node.role master name
127.0.0.1 20 95 2 cdfhilmrstw * node-es1
127.0.0.1 18 95 2 cdfhilmrstw - node-es2

预期输出显示两个节点,构成双节点集群,多实例部署完成。


常见问题与排错指南#

ES 启动失败的原因五花八门,但排查路径是收敛的。本章给出一套”排错三板斧”通用流程,再逐一拆解四个最典型的报错场景,让你面对任何启动异常都有章可循。

排错三板斧:状态、日志、错误关键字#

遇到问题按以下顺序执行,三板斧下来,90% 的故障都能定位:

第一斧——查看服务状态,systemd 会截留最近一次启动的报错摘要:

第一斧:服务状态
systemctl status es7 -l # -l 显示完整报错行,不截断

第二斧——查看 systemd 日志,追踪服务启动全过程(含 ExecStart 之前的失败):

第二斧:systemd 日志
journalctl -u es7

第三斧——跟踪 ES 自身日志,这里才有最详细的堆栈信息:

第三斧:ES 日志
tail -100f $ES_HOME/logs/<cluster.name>.log
日志阅读技巧

重点过滤 ERROR 关键字,找到第一个错误块后,顺着 at 开头的 Java 堆栈行向下读,最底层的类与方法往往就是根因所在。日志文件名由 cluster.name 决定,改集群名后找不到日志先核对文件名。

典型报错与解决方案#

下表汇总四个高频报错,随后逐一说明:

报错特征根因修复方向
max file descriptors [4096] too low文件描述符限制未生效核对 limits 配置,重新登录
vm.max_map_count [65530] is too low虚拟内存映射数过低执行 sysctl -p 加载配置
OutOfMemoryError / 进程被 Kill物理内存不足调低 Xms / Xmx
节点无法加入集群脏数据 / 配置不一致清数据目录、核对配置
bootstrap checks 失败

生产模式(network.host 绑定非回环地址)下 ES 会强制执行启动检查。报 max file descriptors [4096] too low 或 max virtual memory areas vm.max_map_count [65530] is too low 时,回到”内核调优”小节核对配置——特别注意 limits 修改后必须重新登录会话才生效,用 ulimit -n 复核当前值。

启动后被 OOM Kill 或无法分配堆

物理内存不足以支撑堆设置时,进程会被内核直接杀掉(dmesg 中可见 OOM 记录)→ 调低 jvm.options 中的 Xms / Xmx,遵循”物理内存一半”原则。

节点无法加入集群

按以下顺序逐项排查:

  • 数据目录残留旧集群 state → 停止服务后清理 path.data 与 path.logs 再重启
  • 各节点 cluster.name 不一致 → 统一所有节点的集群名
  • discovery.seed_hosts 配置错误 → 核对 IP 与 9300 端口可达性
  • 9300 端口被防火墙拦截 → firewall-cmd --add-port=9300/tcp --permanent && firewall-cmd --reload

其余零散的启动失败,八成是权限问题,一条命令统一修正:

修正目录属主
chown -R es:es /usr/local/es7 /data /logs

总结#

本文从概念认知出发,完整走通了 ElasticSearch 的三种安装方式与通用排错流程。最后回顾一下核心脉络,并给出生产落地建议。

核心内容回顾#

三种安装方式各有适用场景,横向对比:

维度RPM二进制多实例
部署速度★★★ 最快★★ 需手工配置★★ 同二进制
可控性★ 路径固定★★★ 完全可控★★★ 完全可控
适用场景快速验证、测试生产推荐高配单机、资源复用

关键配置主线贯穿全文:网络绑定 → 集群/节点命名 → Master 选举 → 内核调优 → 堆内存,无论哪种安装方式,这条主线都适用。

生产实践建议与进阶方向#

生产环境落地,牢记以下清单:

  • 优先采用二进制部署,路径与参数完全掌控
  • 数据目录挂载独立磁盘,与系统盘隔离
  • 堆内存设为物理内存一半,且不超过 32G
  • 先完成内核调优再上线,勿带默认参数强行启动

:::

Footnotes#

  1. 更多网络配置细节可参考官方文档 “Network settings” 章节。 ↩

  2. 若 9300 未监听,通常是 transport.port 未配置或被防火墙拦截,可结合文末排错章节处理。 ↩

ELK系列(一):ElasticSearch 介绍与安装(RPM / 二进制 / 多实例全攻略)
https://www.6ixblog.site/posts/elk-1/
作者
Licwic
发布于
2025-07-02
许可协议
CC BY-NC-SA 4.0