ElasticsearchNotes

第 03 章:环境搭建

zjc 于 2026-01-03 发布

这是《Elasticsearch 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 本章搭建一个学习环境:Elasticsearch + Kibana,并介绍 Docker Compose、基础配置、安全认证、目录结构和常用验证命令。生产部署不只是“能启动”,还要规划 JVM、磁盘、网络、角色和安全策略。

3.1 版本选择

建议学习环境选择 8.x 最新稳定版。若公司仍使用 7.x,需要注意:

变化 7.x 8.x    
安全 可选,默认弱 默认开启 TLS 与认证    
客户端 High Level REST Client 常见 推荐 Java API Client    
类型 已基本移除 完全移除    
向量 支持有限 dense_vector 与 kNN 能力增强    
SQL/ES QL SQL 支持较成熟 ES QL 逐步增强

示例版本:

ELASTIC_VERSION: 8.15.0

3.2 Docker Compose 启动

创建 docker-compose.yml

services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.15.0
    container_name: es01
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - ES_JAVA_OPTS=-Xms1g -Xmx1g
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - es-data:/usr/share/elasticsearch/data
    ports:
      - "9200:9200"

  kibana:
    image: docker.elastic.co/kibana/kibana:8.15.0
    container_name: kibana01
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    ports:
      - "5601:5601"
    depends_on:
      - elasticsearch

volumes:
  es-data:

启动:

docker compose up -d
docker compose ps
docker logs -f es01

访问:

Elasticsearch: http://localhost:9200
Kibana:        http://localhost:5601

验证:

curl http://localhost:9200
curl http://localhost:9200/_cluster/health?pretty

3.3 本机安装

3.3.1 下载和解压

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.15.0-linux-x86_64.tar.gz
tar -xzf elasticsearch-8.15.0-linux-x86_64.tar.gz
cd elasticsearch-8.15.0

3.3.2 创建运行用户

Elasticsearch 不允许 root 直接启动。

useradd elastic
chown -R elastic:elastic /opt/elasticsearch-8.15.0
su elastic

3.3.3 修改配置

编辑 config/elasticsearch.yml

cluster.name: es-learning
node.name: node-1
path.data: /opt/elasticsearch-8.15.0/data
path.logs: /opt/elasticsearch-8.15.0/logs
network.host: 127.0.0.1
http.port: 9200
discovery.type: single-node
xpack.security.enabled: false

启动:

bin/elasticsearch

后台启动:

bin/elasticsearch -d -p pid.lock

3.4 Kibana 安装

解压并编辑 config/kibana.yml

server.name: kibana
server.host: "0.0.0.0"
server.port: 5601
elasticsearch.hosts: ["http://127.0.0.1:9200"]

启动:

bin/kibana

打开 Dev Tools:

Management -> Dev Tools

Kibana Dev Tools 是学习 ES 最方便的入口,支持自动补全和格式化。

3.5 三节点学习集群

学习分布式行为时,单节点环境不够。可用 Docker Compose 启动三节点。

示例 es01 配置:

services:
  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.15.0
    container_name: es01
    environment:
      - node.name=es01
      - cluster.name=es-learning
      - discovery.seed_hosts=es01,es02,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - xpack.security.enabled=false
      - ES_JAVA_OPTS=-Xms1g -Xmx1g
    ulimits:
      memlock:
        soft: -1
        hard: -1
    ports:
      - "9200:9200"

es02es03 类似,修改:

container_name: es02 / es03
node.name: es02 / es03
ports: 9201:9200 / 9202:9200

cluster.initial_master_nodes 只在集群首次启动时使用,生产集群扩容后不要随意修改。

3.6 基础配置详解

3.6.1 集群与节点

cluster.name: es-learning
node.name: node-1
network.host: 0.0.0.0
http.port: 9200
transport.port: 9300
discovery.seed_hosts:
  - 10.0.0.11:9300
  - 10.0.0.12:9300
  - 10.0.0.13:9300
cluster.initial_master_nodes:
  - node-1
  - node-2
  - node-3

说明:

配置 作用
cluster.name 集群名称,同集群必须一致
node.name 节点名称,必须唯一
discovery.seed_hosts 种子节点列表
cluster.initial_master_nodes 首次启动时候选 master
network.host 绑定地址
http.port REST API 端口
transport.port 节点通信端口

3.6.2 路径

path.data: /data/elasticsearch
path.logs: /var/log/elasticsearch

生产要求:

  1. 数据目录使用独立磁盘或卷;
  2. 避免数据目录和日志目录放满;
  3. 目录属主必须是运行用户;
  4. 不要把数据目录放在 NFS 等不满足一致性语义的文件系统上。

3.6.3 内存

bootstrap.memory_lock: true

环境变量:

ES_JAVA_OPTS=-Xms8g -Xmx8g

推荐通过 jvm.optionsjvm.options.d 配置:

-Xms8g
-Xmx8g

经验:

  1. Xms 与 Xmx 设置一致,避免堆动态伸缩;
  2. 堆内存通常不超过物理内存 50%,剩余留给操作系统 Page Cache;
  3. 单节点堆通常不超过 31GB,具体与压缩指针边界有关;
  4. 交换内存应禁用或严格控制。

3.6.4 系统 vm.max_map_count

sudo sysctl -w vm.max_map_count=262144
echo 'vm.max_map_count=262144' | sudo tee /etc/sysctl.d/99-elasticsearch.conf

Lucene 需要大量内存映射文件,该参数过小会导致启动失败。

3.6.5 文件描述符

ulimit -n 65535

生产建议至少 65535,可通过 systemd 配置:

[Service]
LimitNOFILE=65535
LimitNPROC=4096
LimitMEMLOCK=infinity

3.7 安全启动

Elasticsearch 8 默认开启安全。首次启动时会输出密码和 enrollment token。

重置 elastic 用户密码:

bin/elasticsearch-reset-password -u elastic

生成 Kibana enrollment token:

bin/elasticsearch-create-enrollment-token -s kibana

带认证访问:

curl -u elastic:'password' https://localhost:9200 -k

正式环境建议:

  1. 启用 TLS;
  2. 使用独立 CA;
  3. 每个节点有独立证书;
  4. Kibana 与 ES 之间加密通信;
  5. 应用使用独立用户和最小权限;
  6. 不在公网暴露 9200。

开发环境可以临时关闭安全:

xpack.security.enabled: false

生产环境不要这样做。

3.8 目录结构

elasticsearch-8.15.0/
 +-- bin/          可执行脚本
 +-- config/       配置文件
 +-- data/         索引数据
 +-- jdk/          内置 JDK
 +-- lib/          Java 依赖
 +-- logs/         日志
 +-- modules/      内置模块
 +-- plugins/      插件

常用命令:

bin/elasticsearch
bin/elasticsearch-plugin list
bin/elasticsearch-plugin install analysis-ik
bin/elasticsearch-reset-password -u elastic
bin/elasticsearch-shard

3.9 安装中文分词插件

以 IK 为例,版本必须与 Elasticsearch 一致:

bin/elasticsearch-plugin install \
  https://get.infini.cloud/elasticsearch/analysis-ik/8.15.0

重启:

bin/elasticsearch -d

测试:

POST /_analyze
{
  "analyzer": "ik_max_word",
  "text": "轻薄高刷新率笔记本电脑"
}

结果应包含:

轻薄
高
刷新率
笔记本
笔记本电脑

实际词库与插件版本有关,需以输出为准。

3.10 常用验证命令

查看节点

GET /_cat/nodes?v

输出示例:

ip        heap.percent ram.percent cpu node.role master name
127.0.0.1           23          67   8 cdfhilmrstw *      node-1

查看索引

GET /_cat/indices?v

查看分片

GET /_cat/shards?v

查看健康

GET /_cluster/health?pretty

查看分配失败原因

GET /_cluster/allocation/explain?pretty

3.11 常见启动问题

问题 原因 处理
vm.max_map_count 太小 系统参数未调整 调整为 262144
启动后立刻退出 root 用户启动 切换非 root 用户
内存不足 JVM 或容器限制过小 增加内存或降低学习配置
文件描述符不足 ulimit 太低 调整 LimitNOFILE
集群一直加入失败 seed hosts 或网络不通 检查 transport 端口
Kibana 连不上 地址或证书错误 检查 elasticsearch.hosts
磁盘水位导致分片不分配 磁盘占用高 清理或扩容磁盘

3.12 学习数据准备

创建索引:

PUT /products
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0
  },
  "mappings": {
    "properties": {
      "title": { "type": "text" },
      "brand": { "type": "keyword" },
      "price": { "type": "double" },
      "status": { "type": "keyword" },
      "created_at": { "type": "date" }
    }
  }
}

写入文档:

POST /products/_bulk
{"index": {"_id": "1"}}
{"title": "轻薄笔记本电脑", "brand": "Nova", "price": 6999, "status": "ON_SALE", "created_at": "2026-08-25T10:00:00Z"}
{"index": {"_id": "2"}}
{"title": "游戏手机", "brand": "Mars", "price": 4999, "status": "ON_SALE", "created_at": "2026-08-24T10:00:00Z"}
{"index": {"_id": "3"}}
{"title": "机械键盘", "brand": "Nova", "price": 499, "status": "OFF_SALE", "created_at": "2026-08-23T10:00:00Z"}

查询:

GET /products/_search
{
  "query": {
    "match": {
      "title": "笔记本"
    }
  }
}

更完整的查询语法见第 8 章。

3.13 本章小结

3.14 思考题

  1. 为什么 Elasticsearch 堆内存不建议超过物理内存的一半?
  2. discovery.seed_hostscluster.initial_master_nodes 分别什么时候使用?
  3. 单节点环境索引副本设为 1 会出现什么现象?为什么?
  4. 如果 Kibana 无法连接 ES,你会按什么顺序排查?
  5. 生产环境关闭 security 可能带来哪些风险?