Elasticsearch 概述与安装

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. 没有使用索引
  2. 数据量太大
  3. 查询语句不优化
  4. 硬件资源不足

解决方案:

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. 副本数太多
  2. 刷新间隔太短
  3. 硬件资源不足

解决方案:

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: 节点无法加入集群

可能原因:

  1. 集群名称不匹配
  2. 网络不通
  3. 版本不兼容

解决方案:

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: 数据丢失

可能原因:

  1. 没有配置副本
  2. 多个节点同时故障
  3. 误删除索引

预防措施:

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 的核心概念,包括索引、文档、映射等。

相关推荐
九河云1 小时前
数据上云的安全边界:零信任架构在混合云场景的应用
大数据·人工智能·安全·架构·数字化转型
Elastic 中国社区官方博客1 小时前
需要知道某个同义词是否实际匹配了你的 Elasticsearch 查询吗?
大数据·数据库·elasticsearch·搜索引擎·全文检索
GlobalInfo2 小时前
汽车域控制模块市场增长率(CAGR)为10.4%:发展方向的启示
大数据·人工智能·汽车
YDS82911 小时前
SpringCloud —— Elasticsearch入门详解
spring·elasticsearch·spring cloud
简佐义的博客12 小时前
转录组数据分析实战,仅需99元(视频版)
大数据·人工智能·数据挖掘·数据分析·音视频
APO Research12 小时前
工业连接件的隐形升级:杆端轴承正在从“标准件”走向“结构安全件”
大数据·安全·#工业零部件·#机械设计·#工业自动化·#杆端轴承·#机械结构件
YangYang9YangYan12 小时前
2026高职财税大数据应用学数据分析的技术价值与应用前景
大数据·数据挖掘·数据分析
l1t12 小时前
在ARM64 KyLin计算机上安装llama.cpp
大数据·llama·kylin
福客AI智能客服12 小时前
电商店铺效率升级:智能客服系统如何重构服务与转化逻辑
大数据·重构