Elasticsearch 核心概念与系统架构详解

Elasticsearch(ES)是一个基于 Lucene 的分布式搜索引擎,它的设计精髓在于一切为了搜索性能

但想要用好 ES,必须先理解它的核心概念系统架构。很多新手在使用 ES 时遇到的性能问题、数据丢失问题、扩容问题,根源往往在于对分片、副本、分配等机制理解不够深入。


1. 核心概念

在进入细节之前,先看一张 ES 与关系型数据库的对照表,帮助你快速建立映射:

ES 7.x 以前 ES 7.x 及以后 MySQL
Index Index Database
Type _doc(默认) Table
Document Document Row
Field Field Column
Mapping Mapping Schema
Shards Shards 分区 / 分表
Replicas Replicas 备份/只读副本

2. 索引(Index)

2.1 定义

索引是具有相似特征的文档集合。你可以把它理解为关系型数据库中的"数据库"。

例如:

  • 客户索引(customer)
  • 商品索引(product)
  • 订单索引(order)

2.2 命名规范

  • 必须全部小写字母
  • 不能包含 \ / * ? " < > | , # : 等特殊字符
  • 建议使用下划线分隔,如 user_logs_2026

2.3 索引的本质

能搜索的数据必须被索引。

我们可以把索引类比为新华字典的目录

  • 目录(索引)的存在,让你能快速找到某个汉字在哪一页。
  • 如果没有目录,你只能一页一页翻(全表扫描),效率极低。

ES 的索引底层是倒排索引(Inverted Index) ,它是一种词条 → 文档列表的映射结构,使得全文搜索可以达到毫秒级响应。

2.4 设计哲学

Elasticsearch 索引的精髓:一切设计都是为了提高搜索的性能。

这意味着:

  • 索引不是"存储"结构,而是"检索"结构。
  • 存储数据只是手段,快速找到数据才是目的。
  • 因此,ES 宁愿牺牲一些写入性能,也要保证查询性能。

3. 类型(Type)

3.1 概念

Type 是 Index 内部的逻辑分类,类似于数据库中的"表"。

例如,在 blog 索引中,你可以有:

  • blog/article(文章)
  • blog/comment(评论)

3.2 版本演进(非常关键!)

ES 版本 Type 支持情况
5.x 支持多种 Type
6.x 一个 Index 只能有一个 Type
7.x 彻底移除自定义 Type,统一使用 _doc

3.3 为什么要移除 Type?

  • 同一 Index 下不同 Type 的相同字段,在 Lucene 底层是共享同一个字段存储的,容易造成映射冲突。
  • 随着时间推移,官方认为 Type 带来的复杂性大于收益。
  • 因此 ES 7.x 起,所有文档都使用 _doc 作为默认 Type。

💡 如果你还在使用 ES 6.x 及以下版本,建议尽快升级。


4. 文档(Document)

4.1 定义

文档是 ES 中可被索引的基本信息单元,也就是一条 JSON 数据。

示例:

json 复制代码
{
  "id": 1001,
  "name": "zhangsan",
  "age": 25,
  "tags": ["engineer", "beijing"]
}

4.2 文档的特点

  • 使用 JSON 格式,是互联网最通用的数据交换格式。
  • 每个文档都有一个唯一的 _id(可自动生成或手动指定)。
  • 文档是不可变的:每次更新实际上是创建了一个新版本,旧版本被标记为删除。

4.3 文档的元数据

字段 说明
_index 文档所属索引
_type 文档所属类型(7.x 为 _doc
_id 文档唯一标识
_version 版本号,每次修改 +1
_seq_no 序列号,用于并发控制
_source 文档原始 JSON 内容

5. 字段(Field)

字段是文档中的属性键值对,类似于 MySQL 的列。

每个字段都有:

  • 数据类型(text、keyword、long、date 等)
  • 是否索引(index: true / false)
  • 是否存储(store: true / false)

⚠️ 注意:即使 store 为 false,字段内容也会存在于 _source 中,只是不会独立存储。


6. 映射(Mapping)

6.1 定义

Mapping 相当于 MySQL 中的表结构定义,它规定了:

  • 字段的数据类型
  • 是否索引
  • 使用什么分词器
  • 是否支持排序/聚合

6.2 动态映射 vs 显式映射

  • 动态映射:ES 会自动推断字段类型(适合快速原型开发)。
  • 显式映射:手动定义字段属性,推荐用于生产环境(性能更好、更可控)。

6.3 Mapping 示例

json 复制代码
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "price": {
        "type": "double"
      },
      "is_active": {
        "type": "boolean"
      }
    }
  }
}

6.4 Mapping 的设计原则

  • 字段越少越好:不必要的字段不要索引。
  • 选择合适的类型 :如不需要分词的字段用 keyword 而非 text
  • 关闭不需要的索引"index": false 可节省存储和提升写入速度。

7. 分片(Shards)

7.1 为什么需要分片?

单个节点无法存储海量数据,或者单个节点处理请求太慢。

ES 通过将索引水平切分为多个分片,来解决这些问题。

7.2 分片的本质

一个分片 = 一个 Lucene 索引实例。

也就是说,你在 ES 中创建一个索引,实际上是在多个节点上创建了多个 Lucene 索引。

7.3 分片的作用

  1. 水平扩展:数据可以分布到多台机器。
  2. 并行处理:搜索请求可以并发执行,提高吞吐量。

7.4 分片数量如何确定?

text 复制代码
分片数 = 总数据量 / 单分片容量(建议 20GB ~ 50GB)
  • ES 7.x 默认主分片数为 1(早期版本为 5)。
  • 分片数一旦创建不可修改,所以要提前规划。

7.5 分片并非越多越好

问题 说明
元数据开销 每个分片都有独立的元数据,过多会增加集群管理负担
查询延迟 查询需要访问所有分片,分片过多会增加协调开销
故障恢复慢 分片越多,节点故障时恢复时间越长

✅ 建议:单个分片数据量控制在 20GB ~ 50GB,分片总数控制在节点数 × 20 以内。


8. 副本(Replicas)

8.1 定义

副本是主分片的完整拷贝,用于提供高可用性和扩展读能力。

8.2 副本的作用

  1. 高可用:当主分片所在的节点宕机,副本可以提升为主分片。
  2. 提升读性能:搜索请求可以分摊到所有副本上并行执行。

8.3 副本数量配置

json 复制代码
{
  "settings": {
    "number_of_replicas": 1   // 默认为 1
  }
}

8.4 副本数量可以动态调整

http 复制代码
PUT /my_index/_settings
{
  "number_of_replicas": 2
}

8.5 副本与主分片的关系

  • 副本永远不会与主分片落在同一个节点上
  • 写入请求只会发往主分片,主分片同步给所有副本(同步或异步)。

9. 分配(Allocation)

9.1 定义

分配是指将分片(主分片或副本)指派到某个具体节点的过程。

9.2 谁负责分配?

集群中的 Master 节点负责统一调度分配决策。

分配时会考虑:

  • 磁盘空间
  • 节点负载
  • 分片均衡策略
  • 机架感知(rack awareness)

9.3 常用分配策略

json 复制代码
{
  "settings": {
    "cluster.routing.allocation.awareness.attributes": "rack_id"
  }
}

这样 ES 会尽量将副本分配到不同的机架,防止机架级故障。


10. 系统架构深入

10.1 节点(Node)

一个运行中的 ES 实例就是一个节点。

节点通过 cluster.name 配置加入同一个集群。

10.2 集群(Cluster)

由多个节点组成,共同承担数据存储和查询压力。

10.3 主节点(Master Node)

  • 负责管理集群层面的变更:创建/删除索引、添加/移除节点。
  • 不参与文档级别的读写操作。
  • 任何节点都可以被选为主节点。

10.4 数据节点(Data Node)

  • 存储分片数据。
  • 执行文档的 CRUD 和搜索操作。

10.5 协调节点(Coordinating Node)

  • 接收客户端请求。
  • 将请求路由到相关数据节点。
  • 汇总并返回结果给客户端。

10.6 一个请求的完整流程

text 复制代码
客户端 → 协调节点 → 路由到主分片/副本 → 执行操作 → 返回结果

ES 对这一切的管理都是完全透明的,你只需要向任意节点发送请求即可。


11. 一张图总结 ES 架构


12. 生产环境最佳实践建议

建议项 说明
分片数规划 提前评估数据量,创建后不可改
副本数设置 至少 1,保证高可用
节点角色分离 主节点不存数据,数据节点不参与选举
监控磁盘 磁盘使用率超过 85% 会影响分配
合理设置刷新间隔 refresh_interval 默认 1s,可适当调大以提升写入性能

✅ 总结

概念 一句话理解
Index 数据库
Type 表(7.x 已弃用)
Document 一行数据
Field 一列数据
Mapping 表结构定义
Shard 数据分片,水平扩展的基础
Replica 主分片的备份,高可用 + 读扩展
Allocation 分片分配到节点的过程
Master Node 集群的管理者
Data Node 数据的存储者

相关推荐
Elastic 中国社区官方博客4 小时前
Elasticsearch:使用 AI Agent 来创建 workflow
大数据·运维·人工智能·elasticsearch·搜索引擎·自动化·全文检索
阿里云大数据AI技术4 小时前
AI Search+ES 9.4.X最佳实践:“更快、更准、更安全的企业级搜索引擎”"为AI Agent提供坚实底座”
人工智能·elasticsearch·agent
Elasticsearch8 小时前
Elastic 社区通讯 — 2026 年 8 月
elasticsearch
国科安芯9 小时前
详解ADC 规则组外部触发:CH2、CH3 与 TRGO2
运维·网络·单片机·嵌入式硬件·mcu·系统架构
lsh曙光9 小时前
ES数据备份与恢复
大数据·elasticsearch·搜索引擎
Dr.kangder9 小时前
嵌入式面试总结(十)——流水线
单片机·嵌入式硬件·面试·职场和发展·系统架构·嵌入式
Shawn Dev12 小时前
MySQL Binlog 数据误删除恢复完全指南
数据库·mysql·elasticsearch
ZJU_统一阿萨姆13 小时前
【推理优化】推理的本质:prefill 与 decode 两阶段
语言模型·系统架构
郑州光合科技余经理13 小时前
餐饮预定系统架构拆解:订单链路、权限组织与私有化源码交付
java·开发语言·前端·数据库·人工智能·系统架构·php
Elastic 中国社区官方博客14 小时前
用两行 JSON 替换你的 ILM 策略:数据流生命周期新增冻结层支持
大数据·运维·elasticsearch·搜索引擎·架构·全文检索