Elasticsearch核心概念详解

一、什么是Elasticsearch?

Elasticsearch是一个开源的分布式、RESTful风格的搜索和分析引擎,基于Apache Lucene构建。它能够以近实时的方式存储、搜索和分析海量数据,广泛应用于全文检索、日志分析、实时监控、商业智能等场景。

核心特点

  • 分布式架构:数据自动分片存储在多台服务器上,支持水平扩展
  • 近实时搜索:从数据写入到可搜索的延迟通常在1秒以内
  • RESTful API:所有操作通过HTTP API完成,简单易用
  • 多租户支持:支持多个索引,每个索引可以独立配置
  • 文档导向:数据以JSON文档形式存储,无需预定义schema

二、核心术语体系

1. 文档(Document)

定义:Elasticsearch中最小的数据单元,以JSON格式存储。每个文档代表一个可被索引的数据记录。

示例

{
  "id": 1,
  "title": "Elasticsearch入门指南",
  "content": "这是一篇关于Elasticsearch的入门文章...",
  "author": "张三",
  "create_time": "2025-12-22T10:30:00",
  "tags": ["elasticsearch", "搜索", "教程"]
}

关键特性

  • 每个文档都有唯一的_id字段,可以自动生成或手动指定
  • 文档是索引和搜索的基本单位
  • 支持嵌套对象和数组类型

2. 索引(Index)

定义:具有相似特征的文档集合,类似于关系型数据库中的”表”。

示例

  • books索引:存储所有图书信息
  • logs索引:存储系统日志
  • products索引:存储商品信息

关键特性

  • 每个索引可以独立配置映射、分片、副本等参数
  • 索引名称必须小写,不能包含特殊字符
  • 支持按时间创建滚动索引(如logs-2025.12.22

3. 类型(Type,已弃用)

历史背景:在Elasticsearch 7.x之前,一个索引可以包含多个类型,类似于关系型数据库中的”表”。但从7.0版本开始,类型已被弃用,8.0版本完全移除。

弃用原因

  • 类型在Lucene层面没有实际意义,导致性能开销
  • 不同类型的数据存储在同一个索引中,容易产生映射冲突
  • 简化数据模型,一个索引只包含一种文档类型

4. 映射(Mapping)

定义:定义索引中字段的类型和属性,类似于关系型数据库中的”表结构”。

示例映射

{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "author": {
        "type": "keyword"
      },
      "price": {
        "type": "float"
      },
      "create_time": {
        "type": "date"
      }
    }
  }
}

映射类型

  • 动态映射:自动根据文档字段推断类型
  • 显式映射:手动定义字段类型和属性
  • 模板映射:通过索引模板自动应用映射规则

5. 分片(Shard)

定义:索引的物理存储单元,一个索引可以被分成多个分片,分布在不同的节点上。

主分片 vs 副本分片

  • 主分片(Primary Shard):存储索引数据的主副本,负责写入操作
  • 副本分片(Replica Shard):主分片的副本,提供数据冗余和读负载均衡

配置示例

{
  "settings": {
    "number_of_shards": 5,    // 主分片数量
    "number_of_replicas": 1   // 每个主分片的副本数量
  }
}

分片策略

  • 主分片数量在创建索引时确定,后续不能修改
  • 副本分片数量可以动态调整
  • 每个分片都是一个独立的Lucene索引

6. 节点(Node)

定义:运行Elasticsearch实例的服务器,是集群的基本组成单元。

节点类型

  • 主节点(Master Node):负责集群管理、索引创建、分片分配等元数据操作
  • 数据节点(Data Node):存储数据分片,处理数据读写请求
  • 协调节点(Coordinating Node):接收客户端请求,分发到数据节点,聚合结果
  • 摄取节点(Ingest Node):在索引前对文档进行预处理
  • 机器学习节点(ML Node):运行机器学习作业

7. 集群(Cluster)

定义:由一个或多个节点组成的集合,共同存储数据并提供搜索服务。

集群状态

  • Green:所有主分片和副本分片都正常
  • Yellow:所有主分片正常,但部分副本分片异常
  • Red:部分主分片异常,数据可能丢失

三、倒排索引原理

基本概念

倒排索引(Inverted Index)是Elasticsearch实现快速全文检索的核心技术,它将文档中的每个词项映射到包含该词项的文档列表。

示例

文档1:I love Elasticsearch
文档2:Elasticsearch is powerful
文档3:I love learning

倒排索引:
I[文档1, 文档3]
love[文档1, 文档3]
Elasticsearch[文档1, 文档2]
is[文档2]
powerful[文档2]
learning[文档3]

倒排索引结构

词项字典(Term Dictionary)

  • 存储所有不重复的词项
  • 按字典序排序,便于二分查找

倒排列表(Posting List)

  • 存储包含该词项的文档ID列表
  • 包含词频、位置等信息

跳表(Skip List)

  • 加速倒排列表的合并操作
  • 在长倒排列表中快速定位

查询过程

  1. 词项解析:将查询字符串分词为词项列表
  2. 查找词项:在词项字典中查找每个词项
  3. 获取文档列表:获取每个词项的倒排列表
  4. 合并结果:根据查询逻辑(AND/OR)合并倒排列表
  5. 相关性打分:计算文档与查询的相关性得分
  6. 返回结果:按得分排序返回文档

四、近实时(NRT)搜索机制

写入流程

  1. 写入请求:客户端发送文档到协调节点
  2. 路由到分片:根据文档ID路由到对应的主分片
  3. 写入内存缓冲区:文档写入到主分片的内存缓冲区
  4. 写入事务日志(translog):同时写入事务日志,保证数据持久化
  5. refresh操作:默认每1秒执行一次,将内存缓冲区的内容刷新到新的段(segment)
  6. 段可搜索:refresh后新文档可以被搜索到
  7. flush操作:将内存中的段写入磁盘,清空事务日志

refresh机制

refresh间隔:默认1秒,可以通过以下方式调整:

  • 动态调整:PUT /index/_settings { "refresh_interval": "30s" }
  • 强制refresh:POST /index/_refresh
  • 关闭refresh:PUT /index/_settings { "refresh_interval": -1 }

性能影响

  • 频繁refresh会增加IO压力,降低写入性能
  • 过长的refresh间隔会延迟搜索可见性

段合并(Segment Merge)

背景:每次refresh都会生成新的段,导致段数量增多,影响搜索性能。

段合并过程

  1. 后台线程定期选择多个小段合并成更大的段
  2. 合并过程中,被合并的段仍然可以被搜索
  3. 合并完成后,删除旧的小段

优化策略

  • 强制合并:POST /index/_forcemerge?max_num_segments=1
  • 避免在写入高峰期执行段合并

五、核心概念关系图

集群(Cluster)
  ├── 节点(Node)
  │   ├── 主节点(Master Node)
  │   ├── 数据节点(Data Node)
  │   └── 协调节点(Coordinating Node)
  │
  └── 索引(Index)
      ├── 映射(Mapping)
      ├── 分片(Shard)
      │   ├── 主分片(Primary Shard)
      │   └── 副本分片(Replica Shard)
      │
      └── 文档(Document)
          └── 字段(Field)

六、最佳实践

1. 索引设计

  • 按业务场景划分索引,避免单个索引过大
  • 合理设置主分片数量(建议每个分片20-50GB)
  • 使用索引别名,便于索引重建和滚动更新

2. 映射设计

  • 提前定义显式映射,避免动态映射导致字段类型冲突
  • 合理选择字段类型:text用于全文搜索,keyword用于精确匹配
  • 关闭不需要索引的字段:"index": false

3. 写入优化

  • 使用批量API(_bulk)减少网络开销
  • 调整refresh间隔,批量写入时设置为-1,写入完成后手动refresh
  • 使用自动生成的文档ID,避免路由计算开销

4. 查询优化

  • 使用filter查询缓存结果
  • 避免深度分页,使用search_after替代from/size
  • 合理使用聚合查询,避免内存溢出

七、总结

Elasticsearch的核心概念体系是理解和使用该技术的基础。文档、索引、映射、分片、节点等概念构成了Elasticsearch的数据模型,倒排索引和近实时搜索机制是其高性能的保障。掌握这些核心概念,能够帮助开发者更好地设计索引结构、优化查询性能、规划集群架构,从而构建高效可靠的搜索和分析系统。

作者:严锋  创建时间:2025-12-22 20:57
最后编辑:严锋  更新时间:2025-12-25 10:39