Elasticsearch知识点详细总结
Elasticsearch(简称 ES)是一款基于 Lucene 构建的分布式、高扩展、高实时的全文搜索引擎,同时也是 Elastic Stack(ELK Stack:Elasticsearch, Logstash, Kibana)的核心组件,广泛应用于日志分析、全文检索、实时数据分析等场景。本文将从核心概念、架构设计、数据操作、查询分析、性能优化等维度进行全面总结。
一、核心概念
Elasticsearch 的概念体系与传统数据库有显著差异,理解这些基础概念是掌握 ES 的前提。
1. 与传统数据库的对应关系
为便于快速理解,可将 ES 核心概念与关系型数据库(如 MySQL)进行类比:
| Elasticsearch 概念 | 关系型数据库概念 | 说明 |
|---|---|---|
| Index(索引) | Database(数据库) | 存储同类文档的集合,具有相似的结构 |
| Type(类型,7.x 后废弃) | Table(表) | 早期用于对 Index 内文档分类,7.x 起强制为 _doc |
| Document(文档) | Row(行) | 索引中最小的数据单元,以 JSON 格式存储 |
| Field(字段) | Column(列) | 文档中的属性,对应 JSON 的键值对 |
| Mapping(映射) | Schema(表结构) | 定义文档中字段的类型、分词器、是否索引等元数据 |
| Shard(分片) | - | 索引的物理分片,实现水平扩展(Lucene 索引实例) |
| Replica(副本) | - | 分片的冗余备份,用于高可用和负载分担 |
2. 核心概念详解
(1)Index(索引)
- 定义:一个逻辑上的集合,包含具有相似结构的文档(如“商品索引”“用户日志索引”)。
- 命名规则: lowercase 小写,无特殊字符(建议用
-分隔,如user-logs-2024)。 - 特点:索引是分片的逻辑容器,创建时需指定分片和副本数量,创建后分片数量不可修改(副本可动态调整)。
(2)Document(文档)
- 格式:唯一支持 JSON 格式,灵活性高(无需严格统一结构,但建议遵循 Mapping 规范)。
- 唯一标识:由
_index(所属索引)、_type(7.x 固定为_doc)、_id(文档 ID)共同确定。_id可手动指定(如用业务 ID 作为_id),也可由 ES 自动生成(20 位 UUID)。
- 元数据:除业务字段外,包含
_index、_type、_id、_version(版本号)、_score(查询相关性得分)等系统字段。
(3)Mapping(映射)
- 定义:相当于文档的“ schema ”,用于约束字段的类型、分词方式、是否可检索等属性。
- 类型:
- 动态映射(Dynamic Mapping):ES 自动根据文档字段值推断类型(如数字→
long,字符串→text/keyword),适合快速上手,但可能存在精度问题。 - 静态映射(Explicit Mapping):手动定义字段类型和属性,适合生产环境,保证数据结构一致性。
- 动态映射(Dynamic Mapping):ES 自动根据文档字段值推断类型(如数字→
- 常见字段类型:
- 文本类:
text(可分词,用于全文检索,如“商品描述”)、keyword(不分词,用于精确匹配/聚合,如“商品分类”)。 - 数值类:
long、integer、double、float(对应不同精度的数字)。 - 日期类:
date(支持格式化,如yyyy-MM-dd HH:mm:ss)。 - 布尔类:
boolean(true/false)。 - 复合类:
object(嵌套对象)、nested(处理嵌套数组,解决object类型的扁平化问题)。
- 文本类:
(4)Shard & Replica(分片与副本)
Shard(分片):
- 核心目的:实现水平扩展。单个索引的数据被拆分到多个分片,每个分片是独立的 Lucene 索引,可分布在不同节点。
- 类型:主分片(Primary Shard)、副本分片(Replica Shard)。
- 数量限制:创建索引时指定主分片数量(
number_of_shards),创建后不可修改(需通过reindex重建索引调整);默认 1 个主分片。
Replica(副本):
- 核心目的:高可用 + 负载分担。副本是主分片的冗余备份,主分片故障时可自动升级为主分片;同时可承担查询请求,缓解主分片压力。
- 数量配置:创建时通过
number_of_replicas指定,支持动态修改(如PUT /index/_settings {"number_of_replicas": 2});默认 1 个副本。 - 约束:副本分片不会与对应的主分片在同一节点(避免单点故障)。
(5)Cluster & Node(集群与节点)
Node(节点):
- 定义:运行 ES 进程的单个服务器,是集群的基本组成单元。
- 类型:
- 主节点(Master Node):负责集群元数据管理(如创建索引、分片分配),默认所有节点均可竞选,建议通过
node.master: true专门配置。 - 数据节点(Data Node):负责数据的存储、索引、查询和聚合,通过
node.data: true配置,是集群的“数据载体”。 - 协调节点(Coordinating Node):接收客户端请求,分发到其他节点,汇总结果返回;默认所有节点都是协调节点,可通过
node.master: false+node.data: false配置专用协调节点。 - ingest 节点:负责数据预处理(如添加字段、转换格式),通过
node.ingest: true配置。
- 主节点(Master Node):负责集群元数据管理(如创建索引、分片分配),默认所有节点均可竞选,建议通过
Cluster(集群):
- 定义:由多个节点组成的集合,共享同一集群名称(
cluster.name),协同工作实现分布式能力。 - 集群状态:通过
_cluster/health查看,状态分为green(所有主/副本分片正常)、yellow(主分片正常,副本分片缺失)、red(主分片缺失,数据不可用)。
- 定义:由多个节点组成的集合,共享同一集群名称(
二、架构设计
Elasticsearch 的分布式架构是其高扩展、高可用的核心,主要围绕“分片分配”“路由机制”“故障转移”展开。
1. 分片路由机制
当客户端写入/查询文档时,ES 需要确定文档归属的主分片,核心逻辑如下:
- 计算路由值:
shard = hash(_routing) % number_of_primary_shards。 _routing默认为文档的_id,可手动指定(如按“用户 ID”路由,确保同一用户的文档在同一分片,优化聚合效率)。- 协调节点根据路由结果,将请求转发到主分片所在节点;写入操作需等待主分片和副本分片均确认后返回成功(默认配置)。
2. 分片分配与再平衡
- 分配策略:Master 节点负责将主分片和副本分片分配到不同节点,遵循“副本不与主分片同节点”“分片均匀分布”等原则。
- 再平衡(Rebalancing):当集群节点数量变化(新增/下线节点)或分片状态变化时,Master 会自动触发分片迁移,确保负载均衡;可通过
cluster.routing.rebalance.enable控制开关。
3. 故障转移机制
当主节点故障或主分片不可用时,ES 自动执行故障转移:
- 节点间通过 ZenDiscovery 协议选举新的主节点(需满足“法定人数”,避免脑裂,可配置
discovery.zen.minimum_master_nodes)。 - 新主节点将该主分片对应的副本分片升级为新的主分片。
- 重新创建缺失的副本分片,恢复集群状态为
green。
三、数据操作(CRUD)
ES 提供 RESTful API 用于数据交互,核心操作包括索引(Index)、查询(Search)、更新(Update)、删除(Delete)。
1. 文档操作
(1)创建文档(Index)
- 手动指定
_id:
1 | PUT /<index>/_doc/<_id> |
- 自动生成
_id(用 POST):
1 | POST /<index>/_doc/ |
(2)查询文档(Get)
- 按
_id精确查询:
1 | GET /<index>/_doc/<_id> |
- 查询文档是否存在:
1 | HEAD /<index>/_doc/<_id> # 200 存在,404 不存在 |
(3)更新文档(Update)
- 全量更新(覆盖原有文档,
_version自增):直接用PUT重写文档。 - 局部更新(仅修改指定字段):
1 | POST /<index>/_doc/<_id>/_update |
(4)删除文档(Delete)
1 | DELETE /<index>/_doc/<_id> |
2. 索引操作
(1)创建索引(含 Mapping)
1 | PUT /<index> |
(2)删除索引
1 | DELETE /<index> # 删除单个索引 |
(3)查看索引信息
- 查看索引设置:
GET /<index>/_settings - 查看索引 Mapping:
GET /<index>/_mapping - 查看索引统计信息:
GET /<index>/_stats
四、查询与分析
查询是 ES 的核心能力,支持全文检索、精确匹配、聚合分析等复杂场景,查询语法通过 Query DSL(Domain Specific Language)定义。
1. 查询类型分类
ES 的查询分为两大类:
| 类型 | 特点 | 代表查询 |
|---|---|---|
| 叶子查询(Leaf Queries) | 直接查询字段值,可单独使用 | 匹配查询(match)、精确匹配(term)、范围查询(range) |
| 复合查询(Compound Queries) | 组合多个叶子查询或其他复合查询 | 布尔查询(bool)、嵌套查询(nested)、函数评分查询(function_score) |
2. 常用核心查询
(1)匹配查询(match)
- 用于
text类型字段的全文检索,会对查询词分词后匹配。 - 示例:查询“手机”相关的商品(“智能手机”“手机壳”均会匹配):
1 | GET /products/_search |
(2)精确匹配(term)
- 用于
keyword或数值类型字段的精确匹配,不对查询词分词。 - 示例:查询分类为“手机”的商品(仅“手机”分类匹配,“智能手机”不匹配):
1 | GET /products/_search |
(3)范围查询(range)
- 用于数值、日期类型字段的范围筛选,支持
gt(>)、gte(≥)、lt(<)、lte(≤)。 - 示例:查询价格 1000-3000 元的商品:
1 | GET /products/_search |
(4)布尔查询(bool)
- 组合多个子查询,通过
must(必须匹配)、should(可选匹配,加分)、must_not(必须不匹配)、filter(过滤,不影响评分)控制逻辑。 - 示例:查询分类为“手机”、价格 1000-3000 元、标题含“华为”的商品:
1 | GET /products/_search |
3. 聚合分析(Aggregation)
聚合用于对查询结果进行统计分析(如分组、求和、排序),类似 SQL 的 GROUP BY + 聚合函数,分为桶聚合(Bucket) 和指标聚合(Metric)。
(1)桶聚合(Bucket)
- 按条件对数据分组,每个组称为一个“桶”,如按分类分组、按价格区间分组。
- 示例:按“category”字段分组,统计每个分类的商品数量:
1 | GET /products/_search |
(2)指标聚合(Metric)
- 对桶内数据进行数值计算,如求和、平均值、最大值等。
- 示例:按分类分组,统计每个分类的商品平均价格:
1 | GET /products/_search |
五、分词器(Analyzer)
分词是全文检索的核心步骤,将文本拆分为可索引的“词条(Term)”,ES 的分词能力依赖于分词器。
1. 分词器组成
一个完整的分词器由 3 部分组成:
- Character Filter(字符过滤器):预处理文本(如去除 HTML 标签、替换特殊字符),可选。
- Tokenizer(分词器):将文本拆分为词条(如按空格、标点拆分),必须。
- Token Filter(词条过滤器):处理词条(如小写转换、停用词移除、同义词替换),可选。
2. 内置分词器
- Standard Analyzer:默认分词器,按 Unicode 文本分割,小写转换,移除标点。
- Simple Analyzer:按非字母字符分割,小写转换。
- Whitespace Analyzer:仅按空格分割,不做其他处理。
- Keyword Analyzer:不分词,将整个文本作为一个词条。
3. 中文分词器
内置分词器对中文支持差(如将“我爱中国”拆分为“我”“爱”“中”“国”),需引入第三方分词器:
- IK Analyzer:最常用的中文分词器,支持自定义词典,有两种模式:
ik_max_word:最大粒度分词(如“中华人民共和国”→“中华人民共和国”“中华人民”“中华”“中国”等)。ik_smart:




