ElasticSearch部署与集群实操全攻略

ElasticSearch部署与集群实操全攻略

一、概述

本文全面覆盖ElasticSearch(ES)从集群部署搭建高级运维实操的全流程核心知识点,包含RPM单点/集群部署、二进制集群部署、ES6/ES7多实例部署,同时详解ES核心术语、RESTful API操作、索引/文档管理、索引模板配置、DSL基础与高级查询、聚合查询、IK中文分词器配置、Kibana集群集成,集群数据迁移、ES集群全量运维API、集群配置优先级、分片重路由等生产级运维内容,还包含系统调优、JDK环境配置、systemd服务管理、堆内存调整等实战内容,并整理了实操中常见报错的解决方案。

二、核心知识点

2.1 ES部署方式分类

部署方式 适用场景 核心优势 关键注意点
RPM部署(单点/集群) 快速测试、简单环境部署 安装便捷、自动配置基础路径 配置灵活性较低,版本依赖系统环境
二进制部署(集群) 生产环境、自定义配置场景 路径自由、配置灵活、版本兼容性强 需手动配置权限、目录、服务管理
多实例部署(ES6+ES7) 多版本测试、资源复用场景 一台主机运行多个ES实例 需区分端口、数据目录,避免资源冲突

2.2 核心端口作用(面试高频)

端口号 作用 通信协议 适用场景
9200 对外提供HTTP/HTTPS服务 HTTP 客户端访问、API调用(如查询集群状态)
9300 集群内部数据通信 TCP 节点间数据同步、主节点选举
19200 ES6多实例对外服务端口 HTTP 多实例部署时ES6的客户端访问端口
19300 ES6多实例内部通信端口 TCP 多实例部署时ES6节点间通信
5601 Kibana可视化工具访问端口 HTTP Kibana界面操作、ES集群可视化管理

2.3 集群核心配置参数

参数名称 作用 集群部署必填项
cluster.name 指定集群名称,同一集群需一致
network.host 监听地址,0.0.0.0表示对外暴露
discovery.seed_hosts 集群节点IP/主机名列表
cluster.initial_master_nodes 参与主节点选举的节点 是(ES7+)
discovery.zen.ping.unicast.hosts 集群节点列表(ES6版本) 是(ES6)
discovery.zen.minimum_master_nodes 最小主节点数(ES6版本) 是(ES6)
path.data 数据存储目录 是(自定义路径时)
path.logs 日志存储目录 是(自定义路径时)
reindex.remote.whitelist 集群迁移远程主机白名单 是(跨集群迁移时)

2.4 核心调优要点

  1. 文件打开限制:ES进程需较高的文件打开数量,建议设置为soft nofile 65535hard nofile 131070
  2. 内核虚拟内存vm.max_map_count需调整为至少524288,否则启动失败;
  3. 堆内存配置-Xms-Xmx需设置一致,避免内存 resize 卡顿,建议不超过物理内存的50%;
  4. 权限控制:ES禁止root用户启动,需创建普通用户(如oldboya)并授权目录权限。

2.5 ES核心术语(实操必备)

术语 核心定义 关键特性
索引(Index) 存储数据的逻辑单元 类比关系型数据库的数据库
分片(Shard) 索引的物理拆分单元 一个索引至少1个分片,分布式存储实现集群扩容
副本(Replica) 分片的冗余备份单元 一个分片可配置0+副本,提升可用性和读性能
文档(Document) 实际存储的最小数据单元 类比关系型数据库的,采用JSON格式存储
主分片 分片的主数据节点 支持读写操作,是数据写入的核心节点
副本分片 主分片的备份节点 仅支持操作,主分片故障时可升级为主分片

2.6 ES集群健康状态(按颜色区分)

颜色 状态说明 核心影响
green(绿色) 所有主分片+副本分片均正常运行 集群状态最优,无任何故障
yellow(黄色) 主分片全部正常,部分副本分片异常 数据可用但无冗余,副本故障无备份
red(红色) 部分主分片异常 集群数据丢失,相关索引无法读写

2.7 RESTful风格与HTTP方法映射

RESTful是ES的核心交互风格,基于HTTP协议实现数据操作,各方法对应操作如下:

HTTP方法 核心操作 ES应用场景
GET 查询/获取数据 查看索引、文档、集群状态、模板
PUT 创建/更新(指定标识) 创建指定配置的索引、修改集群设置
POST 创建/更新/批量操作 创建文档、批量增删改查、重索引、模板创建
DELETE 删除数据 删除索引、文档、模板

2.8 ES核心字段类型(常用)

类型 特性 适用场景 检索规则
text 支持分词,可全文检索 商品标题、用户名、文章内容 模糊匹配、分词检索
keyword 不支持分词,精准匹配 性别、省份、商品类型、IP 完全匹配、聚合分析
date 日期类型,支持指定格式 生日、创建时间、日志时间 范围查询、排序
ip 支持IPV4/IPV6,网段匹配 客户端IP、服务器IP 精准匹配、网段查询(如192.168.15.0/24)
double/long 数值类型 价格、数量、分组ID 范围查询、排序、聚合
boolean 布尔值(true/false) 状态标识、开关配置 精准匹配

2.9 分词器核心类型

分词器 特性 适用场景
standard(标准分词器) 按空格/符号分词,中文按单字拆分 英文检索
ik_max_word(IK细粒度分词) 中文按语义拆分,穷尽所有分词可能 中文全文检索
ik_smart(IK粗粒度分词) 中文按语义拆分,取最优分词结果 中文精准检索

2.10 索引模板核心特性

  1. 定义:创建索引的标准化模板,预配置别名、索引匹配规则、分片副本、映射关系,创建符合匹配规则的索引时会自动套用模板配置;
  2. 匹配规则:通过index_patterns配置(支持通配符*),如oldboya-linux85*匹配所有以该前缀命名的索引;
  3. 生效时机:仅在索引创建时生效,修改模板后不影响已创建的索引。

2.11 DSL查询分类(核心)

DSL(Domain Specific Language)是ES基于JSON的查询语言,覆盖所有数据检索场景,核心分类如下:

查询类型 核心特性 适用场景
基础查询 match/match_phrase/match_all 全文检索、精准匹配、全量查询
辅助查询 _source/exists/高亮 指定返回字段、判断字段存在、结果高亮
分页查询 size+from 分页展示检索结果
排序查询 sort+order(asc/desc) 按数值/日期字段升序/降序排序
多条件查询 bool(must/should/must_not/filter) 多条件组合检索、范围过滤
精准多值查询 terms 匹配字段的多个值(如价格9.9/19.9)
权重查询 boost 为指定检索词设置权重,提升匹配优先级

2.12 聚合查询类型(常用)

聚合查询用于对ES数据做统计分析,类比关系型数据库的count/max/min/avg/sum,核心类型如下:

聚合类型 核心作用 对应SQL函数
terms 按字段分组统计数量 group by + count
max 统计字段最大值 max()
min 统计字段最小值 min()
avg 统计字段平均值 avg()
sum 统计字段求和 sum()

2.13 ES集群配置优先级(从高到低)

ES支持多种配置方式,相同配置按以下优先级生效,高优先级覆盖低优先级:

  1. Transient:临时配置,集群重启后立即失效,适用于临时调试;
  2. Persistent:持久化配置,集群重启后依旧生效,适用于长期配置;
  3. elasticsearch.yml:本地配置文件,节点级配置,仅对当前节点生效;
  4. Default:ES默认配置,未手动配置时启用。

2.14 ES集群核心运维API分类

ES提供全量RESTful API实现集群运维,无需登录节点即可操作,核心分类如下:

API类型 核心作用 核心接口
健康状态API 查看集群健康状态、分片信息 /_cluster/health
配置设置API 查看/修改集群配置(临时/持久化) /_cluster/settings
集群状态API 查看节点、索引元数据、分片路由 /_cluster/state
统计API 查看集群/节点/索引的统计指标 /_cluster/stats
分片分配API 分析分片未分配原因 /_cluster/allocation/explain
分片重路由API 手动移动/取消分片分配 /_cluster/reroute
重索引API 同集群/跨集群数据迁移 /_reindex

三、步骤/命令

3.1 RPM方式单点部署(快速测试)

# 1. 下载ES RPM包(线下环境直接下载)
⭐️curl -o elasticsearch-7.17.5-x86_64.rpm http://192.168.15.253/ElasticStack/softwares/rpm/elasticsearch-7.17.5-x86_64.rpm

# 2. 安装ES
⭐️rpm -ivh elasticsearch-7.17.5-x86_64.rpm  # -i:安装,-v:显示过程,-h:进度条

# 3. 修改核心配置文件
⭐️cat > /etc/elasticsearch/elasticsearch.yml << EOF
network.host: 0.0.0.0  # 对外暴露服务
discovery.seed_hosts: ["10.0.0.101"]  # 本机IP
cluster.initial_master_nodes: ["10.0.0.101"]  # 本机参与主节点选举
EOF

# 4. 启动ES服务并设置开机自启
⭐️systemctl enable --now elasticsearch

# 5. 效果验证(检查端口与服务状态)
ss -ntl  # 查看9200、9300端口是否监听
curl 10.0.0.101:9200  # 返回ES节点信息即为成功

3.2 RPM方式集群部署(3节点)

# 前提:3个节点均完成步骤1-2(下载+安装RPM包)

# 1. 主节点(10.0.0.101)数据清空(若之前部署过ES)
systemctl stop elasticsearch
rm -rf /var/lib/elasticsearch/* /var/log/elasticsearch/* /tmp/*

# 2. 主节点修改配置文件
⭐️cat > /etc/elasticsearch/elasticsearch.yml << EOF
cluster.name: oldboya-linux85  # 集群名称,所有节点一致
network.host: 0.0.0.0
discovery.seed_hosts: ["10.0.0.101","10.0.0.102","10.0.0.103"]  # 集群所有节点IP
cluster.initial_master_nodes: ["10.0.0.101","10.0.0.102","10.0.0.103"]  # 参与选举的节点
EOF

# 3. 分发配置文件到其他节点
scp /etc/elasticsearch/elasticsearch.yml 10.0.0.102:/etc/elasticsearch/
scp /etc/elasticsearch/elasticsearch.yml 10.0.0.103:/etc/elasticsearch/

# 4. 所有节点启动ES服务
systemctl enable --now elasticsearch

# 5. 效果验证(查看集群节点状态)
curl 10.0.0.101:9200/_cat/nodes  # 显示3个节点信息,*表示主节点
curl 10.0.0.101:9200/_cat/nodes?v  # 显示详细节点状态(堆内存、CPU等)

3.3 二进制方式集群部署(生产推荐)

3.3.1 前置准备(免密登录+同步脚本)

# 1. 所有节点配置主机名解析(主节点10.0.0.101操作)
cat >> /etc/hosts <<'EOF'
10.0.0.101 elk101.oldboya.com
10.0.0.102 elk102.oldboya.com
10.0.0.103 elk103.oldboya.com
EOF

# 2. 主节点生成密钥对(免密登录)
⭐️ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa -q  # -P:空密码,-f:指定私钥路径,-q:静默模式

# 3. 主节点配置所有节点免密登录
for ((host_id=101;host_id<=103;host_id++));do
  ssh-copy-id elk${host_id}.oldboya.com  # 按提示输入节点密码
done

# 4. 所有节点安装rsync(数据同步工具)
ansible all -m yum -a 'name=rsync state=installed'  # 若未安装ansible,可逐节点执行yum命令

# 5. 主节点编写同步脚本(批量同步文件)
⭐️cat > /usr/local/sbin/data_rsync.sh <<'EOF'
#!/bin/bash
# 功能:批量同步文件到集群其他节点
if [ $# -ne 1 ];then
  echo "Usage: $0 /path/to/file(绝对路径)"
  exit 1
fi
if [ ! -e $1 ];then
  echo "[ $1 ] dir or file not find!"
  exit 1
fi
fullpath=$(dirname $1)
basename=$(basename $1)
cd $fullpath
for ((host_id=102;host_id<=103;host_id++))
do
  tput setaf 2
  echo "===== rsyncing elk${host_id}.oldboya.com: $basename ===== "
  tput setaf 7
  rsync -apz $basename $(whoami)@elk${host_id}.oldboya.com:$fullpath
  [ $? -eq 0 ] && echo "命令执行成功!"
done
EOF

# 6. 脚本授权
chmod +x /usr/local/sbin/data_rsync.sh

3.3.2 二进制部署核心步骤

# 1. 主节点下载ES二进制包
curl -o elasticsearch-7.17.5-linux-x86_64.tar.gz http://192.168.15.253/ElasticStack/softwares/binary/elasticsearch-7.17.5-linux-x86_64.tar.gz

# 2. 所有节点创建ES运行用户(避免root启动)
useradd -u 2023 oldboya  # 统一UID,便于权限管理

# 3. 主节点创建工作目录(数据、日志、软件存放路径)
⭐️install -d /oldboya/{data,logs,softwares}/es7 -o oldboya -g oldboya  # -o:指定属主,-g:指定属组

# 4. 主节点解压软件包
tar xf elasticsearch-7.17.5-linux-x86_64.tar.gz -C /oldboya/softwares/es7/

# 5. 主节点修改ES配置文件
⭐️cat > /oldboya/softwares/es7/elasticsearch-7.17.5/config/elasticsearch.yml <<EOF
cluster.name: oldboya-linux85-binary
path.data: /oldboya/data/es7  # 数据目录
path.logs: /oldboya/logs/es7  # 日志目录
network.host: 0.0.0.0
discovery.seed_hosts: ["elk101.oldboya.com","elk102.oldboya.com","elk103.oldboya.com"]
cluster.initial_master_nodes: ["elk101.oldboya.com","elk102.oldboya.com","elk103.oldboya.com"]
EOF

# 6. 主节点同步文件到其他节点
data_rsync.sh /oldboya  # 同步工作目录与软件包
data_rsync.sh /etc/hosts  # 同步主机名解析

# 7. 所有节点系统调优(主节点操作后同步)
# 7.1 调大文件打开限制
cat > /etc/security/limits.d/es7.conf <<EOF
*	soft	nofile	65535
*	hard	nofile	131070
*	hard	nproc	8192
EOF

# 7.2 调大内核虚拟内存映射
cat > /etc/sysctl.d/es.conf <<EOF
vm.max_map_count=524288
EOF

# 7.3 同步调优文件
data_rsync.sh /etc/security/limits.d/es7.conf
data_rsync.sh /etc/sysctl.d/es.conf

# 8. 所有节点生效配置并启动服务
# 8.1 断开当前会话(使文件打开限制生效)
exit

# 8.2 重新登录后生效内核参数
sysctl -f /etc/sysctl.d/es.conf

# 8.3 后台启动ES(普通用户执行)
su oldboya -c '/oldboya/softwares/es7/elasticsearch-7.17.5/bin/elasticsearch -d'  # -d:后台运行

# 9. 效果验证
curl 10.0.0.101:9200  # 验证单节点状态
curl 10.0.0.101:9200/_cat/nodes  # 验证集群节点状态

3.4 ES多实例部署(ES6+ES7共存)

# 前提:已完成二进制ES7部署,JDK环境已配置

# 1. 所有节点创建ES6工作目录
install -d /oldboya/{data,logs,softwares}/es6 -o oldboya -g oldboya

# 2. 主节点下载ES6二进制包
curl -o elasticsearch-6.8.23.tar.gz http://192.168.15.253/ElasticStack/softwares/binary/elasticsearch-6.8.23.tar.gz

# 3. 主节点解压ES6包并授权
tar xf elasticsearch-6.8.23.tar.gz -C /oldboya/softwares/es6/
chown oldboya:oldboya -R /oldboya/softwares/es6/elasticsearch-6.8.23/

# 4. 主节点修改ES6配置文件(区分端口与路径)
⭐️cat > /oldboya/softwares/es6/elasticsearch-6.8.23/config/elasticsearch.yml <<EOF
cluster.name: oldboya-linux85-es6
node.name: elk101.oldboya.com
path.data: /oldboya/data/es6
path.logs: /oldboya/logs/es6
network.host: 0.0.0.0
http.port: 19200  # ES6对外端口(区别于ES7的9200)
transport.tcp.port: 19300  # ES6内部通信端口(区别于ES7的9300)
discovery.zen.ping.unicast.hosts: ["elk101.oldboya.com","elk102.oldboya.com","elk103.oldboya.com"]
discovery.zen.minimum_master_nodes: 2  # ES6最小主节点数(避免脑裂)
EOF

# 5. 主节点修改ES6堆内存(默认1GB,调整为256MB)
sed -i 's/-Xms1g/-Xms256m/' /oldboya/softwares/es6/elasticsearch-6.8.23/config/jvm.options
sed -i 's/-Xmx1g/-Xmx256m/' /oldboya/softwares/es6/elasticsearch-6.8.23/config/jvm.options

# 6. 主节点编写ES6 systemd服务文件
⭐️cat > /usr/lib/systemd/system/es6.service <<EOF
[Unit]
Description=oldboya linux85 es6
After=network.target
[Service]
Type=simple
Environment=JAVA_HOME=/oldboya/softwares/jdk1.8.0_291  # 关联JDK环境
ExecStart=/oldboya/softwares/es6/elasticsearch-6.8.23/bin/elasticsearch
User=oldboya
LimitNOFILE=131070
[Install]
WantedBy=multi-user.target
EOF

# 7. 同步配置到其他节点
data_rsync.sh /oldboya/softwares/es6/
data_rsync.sh /usr/lib/systemd/system/es6.service

# 8. 其他节点修改节点名称(以10.0.0.102为例)
sed -i 's/node.name: elk101.oldboya.com/node.name: elk102.oldboya.com/' /oldboya/softwares/es6/elasticsearch-6.8.23/config/elasticsearch.yml

# 9. 所有节点启动ES6服务
systemctl daemon-reload && systemctl enable --now es6

# 10. 效果验证
curl 10.0.0.101:19200/_cat/nodes  # 查看ES6集群节点状态

3.5 关键补充配置(JDK/堆内存/UUID异常)

3.5.1 JDK环境配置(ES依赖)

# 1. 主节点下载JDK包
curl -o jdk-8u291-linux-x64.tar.gz http://192.168.15.253/ElasticStack/softwares/binary/jdk-8u291-linux-x64.tar.gz

# 2. 解压JDK到工作目录
tar xf jdk-8u291-linux-x64.tar.gz -C /oldboya/softwares/

# 3. 配置系统环境变量
⭐️cat > /etc/profile.d/jdk.sh <<EOF
#!/bin/bash
export JAVA_HOME=/oldboya/softwares/jdk1.8.0_291
export PATH=\$PATH:\$JAVA_HOME/bin
EOF

# 4. 生效环境变量并验证
source /etc/profile.d/jdk.sh
java -version  # 显示jdk1.8.0_291版本即为成功

# 5. 同步JDK环境到其他节点
data_rsync.sh /etc/profile.d/jdk.sh
data_rsync.sh /oldboya/softwares/jdk1.8.0_291

3.5.2 堆内存调整(优化ES性能)

# 1. 主节点修改ES7堆内存配置(以256MB为例)
⭐️sed -i 's/-Xms1g/-Xms256m/' /oldboya/softwares/es7/elasticsearch-7.17.5/config/jvm.options
sed -i 's/-Xmx1g/-Xmx256m/' /oldboya/softwares/es7/elasticsearch-7.17.5/config/jvm.options

# 2. 重启ES7服务
systemctl restart es7

# 3. 验证堆内存大小
jmap -heap $(jps | awk '/Elasticsearch/{print $1}') | grep MaxHeapSize  # 显示268435456(256MB)

# 4. 同步配置到其他节点
data_rsync.sh /oldboya/softwares/es7/elasticsearch-7.17.5/config/jvm.options
其他节点执行:systemctl restart es7

3.5.3 UUID为“na”的处理

# 所有节点执行以下操作
systemctl stop elasticsearch  # 二进制部署用pkill java
rm -rf /var/lib/elasticsearch/* /var/log/elasticsearch/* /tmp/*  # RPM部署路径
# 二进制部署路径:rm -rf /oldboya/data/es7/* /oldboya/logs/es7/* /tmp/*
systemctl start elasticsearch  # 重启服务
curl 10.0.0.101:9200  # 验证UUID是否正常

3.6 ES索引核心操作(CRUD+别名)

3.6.1 查看/创建/修改/删除索引

# 1. 查看所有索引
⭐️curl -X GET 10.0.0.101:9200/_cat/indices

# 2. 创建索引(默认1主分片+1副本)
curl -X PUT 10.0.0.101:9200/oldboya-linux85

# 3. 创建指定主分片的索引(3主分片)
curl -X PUT 10.0.0.101:9200/oldboya-linux86 -H "Content-Type: application/json" -d '{
    "settings":{
        "number_of_shards": 3
    }
}'

# 4. 创建指定主分片+副本的索引(5主分片+2副本)
curl -X PUT 10.0.0.101:9200/oldboya-linux87-003 -H "Content-Type: application/json" -d '{
    "settings":{
        "number_of_shards": 5,
        "number_of_replicas":2
    }
}'

# 5. 修改索引副本数(2→1,主分片不可修改)
curl -X PUT 10.0.0.101:9200/oldboya-linux87-003/_settings -H "Content-Type: application/json" -d '{
    "number_of_replicas": 1
}'

# 6. 删除索引(单个/通配符)
curl -X DELETE 10.0.0.101:9200/oldboya-linux87-003  # 单个
curl -X DELETE 10.0.0.101:9200/oldboya-linux87-*   # 通配符

# 7. 关闭/打开索引
curl -X POST 10.0.0.101:9200/oldboya-linux85/_close
curl -X POST 10.0.0.101:9200/oldboya-linux85/_open

3.6.2 索引别名操作(新增/查看/删除/修改)

# 1. 新增别名(多个索引映射一个别名)
curl -X POST 10.0.0.101:9200/_aliases -H "Content-Type: application/json" -d '{
    "actions": [
        {"add": {"index": "oldboya-linux85", "alias": "Linux2023"}},
        {"add": {"index": "oldboya-linux86", "alias": "Linux2023"}},
        {"add": {"index": "oldboya-linux87", "alias": "Linux2023"}}
    ]
}'

# 2. 查看所有索引别名
⭐️curl -X GET 10.0.0.101:9200/_aliases

# 3. 删除别名
curl -X POST 10.0.0.101:9200/_aliases -H "Content-Type: application/json" -d '{
    "actions": [
        {"remove": {"index": "oldboya-linux87", "alias": "Linux2023"}}
    ]
}'

# 4. 修改别名(先删后加)
curl -X POST 10.0.0.101:9200/_aliases -H "Content-Type: application/json" -d '{
    "actions": [
        {"remove": {"index": "oldboya-linux85", "alias": "DBA"}},
        {"add": {"index": "oldboya-linux85", "alias": "数据库运维工程师"}}
    ]
}'

3.7 ES文档核心操作(CRUD)

# 前提:创建索引oldboya-linux85-student
curl -X PUT 10.0.0.101:9200/oldboya-linux85-student

# 1. 创建文档
# 1.1 不指定文档ID(ES自动生成)
⭐️curl -X POST 10.0.0.101:9200/oldboya-linux85-student/_doc -H "Content-Type: application/json" -d '{
    "name": "李文轩",
    "hobby": ["吃鸡","rap"]
}'

# 1.2 指定文档ID(ID=1001)
curl -X POST 10.0.0.101:9200/oldboya-linux85-student/_doc/1001 -H "Content-Type: application/json" -d '{
    "name": "彭斌北京分斌",
    "hobby": ["浏览网站","熬夜"]
}'

# 2. 修改文档
# 2.1 全量更新(覆盖原有数据,需传入完整文档)
curl -X POST 10.0.0.101:9200/oldboya-linux85-student/_doc/YhF3SocBX1qpvxZ-PePd -H "Content-Type: application/json" -d '{
    "name": "李文轩2023"
}'

# 2.2 局部更新(仅修改指定字段,_update接口)
⭐️curl -X POST 10.0.0.101:9200/oldboya-linux85-student/_doc/1001/_update -H "Content-Type: application/json" -d '{
    "doc":{
        "age":20,
        "hobby":["抽烟","喝酒","烫头"]
    }
}'

# 3. 查看文档(全量查询)
⭐️curl -X GET 10.0.0.101:9200/oldboya-linux85-student/_search

# 4. 删除文档(指定ID)
curl -X DELETE 10.0.0.101:9200/oldboya-linux85-student/_doc/1001

3.8 ES批量操作(_bulk/_mget)

# 1. 批量创建文档(_bulk接口,一行操作+一行数据)
⭐️curl -X POST 10.0.0.101:9200/_bulk -H "Content-Type: application/json" -d '
{ "create": { "_index": "oldboya-linux85-elk"} }
{ "name": "oldboy","hobby":["Linux","思想课"] }
{ "create": { "_index": "oldboya-linux85-elk","_id": 1002} }
{ "name": "振亚老师","hobby":["妹子","吃面"] }
{ "create": { "_index": "oldboya-linux85-elk","_id": 1001} }
{ "name": "苍老师","hobby":["家庭主妇"] }
'

# 2. 批量修改文档
curl -X POST 10.0.0.101:9200/_bulk -H "Content-Type: application/json" -d '
{ "update" : {"_id" : "1001", "_index" : "oldboya-linux85-elk"} }
{ "doc" : {"name" : "CangLaoShi"} }
{ "update" : {"_id" : "1002", "_index" : "oldboya-linux85-elk"} }
{ "doc" : {"name" : "ZhenYaTeacher"} }
'

# 3. 批量查询文档(_mget接口)
curl -X GET 10.0.0.101:9200/_mget -H "Content-Type: application/json" -d '{
  "docs": [
    {"_index": "oldboya-linux85-elk", "_id": "1001"},
    {"_index": "oldboya-linux85-elk", "_id": "1002"}
  ]
}'

# 4. 批量删除文档
curl -X POST 10.0.0.101:9200/_bulk -H "Content-Type: application/json" -d '
{ "delete" : { "_index" : "oldboya-linux85-elk", "_id" : "1001" } }
{ "delete" : { "_index" : "oldboya-linux85-elk", "_id" : "1002" } }
'

3.9 ES映射配置(字段类型定义)

3.9.1 创建索引时指定映射

# 创建索引并指定date类型映射(生日,格式yyyy-MM-dd)
⭐️curl -X PUT 10.0.0.101:9200/oldboya-linux85-date -H "Content-Type: application/json" -d '{
  "mappings": {
    "properties": {
      "birthday": {
        "type":   "date",
        "format": "yyyy-MM-dd"
      }
    }
  }
}'

# 查看索引映射关系
curl -X GET 10.0.0.101:9200/oldboya-linux85-date

3.9.2 为已存在索引添加映射

# 1. 先创建空索引
curl -X PUT 10.0.0.101:9200/oldboya-linux85-elk-2023

# 2. 为已有索引添加多字段类型映射
⭐️curl -X PUT 10.0.0.101:9200/oldboya-linux85-elk-2023/_mapping -H "Content-Type: application/json" -d '{
    "properties": {
        "name": {"type": "text", "index": true},
        "gender": {"type": "keyword", "index": true},
        "province": {"type": "keyword", "index": true},
        "city": {"type": "keyword", "index": false}, # 关闭索引,不可检索
        "email": {"type": "keyword"},
        "ip_addr": {"type": "ip"},
        "birthday": {"type": "date", "format": "yyyy-MM-dd"}
    }
}'

# 3. 写入测试数据
curl -X POST 10.0.0.101:9200/_bulk -H "Content-Type: application/json" -d '
{ "create": { "_index": "oldboya-linux85-elk-2023"}}
{ "name": "吴明昆","gender":"男性的","province":"广西","city":"北海市","email":"[email protected]","ip_addr":"192.168.25.201","birthday":"1999-04-05"}
{ "create": { "_index": "oldboya-linux85-elk-2023"}}
{ "name": "蒋相宇","gender":"女性的","province":"河南","city":"濮阳市","email":"[email protected]","ip_addr":"192.168.15.31","birthday":"2003-09-05"}
'

# 4. 按字段类型检索示例(IP网段查询)
curl -X GET 10.0.0.101:9200/oldboya-linux85-elk-2023/_search -H "Content-Type: application/json" -d '{
    "query": {
        "match" : {
            "ip_addr": "192.168.15.0/24"
        }
    }
}'

3.10 IK中文分词器安装与配置

3.10.1 安装IK分词器(与ES版本一致:7.17.5)

# 1. 创建IK插件目录(所有节点执行)
⭐️mkdir -p /oldboya/softwares/es7/elasticsearch-7.17.5/plugins/ik

# 2. 下载并解压IK分词器(主节点执行,后同步)
cd /oldboya/softwares/es7/elasticsearch-7.17.5/plugins/ik
wget http://192.168.15.253/ElasticStack/day02/softwares/elasticsearch-analysis-ik-7.17.5.zip
unzip elasticsearch-analysis-ik-7.17.5.zip 
rm -f elasticsearch-analysis-ik-7.17.5.zip

# 3. 同步插件到其他节点
data_rsync.sh /oldboya/softwares/es7/elasticsearch-7.17.5/plugins/ik

# 4. 所有节点重启ES服务
systemctl restart es7

# 5. 测试IK分词器
# 5.1 细粒度分词(ik_max_word)
curl -X GET 10.0.0.101:9200/_analyze -H "Content-Type: application/json" -d '{
    "analyzer": "ik_max_word",
    "text": "我爱北京天安门!"
}'

# 5.2 粗粒度分词(ik_smart)
curl -X GET 10.0.0.101:9200/_analyze -H "Content-Type: application/json" -d '{
    "analyzer": "ik_smart",
    "text": "我爱北京天安门!"
}'

3.10.2 自定义IK分词字典

# 1. 进入IK配置目录(所有节点执行)
cd /oldboya/softwares/es7/elasticsearch-7.17.5/plugins/ik/config

# 2. 创建自定义字典(主节点执行)
⭐️cat > oldboya-linux85.dic <<'EOF'
德玛西亚
艾欧尼亚
亚索
上号
带你飞
贼6
EOF

# 3. 加载自定义字典(修改IK配置文件)
sed -i '/<entry key="ext_dict">/c\<entry key="ext_dict">oldboya-linux85.dic</entry>' IKAnalyzer.cfg.xml

# 4. 同步字典与配置文件到其他节点
data_rsync.sh /oldboya/softwares/es7/elasticsearch-7.17.5/plugins/ik/config/oldboya-linux85.dic
data_rsync.sh /oldboya/softwares/es7/elasticsearch-7.17.5/plugins/ik/config/IKAnalyzer.cfg.xml

# 5. 所有节点重启ES,测试自定义分词
systemctl restart es7
curl -X GET 10.0.0.101:9200/_analyze -H "Content-Type: application/json" -d '{
    "analyzer": "ik_smart",
    "text": "嗨,哥们! 上号,我德玛西亚和艾欧尼亚都有号! 我亚索贼6,肯定能带你飞!!!"
}'

3.11 Kibana安装与ES集群集成

# 1. 下载Kibana RPM包(与ES版本一致:7.17.5)
⭐️wget http://192.168.15.253/ElasticStack/day02/softwares/kibana-7.17.5-x86_64.rpm

# 2. 安装Kibana
rpm -ivh kibana-7.17.5-x86_64.rpm

# 3. 修改Kibana核心配置文件
⭐️cat > /etc/kibana/kibana.yml << EOF
server.host: "0.0.0.0"  # 对外暴露访问
elasticsearch.hosts: ["http://10.0.0.101:9200","http://10.0.0.102:9200","http://10.0.0.103:9200"]  # 连接ES集群
i18n.locale: "zh-CN"  # 中文界面
EOF

# 4. 启动Kibana并设置开机自启
systemctl enable --now kibana

# 5. 效果验证
ss -ntl | grep 5601  # 查看5601端口监听
# 浏览器访问:http://10.0.0.103:5601/,进入Kibana中文界面即为成功

3.12 索引模板核心操作(CRUD)

# 前提:准备商品索引基础映射,用于模板配置
# 1. 查看索引模板
# 1.1 查看所有模板
⭐️curl -X GET 10.0.0.103:9200/_template
# 1.2 查看单个模板
curl -X GET 10.0.0.103:9200/_template/.monitoring-es

# 2. 创建/修改索引模板(含别名、匹配规则、分片、映射)
⭐️curl -X POST 10.0.0.103:9200/_template/oldboya-linux85 -H "Content-Type: application/json" -d '{
    "aliases": {
        "DBA": {},
        "SRE": {},
        "K8S": {}
    },
    "index_patterns": ["oldboya-linux85*"],
    "settings": {
        "index": {
            "number_of_shards": 3,
            "number_of_replicas": 0
        }
    },
    "mappings": {
        "properties":{
            "ip_addr": {"type": "ip"},
            "access_time": {"type": "date"},
            "address": {"type" :"text"},
            "name": {"type": "keyword"}
        }
    }
}'

# 3. 验证模板(创建匹配规则的索引,自动套用模板)
curl -X PUT 10.0.0.103:9200/oldboya-linux85-test
curl -X GET 10.0.0.103:9200/oldboya-linux85-test  # 查看是否套用模板配置

# 4. 删除索引模板
curl -X DELETE 10.0.0.103:9200/_template/oldboya-linux85

3.13 DSL基础与高级查询实操

3.13.1 基础准备(创建商品索引+导入测试数据)

# 1. 创建商品索引并配置映射
⭐️curl -X PUT 10.0.0.101:9200/oldboya-linux85-shopping -H "Content-Type: application/json" -d '{
    "mappings": {
        "properties": {
            "item": {"type": "text"},
            "title": {"type": "text"},
            "price": {"type": "double"},
            "type": {"type": "keyword"},
            "group": {"type": "long"},
            "auther": {"type": "text"},
            "birthday": {"type": "date","format": "yyyy-MM-dd"},
            "province": {"type": "keyword"},
            "city": {"type": "keyword"},
            "remote_ip": {"type": "ip"}
        }
    }
}'

# 2. 批量导入测试数据(参考Linux85期商品收集作业.json)
curl -X POST 10.0.0.101:9200/_bulk -H "Content-Type: application/json" --data-binary @Linux85期商品收集作业.json

3.13.2 基础查询(match/match_phrase/match_all)

# 1. 全文检索(match)- 查询彭斌收集的数据
curl -X GET 10.0.0.101:9200/oldboya-linux85-shopping/_search -H "Content-Type: application/json" -d '{
    "query":{
        "match":{"auther":"彭斌"}
    }
}'

# 2. 精准匹配(match_phrase)- 查询张宇杰的数据
curl -X GET 10.0.0.101:9200/oldboya-linux85-shopping/_search -H "Content-Type: application/json" -d '{
    "query":{
        "match_phrase":{"auther":"张宇杰"}
    }
}'

# 3. 全量查询(match_all)
curl -X GET 10.0.0.101:9200/oldboya-linux85-shopping/_search -H "Content-Type: application/json" -d '{
    "query": {"match_all": {}}
}'

3.13.3 辅助查询(分页/_source/exists/高亮)

# 1. 分页查询 - 张宇杰数据,每页3条,第4页(from=(4-1)*3=9)
curl -X GET 10.0.0.101:9200/oldboya-linux85-shopping/_search -H "Content-Type: application/json" -d '{
    "query":{"match_phrase":{"auther":"张宇杰"}},
    "size":3,
    "from":9
}'

# 2. 指定返回字段(_source)- 丘鸿彬数据,仅返回标题/作者/价格
curl -X GET 10.0.0.101:9200/oldboya-linux85-shopping/_search -H "Content-Type: application/json" -d '{
    "query":{"match_phrase":{"auther":"丘鸿彬"}},
    "_source":["title","auther","price"]
}'

# 3. 判断字段存在(exists)- 查询包含hobby字段的文档
curl -X GET 10.0.0.101:9200/oldboya-linux85-shopping/_search -H "Content-Type: application/json" -d '{
    "query": {"exists": {"field": "hobby"}}
}'

# 4. 结果高亮 - 标题包含孙子兵法,红色高亮
curl -X GET 10.0.0.101:9200/oldboya-linux85-shopping/_search -H "Content-Type: application/json" -d '{
    "query": {"match_phrase": {"title": "孙子兵法"}},
    "highlight": {
        "pre_tags": ["<span style='color:red;'>"],
        "post_tags": ["</span>"],
        "fields": {"title": {}}
    }
}'

3.13.4 排序/多条件/过滤/权重查询

# 1. 排序查询 - 于萌数据,按价格升序取最便宜的1个
curl -X GET 10.0.0.101:9200/oldboya-linux85-shopping/_search -H "Content-Type: application/json" -d '{
    "query":{"match_phrase":{"auther":"于萌"}},
    "sort":{"price":{"order": "asc"}},
    "size":1
}'

# 2. 多条件查询(bool)- 于萌且价格24.90
curl -X GET 10.0.0.101:9200/oldboya-linux85-shopping/_search -H "Content-Type: application/json" -d '{
    "query": {
        "bool": {
            "must": [
                {"match_phrase":{"auther": "于萌"}},
                {"match":{"price": 24.90}}
            ]
        }
    }
}'

# 3. 过滤查询(filter)- 3组数据,价格3599-10500,升序取3个
curl -X GET 10.0.0.101:9200/oldboya-linux85-shopping/_search -H "Content-Type: application/json" -d '{
    "query": {
        "bool": {
            "must": [{"match":{"group": 3}}],
            "filter": {
                "range": {"price": {"gte": 3599, "lte": 10500}}
            }
        }
    },
    "sort":{"price":{"order": "asc"}},
    "size":3
}'

# 4. 权重查询(boost)- 小面包,下午茶权重5,良品铺子权重2
curl -X GET 10.0.0.101:9200/oldboya-linux85-shopping/_search -H "Content-Type: application/json" -d '{
    "query": {
        "bool": {
            "must": [{"match": {"title": {"query": "小面包","operator": "and"}}}],
            "should": [
                {"match": {"title": {"query": "下午茶","boost": 5}}},
                {"match": {"title": {"query": "良品铺子","boost": 2}}}
            ]
        }
    },
    "highlight": {
        "pre_tags": ["<h1>"],
        "post_tags": ["</h1>"],
        "fields": {"title": {}}
    }
}'

# 5. 精准多值查询(terms)- 价格9.9和19.9
curl -X GET 10.0.0.101:9200/oldboya-linux85-shopping/_search -H "Content-Type: application/json" -d '{
    "query": {
        "terms": {"price": [9.9,19.9]}
    }
}'

3.14 聚合查询实操

# 1. 分组统计(terms)- 按group统计商品数量
⭐️curl -X GET 10.0.0.101:9200/oldboya-linux85-shopping/_search -H "Content-Type: application/json" -d '{
    "aggs": {
        "group_count": {"terms":{"field": "group"}}
    },
    "size": 0
}'

# 2. 最大值(max)- 2组最贵商品
curl -X GET 10.0.0.101:9200/oldboya-linux85-shopping/_search -H "Content-Type: application/json" -d '{
    "query": {"match":{"group": 2}},
    "aggs": {"max_price": {"max":{"field": "price"}}},
    "sort":{"price":{"order":"desc"}},
    "size":1
}'

# 3. 最小值(min)- 3组最便宜商品
curl -X GET 10.0.0.101:9200/oldboya-linux85-shopping/_search -H "Content-Type: application/json" -d '{
    "query": {"match":{"group": 3}},
    "aggs": {"min_price": {"min":{"field": "price"}}},
    "sort":{"price":{"order":"asc"}},
    "size":1
}'

# 4. 平均值(avg)- 4组商品平均价格
curl -X GET 10.0.0.101:9200/oldboya-linux85-shopping/_search -H "Content-Type: application/json" -d '{
    "query": {"match":{"group": 4}},
    "aggs": {"avg_price": {"avg":{"field": "price"}}},
    "size":0
}'

# 5. 求和(sum)- 5组商品总价
curl -X GET 10.0.0.101:9200/oldboya-linux85-shopping/_search -H "Content-Type: application/json" -d '{
    "query": {"match":{"group":5}},
    "aggs": {"sum_price": {"sum":{"field": "price"}}},
    "size":0
}'

3.15 ES集群数据迁移(同集群/跨集群)

3.15.1 同集群数据迁移(_reindex)

# 将oldboya-linux85-shopping迁移到新索引oldboya-linux85-shopping-new
⭐️curl -X POST 10.0.0.103:9200/_reindex -H "Content-Type: application/json" -d '{
    "source": {"index": "oldboya-linux85-shopping"},
    "dest": {"index": "oldboya-linux85-shopping-new"}
}'

# 验证迁移结果
curl -X GET 10.0.0.103:9200/oldboya-linux85-shopping-new/_search

3.15.2 跨集群数据迁移(ES7←ES6,10.0.0.101:19200为ES6端口)

# 1. 目标集群(ES7)配置远程白名单(所有节点执行)
# 1.1 修改ES配置文件
sed -i '$a reindex.remote.whitelist: "10.0.0.*:19200"' /oldboya/softwares/es7/elasticsearch-7.17.5/config/elasticsearch.yml
# 1.2 同步配置并重启ES
data_rsync.sh /oldboya/softwares/es7/elasticsearch-7.17.5/config/elasticsearch.yml
systemctl restart es7

# 2. 跨集群迁移(过滤age>25的学生数据)
⭐️curl -X POST 10.0.0.103:9200/_reindex -H "Content-Type: application/json" -d '{
    "source": {
        "index": "oldboya-linux85-student",
        "remote": {"host": "http://10.0.0.101:19200"},
        "query": {
            "bool": {
                "filter": {"range": {"age": {"gt": 25}}}
            }
        }
    },
    "dest": {"index": "oldboya-linux85-student-jiaoshi07"}
}'

# 3. 验证迁移结果
curl -X GET 10.0.0.103:9200/oldboya-linux85-student-jiaoshi07/_search

3.16 ES集群核心运维API实操

3.16.1 健康状态API(安装jq工具格式化输出)

# 1. 安装jq工具
yum -y install epel-release && yum -y install jq

# 2. 查看集群健康状态
⭐️curl http://10.0.0.103:9200/_cluster/health 2>/dev/null | jq
# 仅查看健康状态(green/yellow/red)
curl http://10.0.0.103:9200/_cluster/health 2>/dev/null | jq .status
# 仅查看活动分片百分比
curl http://10.0.0.103:9200/_cluster/health 2>/dev/null | jq .active_shards_percent_as_number

3.16.2 集群配置设置API(临时/持久化)

# 1. 查看集群所有配置(含默认配置)
curl -X GET 10.0.0.103:9200/_cluster/settings?include_defaults=true&flat_settings=true | jq

# 2. 设置临时配置(禁止分片分配,重启失效)
⭐️curl -X PUT 10.0.0.103:9200/_cluster/settings -H "Content-Type: application/json" -d '{
    "transient": {"cluster.routing.allocation.enable": "none"}
}'

# 3. 恢复默认配置(开启所有分片分配)
curl -X PUT 10.0.0.103:9200/_cluster/settings -H "Content-Type: application/json" -d '{
    "transient": {"cluster.routing.allocation.enable": "all"}
}'

3.16.3 分片分配/重路由API

# 1. 分析分片未分配原因(分析teacher索引0号主分片)
curl -X GET 10.0.0.101:9200/_cluster/allocation/explain -H "Content-Type: application/json" -d '{
  "index": "teacher",
  "shard": 0,
  "primary": true
}' | jq

# 2. 分片重路由 - 将索引0号分片从elk102移到elk101
⭐️curl -X POST 10.0.0.101:9200/_cluster/reroute -H "Content-Type: application/json" -d '{
    "commands": [
        {
            "move": {
                "index": "oldboya-linux85-student-jiaoshi07",
                "shard": 0,
                "from_node": "elk102.oldboya.com",
                "to_node": "elk101.oldboya.com"
            }
        }
    ]
}'

# 3. 取消分片分配(elk103的0号副本分片)
curl -X POST 10.0.0.101:9200/_cluster/reroute -H "Content-Type: application/json" -d '{
    "commands": [
        {
            "cancel": {
                "index": "oldboya-linux85-student-jiaoshi07",
                "shard": 0,
                "node": "elk103.oldboya.com"
            }
        }
    ]
}'

3.16.4 集群状态/统计API

# 1. 查看集群状态(节点+索引元数据+分片路由)
curl -X GET 10.0.0.103:9200/_cluster/state | jq
# 仅查看节点信息
curl -X GET 10.0.0.103:9200/_cluster/state/nodes | jq

# 2. 查看集群统计信息(节点/索引/存储/插件)
⭐️curl -X GET 10.0.0.103:9200/_cluster/stats | jq

四、原理说明

4.1 ES端口通信原理

  • 9200端口:基于HTTP协议,面向外部客户端提供服务,支持RESTful API调用(如查询集群状态、索引操作),是ES与外部系统交互的核心端口;
  • 9300端口:基于TCP协议,面向集群内部节点,用于节点间的数据同步、分片复制、主节点选举等通信,集群节点必须开放此端口才能正常加入集群。

4.2 ES集群主节点选举原理

  • ES7+集群通过cluster.initial_master_nodes指定候选主节点,选举时需满足“多数派原则”(候选节点数的一半以上存活);
  • 主节点负责集群元数据管理(如索引创建、分片分配),数据节点负责数据存储与查询,候选节点默认同时具备主节点和数据节点角色;
  • ES6集群通过discovery.zen.minimum_master_nodes指定最小主节点数,避免集群分裂(脑裂),建议设置为“候选主节点数/2 + 1”。

4.3 系统权限与资源限制原理

  • ES禁止root用户启动,因root权限过高可能导致误操作,且ES内置安全机制限制root运行,普通用户需拥有工作目录的读写权限;
  • 文件打开限制(nofile):ES运行时需同时打开大量文件(索引分片、日志文件等),默认4096过小会导致启动失败,需调至65535以上;
  • 内核虚拟内存(vm.max_map_count):ES使用Lucene作为底层索引引擎,需大量虚拟内存映射文件,默认65530过小会触发启动校验失败,需调至524288以上。

4.4 堆内存配置原理

  • ES堆内存用于存储索引元数据、查询缓存等,-Xms(初始堆)与-Xmx(最大堆)需设置一致,避免运行时内存扩容/缩容导致性能波动;
  • 堆内存建议不超过物理内存的50%,剩余内存留给操作系统缓存文件系统数据,同时最大不超过32GB(JVM在32GB以上内存会启用压缩指针失效,性能下降)。

4.5 分片与副本工作原理

  • 分片:将单个索引的海量数据拆分为多个分片,分布式存储在集群不同节点,实现水平扩容,提升ES的存储和查询性能;主分片数量在索引创建时指定,创建后不可修改
  • 副本:主分片的冗余备份,存储在与主分片不同的节点,提升集群的高可用性;副本数可随时修改,主分片故障时,副本分片会被自动选举为新的主分片;
  • 文档写入仅会发送到主分片,再由主分片同步到所有副本分片;文档查询可在主分片或副本分片执行,实现读负载均衡。

4.6 文档分片路由原理

文档写入时会根据文档ID计算确定对应的主分片,计算公式为:hash(文档ID) % 主分片数量

  • 若指定文档ID,ES会通过公式直接计算分片位置,确保文档固定存储在某一分片;
  • 若未指定文档ID,ES会自动生成唯一ID,再通过公式计算分片位置,保证数据均匀分布在各分片。

4.7 分词器工作原理

  • standard分词器:按空格、标点符号拆分文本,中文按单字拆分,无语义分析能力,仅适用于英文;
  • IK分词器:基于中文语料库实现语义拆分,通过词典匹配将中文拆分为有意义的词语,支持细粒度(ik_max_word)和粗粒度(ik_smart)两种分词模式;
  • 自定义字典:通过添加自定义词汇到IK词典,让分词器识别行业专属词汇、网络词汇等,提升中文分词的准确性。

4.8 映射与字段类型原理

  • 映射(Mapping):定义索引的字段名称、数据类型、检索规则的配置,类比关系型数据库的表结构
  • text与keyword区别:text类型会进行分词处理,支持全文检索;keyword类型不分词,仅支持精准匹配,适合聚合分析和筛选;
  • index: false:设置该字段不创建索引,无法通过DSL查询检索,仅用于存储数据,节省ES的索引存储空间。

4.9 索引模板工作原理

  • 索引模板是预配置的索引规则集,包含别名、分片副本、映射等配置,通过index_patterns配置匹配规则(支持通配符);
  • 当创建符合匹配规则的新索引时,ES会自动将模板的配置套用至新索引,实现索引创建的标准化;
  • 模板仅在索引创建时生效,修改模板配置后,已创建的索引不会受到影响,如需生效需重建索引。

4.10 DSL查询匹配原理

  • match查询:对检索词进行分词后,匹配文档中任意分词结果,属于全文检索,会计算文档与检索词的相关性得分,得分越高排名越靠前;
  • match_phrase查询:对检索词分词后,按顺序精准匹配文档中的连续分词结果,无分词顺序错乱的情况,适用于精准短语检索;
  • match_all查询:全量扫描索引中的所有文档,不计算相关性得分,适用于无过滤条件的全量数据查询,性能随文档量增加而下降;
  • bool多条件查询:通过must/should/must_not/filter实现多条件逻辑组合,其中must(必须匹配)、should(至少匹配一个)会计算相关性得分,must_not(必须不匹配)、filter(过滤匹配)不计算相关性得分,且filter会缓存过滤结果,重复查询时性能远高于must
  • terms查询:对非分词字段进行多值精准匹配,相当于SQL的in语句,仅适用于keyword/ip/long等不分词字段。

4.11 聚合查询原理

ES聚合查询分为桶聚合(Bucket Aggregation)指标聚合(Metric Aggregation),执行逻辑为先过滤,后聚合

  1. 先通过query中的条件过滤出符合要求的文档;
  2. 对过滤后的文档执行桶聚合,按指定字段将数据划分为多个“桶”(类比SQL的group by);
  3. 对每个桶内的文档执行指标聚合,计算max/min/avg/sum等统计指标;
  • 配置"size": 0可关闭原始文档的返回,仅返回聚合统计结果,大幅提升聚合查询性能;
  • 聚合查询仅支持不分词字段(如keyword/long/double),text字段需开启字段映射的fielddata才能聚合,生产环境不建议使用。

4.12 集群数据迁移(_reindex)原理

_reindex是ES基于拉取模式实现的数据迁移接口,核心原理为源索引拉取文档→目标索引写入文档,支持同集群和跨集群迁移:

  • 同集群迁移:直接拉取本地集群源索引的文档,按分片路由规则写入目标索引,无需额外配置;
  • 跨集群迁移:目标集群需从源集群拉取数据,因此需在目标集群配置reindex.remote.whitelist指定源集群的IP和端口,做白名单授权,避免未授权的远程数据访问;
  • 迁移过程中支持通过query条件过滤需要迁移的文档,实现增量迁移,且不影响源索引的正常读写。

4.13 分片分配与重路由原理

  • 自动分片分配:ES默认开启自动分片分配,集群会根据节点数量、节点负载、分片规则,自动将主分片和副本分片分配到不同节点,保证数据高可用和负载均衡;
  • 手动分片重路由(reroute):用于节点维护、人工负载均衡、分片异常修复等特殊场景,支持move(移动分片)、cancel(取消分片分配)两种核心操作,仅改变分片的物理存储节点,不修改分片内的文档数据,操作后集群会自动同步分片元数据;
  • 分片分配的核心约束:同一分片的主分片和副本分片不能存储在同一个节点,避免节点故障导致数据丢失。

4.14 集群配置优先级原理

ES的集群配置会按高优先级覆盖低优先级的规则生效,所有配置最终存储在集群状态中,供所有节点同步:

  • Transient(临时配置):配置后立即生效,存储在集群内存的状态中,集群重启后立即失效,适用于节点维护、临时调试等短期场景;
  • Persistent(持久化配置):配置后立即生效,存储在集群的持久化状态中,集群重启后依旧生效,适用于长期的集群配置调整;
  • elasticsearch.yml(本地配置):节点级的本地配置文件,仅对当前节点生效,若与集群级配置(Transient/Persistent)冲突,会被集群级配置覆盖;
  • Default(默认配置):ES内置的默认配置,未做任何手动配置时启用,是所有配置的兜底规则。

五、注意事项

  1. 索引模板生效规则:索引模板仅在新索引创建时生效,修改模板后不影响已创建的索引,如需让已有索引套用新模板,需重建索引;
  2. DSL查询字段适配match/match_phrase适用于text分词字段,terms/filter适用于keyword/ip/long等不分词字段,避免用text字段做精准匹配和聚合;
  3. 跨集群迁移配置:跨集群迁移时,仅需在目标集群配置远程白名单,源集群无需额外配置,且白名单支持通配符(如10.0.0.*:19200);
  4. 分片操作约束:手动重路由分片时,需确保目标节点有足够的磁盘空间和内存,且同一分片的主副分片不能分配到同一节点;
  5. 集群配置操作:修改cluster.routing.allocation.enablenone后,集群会停止所有分片分配,节点维护完成后需及时恢复为all,避免新索引无法创建分片;
  6. 聚合查询优化:聚合查询务必指定过滤条件,且仅对不分词字段做聚合,同时设置size:0关闭原始文档返回,提升查询性能;
  7. 深度分页限制:生产环境避免使用from+size做深度分页(如页码大于100),深度分页会导致ES扫描大量无关文档,性能急剧下降,建议使用scrollsearch_after
  8. _bulk操作规范_bulk批量操作要求一行操作指令+一行数据,且最后一行必须换行,同时控制单批次操作的文档数量(建议1000条以内),避免内存溢出。

六、结尾

总结

本文完成了ElasticSearch从基础部署搭建企业级集群运维的全知识体系覆盖,核心分为五大模块:

  1. 部署模块:包含RPM单点/集群、二进制集群、ES6/ES7多实例三种部署方式,配套JDK配置、系统调优、systemd服务管理,是ES集群运行的基础;
  2. 基础操作模块:涵盖索引/文档/别名的CRUD、批量操作、映射配置、IK中文分词器与Kibana集成,实现ES的基础数据管理和可视化操作;
  3. 高级查询模块:详解DSL基础查询、分页/排序/高亮/多条件查询、权重查询、过滤查询,以及terms多值查询,覆盖所有业务检索场景;
  4. 统计分析模块:讲解ES聚合查询的核心用法,包括桶聚合和指标聚合,实现对ES数据的统计分析,满足业务报表、数据监控等需求;
  5. 集群运维模块:新增索引模板、集群数据迁移(同集群/跨集群)、集群全量运维API、分片分配与重路由、集群配置优先级,覆盖生产环境ES集群的日常运维、故障修复、数据迁移等核心工作。

从基础到进阶,从操作到原理,形成了一套完整的ES实战体系,可直接应用于Linux运维的ES集群部署、操作与运维工作。

避坑指南(核心坑点+解决方案)

  1. 坑点:创建索引后想修改主分片数量,执行指令后报错;解决方案:主分片数量在索引创建时指定,创建后不可修改,需提前根据业务数据量规划,若需调整需删除原有索引重新创建;
  2. 坑点:用text字段做聚合查询,执行后提示字段不可聚合;解决方案:聚合查询仅支持不分词字段,将text字段改为keyword,或为text字段添加keyword子字段(如"title.keyword");
  3. 坑点:跨集群迁移数据时,提示“remote host is not whitelisted”;解决方案:在目标集群的elasticsearch.yml中配置reindex.remote.whitelist,添加源集群的IP和端口,重启ES后再执行迁移;
  4. 坑点:使用from+size做深度分页,页码过大时查询超时;解决方案:生产环境替换为search_after分页方式,基于上一页的最后一条文档的排序值做分页,避免全量扫描文档;
  5. 坑点:修改filter过滤条件后,查询结果未更新;解决方案:ES会缓存filter的过滤结果,若底层数据发生变化,可通过刷新索引(_refresh)或等待缓存过期,也可手动清除缓存;
  6. 坑点:手动重路由分片后,集群状态变为yellow;解决方案:检查副本分片是否未分配,若因节点数量不足导致副本无法分配,可临时减少副本数,或添加新节点后重新开启自动分片分配;
  7. 坑点:创建索引模板后,新索引未套用模板配置;解决方案:检查模板的index_patterns匹配规则是否与新索引名称一致(通配符是否正确),且模板创建需在索引创建之前执行;
  8. 坑点:执行_bulk批量操作时,提示“parse_exception”格式错误;解决方案:确保_bulk数据为“一行操作+一行数据”的格式,且最后一行必须换行,同时保证Content-Type为application/json
posted @ 2026-03-16 22:45  gzjwo  阅读(5)  评论(0)    收藏  举报