Elasticsearch 概述与安装
学习目标
- 理解 Elasticsearch 的核心价值和应用场景
- 掌握 Elasticsearch 的安装和基本配置
- 了解 Elasticsearch 的基本架构
- 能够启动和验证 Elasticsearch 服务
一、为什么需要 Elasticsearch?
1.1 传统数据库的搜索痛点
假设你在开发一个电商系统,用户搜索"华为手机":
sql
-- MySQL 的模糊查询
SELECT * FROM product
WHERE name LIKE '%华为%' AND name LIKE '%手机%';
问题:
- ❌ 性能差:LIKE 查询无法使用索引,全表扫描
- ❌ 功能弱:无法处理同义词("手机" vs "移动电话")
- ❌ 不智能:无法按相关性排序
- ❌ 无分词:搜索"华为手机"无法匹配"华为 Mate 50 智能手机"
1.2 Elasticsearch 如何解决?
用户输入:"华为手机"
↓
分词处理
↓
["华为", "手机"]
↓
倒排索引查询(毫秒级)
↓
相关性评分排序
↓
返回最匹配的结果
优势:
- ✓ 快速:基于倒排索引,搜索速度快
- ✓ 智能:支持分词、同义词、拼音搜索
- ✓ 相关性:自动按匹配度排序
- ✓ 分布式:天然支持海量数据
二、核心概念
2.1 Elasticsearch vs MySQL(基于 ES 8.x)
重要变化:ES 7.x 后完全移除了 Type 概念!
| 概念 | MySQL | Elasticsearch 8.x | 说明 |
|---|---|---|---|
| 数据库 | Database | Index(索引) | 存储数据的容器 |
| 表 | Table | Type(已废弃) | ES 7.x+ 已完全移除 |
| 行 | Row | Document(文档) | 一条数据记录 |
| 列 | Column | Field(字段) | 数据的属性 |
| 主键 | Primary Key | _id | 文档唯一标识 |
| 索引 | Index | 倒排索引 | 加速查询的数据结构 |
| Schema | Schema | Mapping | 字段定义和类型 |
版本演进:
Elasticsearch 6.x 及之前:
Index → Type → Document
products → phone → doc1
products → tablet → doc2
❌ 问题:不同 Type 的相同字段必须有相同映射
Elasticsearch 7.x:
Index → Document(Type 标记为废弃)
products → doc1
products → doc2
⚠️ 过渡期:仍支持 _doc,但不推荐
Elasticsearch 8.x(当前版本):
Index → Document(Type 完全移除)
products → doc1
products → doc2
✓ 简化:一个索引只存储一种类型的文档
示例对比(ES 8.x):
MySQL 数据库设计:
┌─────────────────────────────────────┐
│ Database: shop │
├─────────────────────────────────────┤
│ Table: products │
│ +----+----------+-------+ │
│ | id | name | price | │
│ +----+----------+-------+ │
│ | 1 | 华为手机 | 3999 | │
│ | 2 | 小米手机 | 2999 | │
│ +----+----------+-------+ │
└─────────────────────────────────────┘
Elasticsearch 8.x 索引设计:
┌─────────────────────────────────────┐
│ Index: products │
├─────────────────────────────────────┤
│ Document 1: │
│ { │
│ "_index": "products", │
│ "_id": "1", │
│ "_source": { │
│ "name": "华为手机", │
│ "price": 3999 │
│ } │
│ } │
│ │
│ Document 2: │
│ { │
│ "_index": "products", │
│ "_id": "2", │
│ "_source": { │
│ "name": "小米手机", │
│ "price": 2999 │
│ } │
│ } │
└─────────────────────────────────────┘
API 对比(ES 8.x):
bash
# MySQL
INSERT INTO products (id, name, price) VALUES (1, '华为手机', 3999);
SELECT * FROM products WHERE id = 1;
UPDATE products SET price = 3899 WHERE id = 1;
DELETE FROM products WHERE id = 1;
# Elasticsearch 8.x(注意:不再使用 _doc)
PUT /products/_doc/1
{
"name": "华为手机",
"price": 3999
}
GET /products/_doc/1
POST /products/_update/1
{
"doc": {
"price": 3899
}
}
DELETE /products/_doc/1
为什么 ES 8.x 移除了 Type?
问题 1:映射冲突
products/phone: { "name": "text" }
products/tablet: { "name": "keyword" }
❌ 错误!同一索引中的相同字段必须有相同类型
问题 2:稀疏存储
products/phone: { "name", "price", "network" }
products/tablet: { "name", "price", "screenSize" }
❌ 浪费空间!每个文档都要存储所有字段的映射
问题 3:性能问题
查询 products/phone 时,仍需要扫描所有文档
❌ 无法真正隔离不同类型的数据
解决方案(ES 8.x):
✓ 为不同类型创建不同索引
✓ products_phone、products_tablet
✓ 或使用字段区分:{ "type": "phone" }
迁移建议(从旧版本升级):
bash
# 旧版本(ES 6.x)
PUT /products/phone/1
{
"name": "华为手机"
}
# 新版本(ES 8.x)- 方案 1:分离索引
PUT /products_phone/_doc/1
{
"name": "华为手机"
}
PUT /products_tablet/_doc/2
{
"name": "iPad"
}
# 新版本(ES 8.x)- 方案 2:使用字段区分
PUT /products/_doc/1
{
"type": "phone",
"name": "华为手机"
}
PUT /products/_doc/2
{
"type": "tablet",
"name": "iPad"
}
2.2 倒排索引原理
正排索引(MySQL):
文档ID → 内容
1 → "华为手机"
2 → "小米手机"
3 → "华为平板"
查询"华为"需要遍历所有文档 ❌
倒排索引(Elasticsearch):
词条 → 文档ID列表
华为 → [1, 3]
手机 → [1, 2]
小米 → [2]
平板 → [3]
查询"华为"直接定位到文档 1 和 3 ✓
2.3 核心架构
┌─────────────────────────────────────────────────────────┐
│ Elasticsearch 集群 │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Node 1 │ │ Node 2 │ │ Node 3 │ │
│ │ (主节点) │ │ (数据) │ │ (数据) │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ ↓ ↓ ↓ │
│ ┌─────────────────────────────────────┐ │
│ │ Index (索引) │ │
│ ├─────────────────────────────────────┤ │
│ │ Shard 0 │ Shard 1 │ Shard 2 │ (主分片) │
│ │ Replica │ Replica │ Replica │ (副本分片) │
│ └─────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
关键概念:
- Cluster(集群):多个节点组成的整体
- Node(节点):一个 Elasticsearch 实例
- Shard(分片):索引的数据分片,支持水平扩展
- Replica(副本):分片的备份,提高可用性
三、安装 Elasticsearch
3.1 环境要求
- Java 17 或更高版本
- 至少 4GB 内存
- 操作系统:Windows/Linux/macOS
3.2 Windows 系统安装
3.2.1 下载安装包
步骤 1:下载
访问:https://www.elastic.co/downloads/elasticsearch
下载:elasticsearch-8.x.x-windows-x86_64.zip
步骤 2:解压
powershell
# 解压到指定目录
Expand-Archive elasticsearch-8.x.x-windows-x86_64.zip -DestinationPath C:\elasticsearch
3.2.2 目录结构说明
elasticsearch-8.x.x/
├── bin/ # 可执行文件
│ ├── elasticsearch.bat # Windows 启动脚本
│ ├── elasticsearch # Linux 启动脚本
│ └── elasticsearch-plugin # 插件管理工具
├── config/ # 配置文件
│ ├── elasticsearch.yml # 主配置文件
│ ├── jvm.options # JVM 配置
│ └── log4j2.properties # 日志配置
├── data/ # 数据目录(自动创建)
├── logs/ # 日志目录(自动创建)
├── lib/ # 依赖库
├── modules/ # 模块
└── plugins/ # 插件目录
3.2.3 启动服务
步骤 3:启动
powershell
cd C:\elasticsearch\elasticsearch-8.x.x\bin
.\elasticsearch.bat
首次启动会输出:
✅ Elasticsearch security features have been automatically configured!
✅ Authentication is enabled and cluster connections are encrypted.
ℹ️ Password for the elastic user: <自动生成的密码>
ℹ️ HTTP CA certificate SHA-256 fingerprint: <指纹>
ℹ️ Configure Kibana to use this cluster:
• Run Kibana and click the configuration link in the terminal when Kibana starts.
• Copy the following enrollment token and paste it into Kibana in your browser:
<enrollment-token>
⚠️ 重要:保存这些信息!
- elastic 用户密码
- CA 证书指纹
- Kibana 注册令牌
3.2.4 配置为 Windows 服务
安装服务:
powershell
# 以管理员身份运行
cd C:\elasticsearch\elasticsearch-8.x.x\bin
.\elasticsearch-service.bat install
启动服务:
powershell
.\elasticsearch-service.bat start
停止服务:
powershell
.\elasticsearch-service.bat stop
卸载服务:
powershell
.\elasticsearch-service.bat remove
3.3 Linux 系统安装
3.3.1 使用 tar.gz 包安装(推荐)
步骤 1:下载
bash
# 下载 Elasticsearch
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.11.0-linux-x86_64.tar.gz
# 下载校验文件
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.11.0-linux-x86_64.tar.gz.sha512
步骤 2:校验文件完整性
bash
# 校验下载的文件
shasum -a 512 -c elasticsearch-8.11.0-linux-x86_64.tar.gz.sha512
# 输出应该是:
# elasticsearch-8.11.0-linux-x86_64.tar.gz: OK
步骤 3:解压
bash
# 解压到 /opt 目录
sudo tar -xzf elasticsearch-8.11.0-linux-x86_64.tar.gz -C /opt/
# 创建软链接(方便版本管理)
sudo ln -s /opt/elasticsearch-8.11.0 /opt/elasticsearch
步骤 4:创建专用用户
bash
# Elasticsearch 不能以 root 用户运行
sudo useradd -m -s /bin/bash elasticsearch
# 设置目录权限
sudo chown -R elasticsearch:elasticsearch /opt/elasticsearch-8.11.0
步骤 5:配置系统参数
编辑 /etc/security/limits.conf:
bash
sudo vim /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 unlimited
编辑 /etc/sysctl.conf:
bash
sudo vim /etc/sysctl.conf
# 添加以下内容
vm.max_map_count=262144
vm.swappiness=1
# 使配置生效
sudo sysctl -p
为什么需要这些配置?
vm.max_map_count:Elasticsearch 使用大量的内存映射文件
vm.swappiness:减少使用交换分区,提高性能
nofile:增加文件描述符限制
memlock:允许锁定内存,防止被交换到磁盘
步骤 6:启动服务
bash
# 切换到 elasticsearch 用户
sudo su - elasticsearch
# 启动 Elasticsearch
cd /opt/elasticsearch
./bin/elasticsearch
首次启动输出:
✅ Elasticsearch security features have been automatically configured!
✅ Authentication is enabled and cluster connections are encrypted.
ℹ️ Password for the elastic user (reset with `bin/elasticsearch-reset-password -u elastic`):
lhQpLELkjkrawaFlwkjflkjwlkfjlwkjflkwjflkwjf
ℹ️ HTTP CA certificate SHA-256 fingerprint:
a52931d7d23e5695d0b7c4c6e4b3c2d1a52931d7d23e5695d0b7c4c6e4b3c2d1
ℹ️ Configure Kibana to use this cluster:
• Run Kibana and click the configuration link in the terminal when Kibana starts.
• Copy the following enrollment token and paste it into Kibana in your browser (valid for the next 30 minutes):
eyJ2ZXIiOiI4LjExLjAiLCJhZHIiOlsiMTkyLjE2OC4xLjEwMDo5MjAwIl0sImZnciI6ImE1MjkzMWQ3ZDIzZTU2OTVkMGI3YzRjNmU0YjNjMmQxYTUyOTMxZDdkMjNlNTY5NWQwYjdjNGM2ZTRiM2MyZDEiLCJrZXkiOiJYbHhYWW9zQkRWemRVWVZsTVRsdjpQdGFjc0RGRlFsS3VhYmNkZWZnaGlqIn0=
ℹ️ Configure other nodes to join this cluster:
• Copy the following enrollment token and start new Elasticsearch nodes with `bin/elasticsearch --enrollment-token <token>` (valid for the next 30 minutes):
eyJ2ZXIiOiI4LjExLjAiLCJhZHIiOlsiMTkyLjE2OC4xLjEwMDo5MjAwIl0sImZnciI6ImE1MjkzMWQ3ZDIzZTU2OTVkMGI3YzRjNmU0YjNjMmQxYTUyOTMxZDdkMjNlNTY5NWQwYjdjNGM2ZTRiM2MyZDEiLCJrZXkiOiJYMXhYWW9zQkRWemRVWVZsTVRsdzpQdGFjc0RGRlFsS3VhYmNkZWZnaGlrIn0=
If you're running in Docker, copy the enrollment token and run:
`docker run -e "ENROLLMENT_TOKEN=<token>" docker.elastic.co/elasticsearch/elasticsearch:8.11.0`
⚠️ 重要:立即保存这些信息到安全的地方!
3.3.2 后台运行
方法 1:使用 nohup
bash
nohup ./bin/elasticsearch > /dev/null 2>&1 &
# 查看进程
ps aux | grep elasticsearch
# 停止服务
pkill -f elasticsearch
方法 2:配置 systemd 服务(推荐)
创建服务文件:
bash
sudo vim /etc/systemd/system/elasticsearch.service
添加以下内容:
ini
[Unit]
Description=Elasticsearch
Documentation=https://www.elastic.co
Wants=network-online.target
After=network-online.target
[Service]
Type=notify
RuntimeDirectory=elasticsearch
PrivateTmp=true
Environment=ES_HOME=/opt/elasticsearch
Environment=ES_PATH_CONF=/opt/elasticsearch/config
Environment=PID_DIR=/var/run/elasticsearch
Environment=ES_SD_NOTIFY=true
EnvironmentFile=-/etc/default/elasticsearch
WorkingDirectory=/opt/elasticsearch
User=elasticsearch
Group=elasticsearch
ExecStart=/opt/elasticsearch/bin/elasticsearch
# 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.
StandardOutput=journal
StandardError=inherit
# Specifies the maximum file descriptor number that can be opened by this process
LimitNOFILE=65535
# Specifies the maximum number of processes
LimitNPROC=4096
# Specifies the maximum size of virtual memory
LimitAS=infinity
# Specifies the maximum file size
LimitFSIZE=infinity
# Disable timeout logic and wait until process is stopped
TimeoutStopSec=0
# SIGTERM signal is used to stop the Java process
KillSignal=SIGTERM
# Send the signal only to the JVM rather than its control group
KillMode=process
# Java process is never killed
SendSIGKILL=no
# When a JVM receives a SIGTERM signal it exits with code 143
SuccessExitStatus=143
# Allow a slow startup before the systemd notifier module kicks in to extend the timeout
TimeoutStartSec=900
[Install]
WantedBy=multi-user.target
启用并启动服务:
bash
# 重新加载 systemd 配置
sudo systemctl daemon-reload
# 启用开机自启
sudo systemctl enable elasticsearch
# 启动服务
sudo systemctl start elasticsearch
# 查看状态
sudo systemctl status elasticsearch
# 查看日志
sudo journalctl -u elasticsearch -f
服务管理命令:
bash
# 启动
sudo systemctl start elasticsearch
# 停止
sudo systemctl stop elasticsearch
# 重启
sudo systemctl restart elasticsearch
# 查看状态
sudo systemctl status elasticsearch
# 禁用开机自启
sudo systemctl disable elasticsearch
3.3.3 使用 RPM 包安装(CentOS/RHEL)
步骤 1:导入 GPG 密钥
bash
sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
步骤 2:创建 yum 仓库
bash
sudo vim /etc/yum.repos.d/elasticsearch.repo
添加以下内容:
ini
[elasticsearch]
name=Elasticsearch repository for 8.x packages
baseurl=https://artifacts.elastic.co/packages/8.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=0
autorefresh=1
type=rpm-md
步骤 3:安装
bash
sudo yum install --enablerepo=elasticsearch elasticsearch
步骤 4:配置系统参数
bash
# 编辑 /etc/security/limits.conf
sudo vim /etc/security/limits.conf
# 添加
elasticsearch soft nofile 65536
elasticsearch hard nofile 65536
# 编辑 /etc/sysctl.conf
sudo vim /etc/sysctl.conf
# 添加
vm.max_map_count=262144
# 使配置生效
sudo sysctl -p
步骤 5:启动服务
bash
# 启用开机自启
sudo systemctl enable elasticsearch
# 启动服务
sudo systemctl start elasticsearch
# 查看状态
sudo systemctl status elasticsearch
RPM 安装的目录结构:
/etc/elasticsearch/ # 配置文件
/usr/share/elasticsearch/ # 程序文件
/var/lib/elasticsearch/ # 数据目录
/var/log/elasticsearch/ # 日志目录
3.3.4 使用 DEB 包安装(Ubuntu/Debian)
步骤 1:导入 GPG 密钥
bash
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
步骤 2:安装 apt-transport-https
bash
sudo apt-get install apt-transport-https
步骤 3:添加 APT 仓库
bash
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
步骤 4:安装
bash
sudo apt-get update
sudo apt-get install elasticsearch
步骤 5:配置系统参数
bash
# 编辑 /etc/security/limits.conf
sudo vim /etc/security/limits.conf
# 添加
elasticsearch soft nofile 65536
elasticsearch hard nofile 65536
# 编辑 /etc/sysctl.conf
sudo vim /etc/sysctl.conf
# 添加
vm.max_map_count=262144
# 使配置生效
sudo sysctl -p
步骤 6:启动服务
bash
# 启用开机自启
sudo systemctl enable elasticsearch
# 启动服务
sudo systemctl start elasticsearch
# 查看状态
sudo systemctl status elasticsearch
3.3.5 Docker 安装(推荐用于开发环境)
单节点模式:
bash
# 拉取镜像
docker pull docker.elastic.co/elasticsearch/elasticsearch:8.11.0
# 运行容器
docker run -d \
--name elasticsearch \
-p 9200:9200 \
-p 9300:9300 \
-e "discovery.type=single-node" \
-e "xpack.security.enabled=false" \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
docker.elastic.co/elasticsearch/elasticsearch:8.11.0
# 查看日志
docker logs -f elasticsearch
使用 Docker Compose:
创建 docker-compose.yml:
yaml
version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.11.0
container_name: elasticsearch
environment:
- discovery.type=single-node
- xpack.security.enabled=false
- "ES_JAVA_OPTS=-Xms1g -Xmx1g"
ports:
- "9200:9200"
- "9300:9300"
volumes:
- es-data:/usr/share/elasticsearch/data
networks:
- elastic
kibana:
image: docker.elastic.co/kibana/kibana:8.11.0
container_name: kibana
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
ports:
- "5601:5601"
depends_on:
- elasticsearch
networks:
- elastic
volumes:
es-data:
driver: local
networks:
elastic:
driver: bridge
启动:
bash
docker-compose up -d
# 查看日志
docker-compose logs -f
# 停止
docker-compose down
# 停止并删除数据
docker-compose down -v
Docker 集群模式:
创建 docker-compose-cluster.yml:
yaml
version: '3.8'
services:
es01:
image: docker.elastic.co/elasticsearch/elasticsearch:8.11.0
container_name: es01
environment:
- node.name=es01
- cluster.name=es-cluster
- discovery.seed_hosts=es02,es03
- cluster.initial_master_nodes=es01,es02,es03
- xpack.security.enabled=false
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ports:
- "9200:9200"
volumes:
- es01-data:/usr/share/elasticsearch/data
networks:
- elastic
es02:
image: docker.elastic.co/elasticsearch/elasticsearch:8.11.0
container_name: es02
environment:
- node.name=es02
- cluster.name=es-cluster
- discovery.seed_hosts=es01,es03
- cluster.initial_master_nodes=es01,es02,es03
- xpack.security.enabled=false
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
volumes:
- es02-data:/usr/share/elasticsearch/data
networks:
- elastic
es03:
image: docker.elastic.co/elasticsearch/elasticsearch:8.11.0
container_name: es03
environment:
- node.name=es03
- cluster.name=es-cluster
- discovery.seed_hosts=es01,es02
- cluster.initial_master_nodes=es01,es02,es03
- xpack.security.enabled=false
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
volumes:
- es03-data:/usr/share/elasticsearch/data
networks:
- elastic
volumes:
es01-data:
es02-data:
es03-data:
networks:
elastic:
driver: bridge
启动集群:
bash
docker-compose -f docker-compose-cluster.yml up -d
# 查看集群状态
curl http://localhost:9200/_cluster/health?pretty
3.3 验证安装
方法 1:浏览器访问
https://localhost:9200
输入用户名 elastic 和刚才保存的密码
方法 2:curl 命令
bash
curl -k -u elastic:你的密码 https://localhost:9200
成功响应:
json
{
"name" : "node-1",
"cluster_name" : "elasticsearch",
"version" : {
"number" : "8.11.0"
},
"tagline" : "You Know, for Search"
}
3.4 安装 Kibana(可选但推荐)
Kibana 是 Elasticsearch 的可视化工具,提供了强大的数据探索和可视化功能。
3.4.1 Windows 安装 Kibana
步骤 1:下载
访问:https://www.elastic.co/downloads/kibana
下载:kibana-8.x.x-windows-x86_64.zip
步骤 2:解压
powershell
Expand-Archive kibana-8.x.x-windows-x86_64.zip -DestinationPath C:\kibana
步骤 3:配置 Kibana
编辑 config/kibana.yml:
yaml
# Kibana 服务器端口
server.port: 5601
# Kibana 服务器主机
server.host: "0.0.0.0"
# Elasticsearch 地址
elasticsearch.hosts: ["http://localhost:9200"]
# 如果 Elasticsearch 启用了安全认证
elasticsearch.username: "kibana_system"
elasticsearch.password: "your_password"
步骤 4:启动
powershell
cd C:\kibana\kibana-8.x.x\bin
.\kibana.bat
步骤 5:访问
http://localhost:5601
首次访问会要求输入注册令牌(enrollment token):
- 使用 Elasticsearch 首次启动时生成的令牌
- 或者运行命令生成新令牌:
bash
bin/elasticsearch-create-enrollment-token -s kibana
3.4.2 Linux 安装 Kibana
使用 tar.gz 包安装:
步骤 1:下载
bash
wget https://artifacts.elastic.co/downloads/kibana/kibana-8.11.0-linux-x86_64.tar.gz
步骤 2:解压
bash
sudo tar -xzf kibana-8.11.0-linux-x86_64.tar.gz -C /opt/
sudo ln -s /opt/kibana-8.11.0 /opt/kibana
步骤 3:设置权限
bash
sudo chown -R elasticsearch:elasticsearch /opt/kibana-8.11.0
步骤 4:配置 Kibana
编辑 config/kibana.yml:
yaml
# Kibana 服务器配置
server.port: 5601
server.host: "0.0.0.0"
server.name: "kibana-server"
# Elasticsearch 配置
elasticsearch.hosts: ["http://localhost:9200"]
# 如果 Elasticsearch 启用了安全认证
elasticsearch.username: "kibana_system"
elasticsearch.password: "your_password"
# 日志配置
logging.dest: /var/log/kibana/kibana.log
步骤 5:创建日志目录
bash
sudo mkdir -p /var/log/kibana
sudo chown elasticsearch:elasticsearch /var/log/kibana
步骤 6:启动 Kibana
bash
sudo su - elasticsearch
cd /opt/kibana
./bin/kibana
配置 systemd 服务:
创建服务文件:
bash
sudo vim /etc/systemd/system/kibana.service
添加以下内容:
ini
[Unit]
Description=Kibana
Documentation=https://www.elastic.co
Wants=network-online.target
After=network-online.target elasticsearch.service
[Service]
Type=simple
User=elasticsearch
Group=elasticsearch
Environment=NODE_OPTIONS="--max-old-space-size=2048"
ExecStart=/opt/kibana/bin/kibana
Restart=on-failure
RestartSec=10s
[Install]
WantedBy=multi-user.target
启用并启动服务:
bash
sudo systemctl daemon-reload
sudo systemctl enable kibana
sudo systemctl start kibana
sudo systemctl status kibana
使用 RPM 包安装(CentOS/RHEL):
bash
sudo yum install --enablerepo=elasticsearch kibana
sudo systemctl enable kibana
sudo systemctl start kibana
使用 DEB 包安装(Ubuntu/Debian):
bash
sudo apt-get install kibana
sudo systemctl enable kibana
sudo systemctl start kibana
3.4.3 Kibana 常用功能
1. Dev Tools(开发工具)
访问:http://localhost:5601/app/dev_tools#/console
用途:执行 Elasticsearch REST API 命令
示例:
json
GET /_cluster/health
POST /products/_doc/1
{
"name": "华为手机",
"price": 3999
}
GET /products/_search
{
"query": {
"match": {
"name": "华为"
}
}
}
2. Discover(数据探索)
访问:http://localhost:5601/app/discover
用途:浏览和搜索索引数据
3. Visualize(可视化)
访问:http://localhost:5601/app/visualize
用途:创建图表和可视化
4. Dashboard(仪表板)
访问:http://localhost:5601/app/dashboards
用途:组合多个可视化创建仪表板
5. Stack Management(堆栈管理)
访问:http://localhost:5601/app/management
用途:管理索引、用户、角色等
四、基本配置
4.1 配置文件位置
elasticsearch/
├── config/
│ ├── elasticsearch.yml # 主配置文件
│ ├── jvm.options # JVM 配置
│ ├── log4j2.properties # 日志配置
│ ├── role_mapping.yml # 角色映射
│ └── users # 用户文件
├── data/ # 数据目录
├── logs/ # 日志目录
└── plugins/ # 插件目录
4.2 elasticsearch.yml 详细配置
4.2.1 集群配置
yaml
# ================================ 集群配置 ================================
# 集群名称(同一集群的所有节点必须相同)
cluster.name: my-application
# 节点名称(集群中每个节点必须唯一)
node.name: node-1
# 节点角色配置
# master: 可以被选举为主节点
# data: 存储数据
# ingest: 数据预处理
# ml: 机器学习
node.roles: [ master, data, ingest ]
# 是否可以被选举为主节点(已废弃,使用 node.roles)
# node.master: true
# 是否存储数据(已废弃,使用 node.roles)
# node.data: true
节点角色说明:
┌─────────────────────────────────────────────────────────────┐
│ 节点角色类型 │
├─────────────────────────────────────────────────────────────┤
│ master │ 管理集群状态,不处理数据请求 │
│ data │ 存储数据,执行数据相关操作 │
│ data_content │ 存储内容数据(文档、日志等) │
│ data_hot │ 存储热数据(频繁访问) │
│ data_warm │ 存储温数据(较少访问) │
│ data_cold │ 存储冷数据(很少访问) │
│ ingest │ 数据预处理(转换、丰富) │
│ ml │ 机器学习任务 │
│ remote_cluster_client │ 跨集群搜索 │
│ transform │ 数据转换 │
└─────────────────────────────────────────────────────────────┘
常见节点配置组合:
yaml
# 专用主节点(不存储数据,不处理请求)
node.roles: [ master ]
# 专用数据节点(不参与主节点选举)
node.roles: [ data, ingest ]
# 协调节点(不存储数据,不参与选举,只负责路由请求)
node.roles: [ ]
# 全能节点(开发环境)
node.roles: [ master, data, ingest ]
4.2.2 网络配置
yaml
# ================================ 网络配置 ================================
# 绑定的网络地址
# 0.0.0.0: 监听所有网卡
# localhost: 只监听本地
# 192.168.1.100: 监听指定 IP
network.host: 0.0.0.0
# HTTP 端口(客户端连接)
http.port: 9200
# TCP 端口(节点间通信)
transport.port: 9300
# 发布地址(其他节点连接本节点的地址)
# 如果服务器有多个 IP,需要指定
# network.publish_host: 192.168.1.100
# HTTP 最大内容长度
http.max_content_length: 100mb
# HTTP 压缩
http.compression: true
# CORS 配置(跨域)
http.cors.enabled: true
http.cors.allow-origin: "*"
http.cors.allow-methods: OPTIONS, HEAD, GET, POST, PUT, DELETE
http.cors.allow-headers: X-Requested-With, Content-Type, Content-Length
为什么需要配置 network.host?
localhost(默认):
✓ 安全,只能本地访问
✗ 无法组建集群
✗ 无法远程访问
0.0.0.0:
✓ 可以远程访问
✓ 可以组建集群
✗ 需要配置防火墙
✗ 需要启用安全认证
4.2.3 路径配置
yaml
# ================================ 路径配置 ================================
# 数据目录(可以配置多个,用逗号分隔)
path.data: /var/lib/elasticsearch
# 日志目录
path.logs: /var/log/elasticsearch
# 插件目录
# path.plugins: /path/to/plugins
# 临时文件目录
# path.work: /path/to/work
多数据目录配置:
yaml
# 配置多个数据目录(用于多磁盘)
path.data:
- /mnt/disk1/elasticsearch
- /mnt/disk2/elasticsearch
- /mnt/disk3/elasticsearch
为什么使用多数据目录?
单数据目录:
✗ 受限于单个磁盘的 I/O
✗ 磁盘满了无法扩展
多数据目录:
✓ 利用多个磁盘的 I/O
✓ 提高读写性能
✓ 增加存储容量
⚠️ 不是 RAID,一个磁盘坏了会丢失数据
4.2.4 内存配置
yaml
# ================================ 内存配置 ================================
# 锁定内存(防止被交换到磁盘)
bootstrap.memory_lock: true
# 系统调用过滤器(安全特性)
bootstrap.system_call_filter: true
为什么要锁定内存?
不锁定内存:
✗ 内存可能被交换到磁盘
✗ 导致性能急剧下降
✗ 可能导致 GC 暂停
锁定内存:
✓ 内存始终在物理内存中
✓ 性能稳定
✓ 避免 GC 问题
如何验证内存锁定成功?
bash
# 查看节点信息
curl -X GET "localhost:9200/_nodes?filter_path=**.mlockall"
# 输出应该是:
{
"nodes": {
"node_id": {
"process": {
"mlockall": true
}
}
}
}
4.2.5 发现配置(集群组建)
yaml
# ================================ 发现配置 ================================
# 单节点模式(开发环境)
discovery.type: single-node
# 集群模式(生产环境)
# discovery.type: multi-node
# 种子节点列表(集群模式必须配置)
discovery.seed_hosts:
- 192.168.1.101:9300
- 192.168.1.102:9300
- 192.168.1.103:9300
# 初始主节点列表(首次启动集群时必须配置)
cluster.initial_master_nodes:
- node-1
- node-2
- node-3
# 最小主节点数(已废弃,ES 7.x 后自动计算)
# discovery.zen.minimum_master_nodes: 2
集群发现流程:
1. 节点启动
↓
2. 读取 discovery.seed_hosts
↓
3. 尝试连接种子节点
↓
4. 交换集群状态信息
↓
5. 选举主节点
↓
6. 加入集群
为什么需要 cluster.initial_master_nodes?
首次启动集群:
✓ 防止脑裂(split brain)
✓ 确保集群正确初始化
⚠️ 只在首次启动时需要
⚠️ 集群启动后应该删除此配置
4.2.6 网关配置(集群恢复)
yaml
# ================================ 网关配置 ================================
# 集群重启后,等待多少个节点在线才开始恢复
gateway.recover_after_nodes: 2
# 等待的超时时间
gateway.recover_after_time: 5m
# 期望的节点数
gateway.expected_nodes: 3
为什么需要这些配置?
场景:3 节点集群重启
不配置:
✗ 第一个节点启动后立即开始恢复
✗ 可能导致大量数据迁移
✗ 浪费资源
配置后:
✓ 等待 2 个节点在线
✓ 或等待 5 分钟超时
✓ 减少不必要的数据迁移
4.2.7 索引配置
yaml
# ================================ 索引配置 ================================
# 默认分片数(ES 7.x 后默认为 1)
# index.number_of_shards: 1
# 默认副本数
# index.number_of_replicas: 1
# 自动创建索引
action.auto_create_index: true
# 允许自动创建的索引模式
# action.auto_create_index: +aaa*,-bbb*,+ccc*,-*
# 禁止删除所有索引
action.destructive_requires_name: true
分片和副本的关系:
索引:products
├── 主分片 0 (node-1)
│ └── 副本分片 0 (node-2)
├── 主分片 1 (node-2)
│ └── 副本分片 1 (node-3)
└── 主分片 2 (node-3)
└── 副本分片 2 (node-1)
优势:
✓ 主分片挂了,副本可以顶上
✓ 读请求可以分散到副本
✓ 提高可用性和性能
4.2.8 安全配置
yaml
# ================================ 安全配置 ================================
# 启用安全特性
xpack.security.enabled: true
# 启用 HTTPS
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: certs/http.p12
# 启用节点间加密
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: certs/transport.p12
xpack.security.transport.ssl.truststore.path: certs/transport.p12
# 审计日志
xpack.security.audit.enabled: true
开发环境简化配置(不推荐生产环境):
yaml
# 关闭安全特性
xpack.security.enabled: false
xpack.security.http.ssl.enabled: false
xpack.security.transport.ssl.enabled: false
4.2.9 监控配置
yaml
# ================================ 监控配置 ================================
# 启用监控
xpack.monitoring.enabled: true
# 监控数据收集间隔
xpack.monitoring.collection.enabled: true
xpack.monitoring.collection.interval: 10s
# 监控索引保留时间
xpack.monitoring.history.duration: 7d
4.2.10 完整配置示例
开发环境配置:
yaml
# ==================== 开发环境配置 ====================
cluster.name: dev-cluster
node.name: dev-node-1
node.roles: [ master, data, ingest ]
network.host: 0.0.0.0
http.port: 9200
discovery.type: single-node
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
bootstrap.memory_lock: true
xpack.security.enabled: false
xpack.security.http.ssl.enabled: false
http.cors.enabled: true
http.cors.allow-origin: "*"
action.destructive_requires_name: true
生产环境配置(3 节点集群):
节点 1 配置:
yaml
# ==================== 生产环境配置 - 节点 1 ====================
cluster.name: prod-cluster
node.name: prod-node-1
node.roles: [ master, data, ingest ]
network.host: 192.168.1.101
http.port: 9200
transport.port: 9300
discovery.seed_hosts:
- 192.168.1.101:9300
- 192.168.1.102:9300
- 192.168.1.103:9300
cluster.initial_master_nodes:
- prod-node-1
- prod-node-2
- prod-node-3
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
bootstrap.memory_lock: true
xpack.security.enabled: true
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: certs/http.p12
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.keystore.path: certs/transport.p12
xpack.security.transport.ssl.truststore.path: certs/transport.p12
gateway.recover_after_nodes: 2
gateway.recover_after_time: 5m
gateway.expected_nodes: 3
action.destructive_requires_name: true
xpack.monitoring.enabled: true
xpack.monitoring.collection.enabled: true
节点 2 和节点 3 配置类似,只需修改:
yaml
node.name: prod-node-2 # 或 prod-node-3
network.host: 192.168.1.102 # 或 192.168.1.103
4.3 JVM 内存配置
4.3.1 jvm.options 配置
配置文件位置:
config/jvm.options
基本配置:
# ==================== JVM 堆内存配置 ====================
# 初始堆大小
-Xms4g
# 最大堆大小
-Xmx4g
# ⚠️ 重要规则:
# 1. Xms 和 Xmx 必须相同(避免堆大小调整)
# 2. 不要超过物理内存的 50%(留给操作系统和 Lucene)
# 3. 不要超过 32GB(压缩指针阈值)
为什么不超过 32GB?
内存 ≤ 32GB:
✓ 使用压缩指针(Compressed Oops)
✓ 每个对象引用占用 4 字节
✓ 内存利用率高
内存 > 32GB:
✗ 无法使用压缩指针
✗ 每个对象引用占用 8 字节
✗ 实际可用内存反而减少
示例:
31GB 堆内存 → 实际可用约 31GB
40GB 堆内存 → 实际可用约 30GB(因为指针占用更多空间)
内存分配建议:
服务器内存 堆内存 说明
8GB 4GB 开发环境
16GB 8GB 小型生产环境
32GB 16GB 中型生产环境
64GB 31GB 大型生产环境(不要超过 32GB)
128GB 31GB 超大型环境(剩余内存给操作系统缓存)
4.3.2 GC 配置
G1GC 配置(ES 默认):
# ==================== G1GC 配置 ====================
# 使用 G1 垃圾回收器
-XX:+UseG1GC
# G1 区域大小
-XX:G1ReservePercent=25
# 初始化堆占用百分比
-XX:InitiatingHeapOccupancyPercent=30
GC 日志配置:
# ==================== GC 日志配置 ====================
# GC 日志文件
-Xlog:gc*,gc+age=trace,safepoint:file=logs/gc.log:utctime,pid,tags:filecount=32,filesize=64m
4.3.3 其他 JVM 配置
# ==================== 其他 JVM 配置 ====================
# 堆转储(OOM 时自动生成)
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=data
# 错误日志
-XX:ErrorFile=logs/hs_err_pid%p.log
# JVM 致命错误时的操作
-XX:+ExitOnOutOfMemoryError
4.4 日志配置
4.4.1 log4j2.properties 配置
配置文件位置:
config/log4j2.properties
基本配置:
properties
# ==================== 日志级别配置 ====================
# 根日志级别
rootLogger.level = info
# 特定包的日志级别
logger.action.name = org.elasticsearch.action
logger.action.level = debug
logger.deprecation.name = org.elasticsearch.deprecation
logger.deprecation.level = warn
日志级别说明:
TRACE:最详细的日志,包含所有信息
DEBUG:调试信息,用于开发和故障排查
INFO:重要的业务信息(默认)
WARN:警告信息,可能存在问题
ERROR:错误信息,需要关注
FATAL:致命错误,系统无法继续运行
日志文件配置:
properties
# ==================== 日志文件配置 ====================
# 主日志文件
appender.rolling.type = RollingFile
appender.rolling.name = rolling
appender.rolling.fileName = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}.log
appender.rolling.filePattern = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}-%d{yyyy-MM-dd}-%i.log.gz
# 日志滚动策略
appender.rolling.policies.type = Policies
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.rolling.policies.time.interval = 1
appender.rolling.policies.time.modulate = true
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling.policies.size.size = 256MB
# 保留的日志文件数量
appender.rolling.strategy.type = DefaultRolloverStrategy
appender.rolling.strategy.max = 30
4.4.2 慢查询日志
配置慢查询日志:
bash
# 设置索引级别的慢查询日志
PUT /my-index/_settings
{
"index.search.slowlog.threshold.query.warn": "10s",
"index.search.slowlog.threshold.query.info": "5s",
"index.search.slowlog.threshold.query.debug": "2s",
"index.search.slowlog.threshold.query.trace": "500ms",
"index.search.slowlog.threshold.fetch.warn": "1s",
"index.search.slowlog.threshold.fetch.info": "800ms",
"index.search.slowlog.threshold.fetch.debug": "500ms",
"index.search.slowlog.threshold.fetch.trace": "200ms",
"index.indexing.slowlog.threshold.index.warn": "10s",
"index.indexing.slowlog.threshold.index.info": "5s",
"index.indexing.slowlog.threshold.index.debug": "2s",
"index.indexing.slowlog.threshold.index.trace": "500ms"
}
慢查询日志文件:
logs/
├── my-cluster.log # 主日志
├── my-cluster_index_search_slowlog.log # 搜索慢查询日志
└── my-cluster_index_indexing_slowlog.log # 索引慢查询日志
4.5 插件管理
4.5.1 安装插件
安装 IK 分词器(中文分词):
bash
# 在线安装
bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v8.11.0/elasticsearch-analysis-ik-8.11.0.zip
# 离线安装
bin/elasticsearch-plugin install file:///path/to/elasticsearch-analysis-ik-8.11.0.zip
安装拼音分词器:
bash
bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-pinyin/releases/download/v8.11.0/elasticsearch-analysis-pinyin-8.11.0.zip
4.5.2 查看已安装插件
bash
bin/elasticsearch-plugin list
4.5.3 删除插件
bash
bin/elasticsearch-plugin remove analysis-ik
4.5.4 常用插件推荐
┌────────────────────────────────────────────────────────────┐
│ 常用插件列表 │
├────────────────────────────────────────────────────────────┤
│ analysis-ik │ 中文分词器 │
│ analysis-pinyin │ 拼音分词器 │
│ analysis-smartcn │ 智能中文分词器(官方) │
│ repository-s3 │ S3 仓库插件(备份到 AWS S3) │
│ repository-hdfs │ HDFS 仓库插件(备份到 Hadoop) │
│ ingest-attachment │ 附件处理器(提取 PDF、Word 等内容) │
└────────────────────────────────────────────────────────────┘
五、开发环境配置
5.1 关闭安全认证(仅开发环境)
elasticsearch.yml:
yaml
# 关闭 HTTPS
xpack.security.enabled: false
xpack.security.http.ssl.enabled: false
重启后可以直接访问:
http://localhost:9200
5.2 跨域配置(前端开发)
yaml
http.cors.enabled: true
http.cors.allow-origin: "*"
六、常见问题与解决方案
6.1 启动问题
Q1: 启动失败,提示内存不足
错误信息:
Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000000c5330000, 986513408, 0) failed; error='Cannot allocate memory' (errno=12)
原因:
- 系统内存不足
- JVM 堆内存配置过大
解决方案:
bash
# 方法 1:降低堆内存
vim config/jvm.options
# 修改为
-Xms1g
-Xmx1g
# 方法 2:增加系统内存
# 或使用云服务器升级配置
Q2: 无法访问 9200 端口
错误信息:
curl: (7) Failed to connect to localhost port 9200: Connection refused
原因:
- Elasticsearch 未启动
- 防火墙阻止
- 监听地址配置错误
解决方案:
bash
# 1. 检查 Elasticsearch 是否运行
ps aux | grep elasticsearch
# 2. 检查端口监听
netstat -tlnp | grep 9200
# 或
ss -tlnp | grep 9200
# 3. 检查防火墙(CentOS/RHEL)
sudo firewall-cmd --list-ports
sudo firewall-cmd --add-port=9200/tcp --permanent
sudo firewall-cmd --reload
# 4. 检查防火墙(Ubuntu/Debian)
sudo ufw status
sudo ufw allow 9200/tcp
sudo ufw reload
# 5. 检查配置文件
vim config/elasticsearch.yml
# 确保 network.host 配置正确
Q3: 忘记 elastic 用户密码
解决方案:
bash
# 重置密码
bin/elasticsearch-reset-password -u elastic
# 交互式重置(可以自定义密码)
bin/elasticsearch-reset-password -u elastic -i
# 自动生成密码
bin/elasticsearch-reset-password -u elastic --auto
Q4: 启动时提示 "max virtual memory areas vm.max_map_count [65530] is too low"
错误信息:
max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
原因:
- 系统的虚拟内存区域限制太低
解决方案:
bash
# 临时设置(重启后失效)
sudo sysctl -w vm.max_map_count=262144
# 永久设置
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Q5: 启动时提示 "memory locking requested for elasticsearch process but memory is not locked"
错误信息:
memory locking requested for elasticsearch process but memory is not locked
原因:
- 配置了 bootstrap.memory_lock: true
- 但系统没有给予足够的权限
解决方案:
bash
# 1. 检查 limits 配置
vim /etc/security/limits.conf
# 添加
elasticsearch soft memlock unlimited
elasticsearch hard memlock unlimited
# 2. 如果使用 systemd,编辑服务文件
sudo vim /etc/systemd/system/elasticsearch.service
# 添加
[Service]
LimitMEMLOCK=infinity
# 3. 重新加载并重启
sudo systemctl daemon-reload
sudo systemctl restart elasticsearch
# 4. 验证
curl -X GET "localhost:9200/_nodes?filter_path=**.mlockall&pretty"
6.2 性能问题
Q6: 查询速度慢
可能原因:
- 没有使用索引
- 数据量太大
- 查询语句不优化
- 硬件资源不足
解决方案:
1. 检查是否使用了索引:
bash
# 查看索引映射
GET /my-index/_mapping
# 确保搜索字段有正确的类型
# text: 全文搜索
# keyword: 精确匹配
2. 使用 Profile API 分析查询:
bash
GET /my-index/_search
{
"profile": true,
"query": {
"match": {
"name": "华为"
}
}
}
3. 启用慢查询日志:
bash
PUT /my-index/_settings
{
"index.search.slowlog.threshold.query.warn": "10s",
"index.search.slowlog.threshold.query.info": "5s",
"index.search.slowlog.threshold.query.debug": "2s",
"index.search.slowlog.threshold.query.trace": "500ms"
}
4. 优化查询语句:
bash
# ❌ 不好的查询(使用通配符)
GET /products/_search
{
"query": {
"wildcard": {
"name": "*手机*"
}
}
}
# ✓ 好的查询(使用 match)
GET /products/_search
{
"query": {
"match": {
"name": "手机"
}
}
}
5. 使用分页:
bash
# ❌ 不好的分页(深度分页)
GET /products/_search
{
"from": 10000,
"size": 10
}
# ✓ 好的分页(使用 search_after)
GET /products/_search
{
"size": 10,
"sort": [
{"_id": "asc"}
],
"search_after": ["last_doc_id"]
}
Q7: 索引速度慢
可能原因:
- 副本数太多
- 刷新间隔太短
- 硬件资源不足
解决方案:
1. 批量索引时临时禁用副本:
bash
# 禁用副本
PUT /my-index/_settings
{
"index.number_of_replicas": 0
}
# 批量索引数据
# ...
# 恢复副本
PUT /my-index/_settings
{
"index.number_of_replicas": 1
}
2. 增加刷新间隔:
bash
# 默认 1s,可以增加到 30s
PUT /my-index/_settings
{
"index.refresh_interval": "30s"
}
# 批量索引时可以完全禁用
PUT /my-index/_settings
{
"index.refresh_interval": "-1"
}
# 索引完成后恢复
PUT /my-index/_settings
{
"index.refresh_interval": "1s"
}
3. 使用 Bulk API:
bash
# ❌ 不好的方式(逐条索引)
POST /products/_doc/1
{"name": "产品1"}
POST /products/_doc/2
{"name": "产品2"}
# ✓ 好的方式(批量索引)
POST /_bulk
{"index": {"_index": "products", "_id": "1"}}
{"name": "产品1"}
{"index": {"_index": "products", "_id": "2"}}
{"name": "产品2"}
6.3 集群问题
Q8: 集群状态为 yellow
原因:
- 有副本分片未分配
- 通常是单节点集群配置了副本
解决方案:
bash
# 查看集群健康状态
GET /_cluster/health?pretty
# 查看未分配的分片
GET /_cat/shards?v&h=index,shard,prirep,state,unassigned.reason
# 方法 1:增加节点(推荐)
# 启动更多节点加入集群
# 方法 2:减少副本数(单节点集群)
PUT /_all/_settings
{
"index.number_of_replicas": 0
}
Q9: 集群状态为 red
原因:
- 有主分片未分配
- 数据丢失或节点故障
解决方案:
bash
# 1. 查看集群健康状态
GET /_cluster/health?pretty
# 2. 查看未分配的分片
GET /_cat/shards?v&h=index,shard,prirep,state,unassigned.reason
# 3. 查看分片分配解释
GET /_cluster/allocation/explain
{
"index": "my-index",
"shard": 0,
"primary": true
}
# 4. 如果数据已丢失,可以强制分配(会丢失数据)
POST /_cluster/reroute
{
"commands": [
{
"allocate_empty_primary": {
"index": "my-index",
"shard": 0,
"node": "node-1",
"accept_data_loss": true
}
}
]
}
Q10: 节点无法加入集群
可能原因:
- 集群名称不匹配
- 网络不通
- 版本不兼容
解决方案:
bash
# 1. 检查集群名称
grep "cluster.name" config/elasticsearch.yml
# 2. 检查网络连通性
ping 192.168.1.101
telnet 192.168.1.101 9300
# 3. 检查防火墙
sudo firewall-cmd --add-port=9300/tcp --permanent
sudo firewall-cmd --reload
# 4. 查看节点日志
tail -f logs/my-cluster.log
# 5. 检查版本
curl -X GET "localhost:9200"
6.4 数据问题
Q11: 数据丢失
可能原因:
- 没有配置副本
- 多个节点同时故障
- 误删除索引
预防措施:
bash
# 1. 配置副本
PUT /my-index/_settings
{
"index.number_of_replicas": 1
}
# 2. 定期备份(快照)
PUT /_snapshot/my_backup
{
"type": "fs",
"settings": {
"location": "/mount/backups/my_backup"
}
}
# 创建快照
PUT /_snapshot/my_backup/snapshot_1?wait_for_completion=true
{
"indices": "my-index",
"ignore_unavailable": true,
"include_global_state": false
}
# 3. 禁止删除所有索引
PUT /_cluster/settings
{
"persistent": {
"action.destructive_requires_name": true
}
}
恢复数据:
bash
# 从快照恢复
POST /_snapshot/my_backup/snapshot_1/_restore
{
"indices": "my-index",
"ignore_unavailable": true,
"include_global_state": false
}
Q12: 磁盘空间不足
错误信息:
flood stage disk watermark [95%] exceeded on [node-1]
解决方案:
bash
# 1. 查看磁盘使用情况
GET /_cat/allocation?v
# 2. 删除不需要的索引
DELETE /old-index
# 3. 清理旧的快照
DELETE /_snapshot/my_backup/old_snapshot
# 4. 增加磁盘空间
# 或添加新的数据节点
# 5. 调整磁盘水位线(临时)
PUT /_cluster/settings
{
"transient": {
"cluster.routing.allocation.disk.watermark.low": "90%",
"cluster.routing.allocation.disk.watermark.high": "95%",
"cluster.routing.allocation.disk.watermark.flood_stage": "97%"
}
}
6.5 安全问题
Q13: 如何启用 HTTPS?
步骤:
bash
# 1. 生成 CA 证书
bin/elasticsearch-certutil ca
# 2. 生成节点证书
bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12
# 3. 将证书复制到 config/certs 目录
mkdir config/certs
mv elastic-certificates.p12 config/certs/
# 4. 配置 elasticsearch.yml
vim config/elasticsearch.yml
# 添加
xpack.security.enabled: true
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: certs/elastic-certificates.p12
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.keystore.path: certs/elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: certs/elastic-certificates.p12
# 5. 重启 Elasticsearch
sudo systemctl restart elasticsearch
# 6. 设置密码
bin/elasticsearch-setup-passwords auto
# 或
bin/elasticsearch-setup-passwords interactive
# 7. 使用 HTTPS 访问
curl -k -u elastic:password https://localhost:9200
Q14: 如何创建用户和角色?
创建角色:
bash
POST /_security/role/my_role
{
"cluster": ["monitor"],
"indices": [
{
"names": ["my-index"],
"privileges": ["read", "write"]
}
]
}
创建用户:
bash
POST /_security/user/my_user
{
"password": "my_password",
"roles": ["my_role"],
"full_name": "My User",
"email": "myuser@example.com"
}
修改用户密码:
bash
POST /_security/user/my_user/_password
{
"password": "new_password"
}
6.6 监控问题
Q15: 如何监控集群状态?
1. 使用 Cat API:
bash
# 集群健康
GET /_cat/health?v
# 节点信息
GET /_cat/nodes?v
# 索引信息
GET /_cat/indices?v
# 分片信息
GET /_cat/shards?v
# 线程池
GET /_cat/thread_pool?v
# 待处理任务
GET /_cat/pending_tasks?v
2. 使用 Cluster API:
bash
# 集群统计
GET /_cluster/stats
# 集群健康
GET /_cluster/health
# 集群状态
GET /_cluster/state
# 节点统计
GET /_nodes/stats
# 节点信息
GET /_nodes
3. 使用 Kibana 监控:
访问:http://localhost:5601/app/monitoring
4. 使用 Metricbeat 监控:
bash
# 安装 Metricbeat
wget https://artifacts.elastic.co/downloads/beats/metricbeat/metricbeat-8.11.0-linux-x86_64.tar.gz
tar -xzf metricbeat-8.11.0-linux-x86_64.tar.gz
# 启用 Elasticsearch 模块
cd metricbeat-8.11.0
./metricbeat modules enable elasticsearch
# 配置
vim modules.d/elasticsearch.yml
# 启动
./metricbeat -e
6.7 升级问题
Q16: 如何升级 Elasticsearch?
滚动升级步骤(推荐):
1. 禁用分片分配:
bash
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.enable": "primaries"
}
}
2. 停止一个节点:
bash
sudo systemctl stop elasticsearch
3. 升级节点:
bash
# 备份配置文件
cp -r /etc/elasticsearch /etc/elasticsearch.backup
# 升级(RPM)
sudo yum install elasticsearch-8.11.0
# 或升级(DEB)
sudo apt-get install elasticsearch=8.11.0
4. 启动节点:
bash
sudo systemctl start elasticsearch
5. 等待节点加入集群:
bash
GET /_cat/nodes?v
6. 重新启用分片分配:
bash
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.enable": "all"
}
}
7. 等待集群恢复:
bash
GET /_cat/health?v
8. 重复步骤 2-7 升级其他节点
完整集群重启升级(不推荐):
bash
# 1. 停止所有节点
# 2. 升级所有节点
# 3. 启动所有节点
# ⚠️ 会导致服务中断
七、快速验证
7.1 创建索引
bash
curl -X PUT "localhost:9200/products"
7.2 添加文档
bash
curl -X POST "localhost:9200/products/_doc/1" -H 'Content-Type: application/json' -d'
{
"name": "华为手机",
"price": 3999
}
'
7.3 搜索文档
bash
curl -X GET "localhost:9200/products/_search?q=华为"
学习检查清单
- 理解 Elasticsearch 的应用场景
- 理解倒排索引的原理
- 成功安装并启动 Elasticsearch
- 能够访问 Elasticsearch 的 REST API
- 了解基本的配置项
- 完成快速验证的三个操作
下一步
下一节我们将深入学习 Elasticsearch 的核心概念,包括索引、文档、映射等。