ElasticsearchNotes

第 01 章:认识 Elasticsearch

zjc 于 2026-01-01 发布

这是《Elasticsearch 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 Elasticsearch 常被简称 ES。它是一个基于 Lucene 构建的分布式搜索与分析引擎,对外提供 REST API,底层把数据拆成多个分片,分布在多个节点上执行搜索和聚合。

本章回答四个问题:

  1. Elasticsearch 到底是什么;
  2. 它和 MySQL、Redis、Kafka 有什么区别;
  3. 它擅长和不擅长什么场景;
  4. 学习它应该掌握哪些核心概念。

1.1 从一个搜索场景开始

假设电商系统里有 1 亿商品,用户在搜索框输入:

轻薄 高刷新率 笔记本

如果使用 MySQL 的 LIKE '%轻薄%',会遇到几个问题:

  1. 前置 % 无法利用普通 B+Tree 索引;
  2. 无法分词,搜“笔记本”不一定能匹配“笔记本电脑”;
  3. 无法计算相关性,结果没有业务排序;
  4. 无法高效组合全文匹配、类目过滤、价格排序和聚合统计;
  5. 大量模糊查询会给数据库带来较大压力。

Elasticsearch 的处理方式不同:

GET /products/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "query": "轻薄 高刷新率 笔记本",
            "fields": ["title^3", "category", "brand", "description"]
          }
        }
      ],
      "filter": [
        { "term": { "status": "ON_SALE" } },
        { "range": { "price": { "gte": 3000, "lte": 12000 } } }
      ]
    }
  },
  "aggs": {
    "brands": {
      "terms": { "field": "brand.keyword" }
    }
  }
}

这条请求会同时完成:

这就是 Elasticsearch 的典型能力。

1.2 Elasticsearch 是什么

可以把 Elasticsearch 理解为四层能力的组合:

能力 说明
存储层 JSON 文档存储 面向文档,弱 Schema,支持 Mapping
索引层 Lucene 倒排索引 支持分词、全文搜索、词项定位
分析层 聚合与指标 Bucket、Metric、Pipeline、时序分析
分布式层 分片与副本 水平扩展、容灾、并行查询

Elasticsearch 不是“带搜索接口的 MySQL”,也不是“更快的 Redis”。它为了搜索和分析做了大量专用结构,因此有些操作非常快,有些操作非常昂贵。

1.3 典型使用场景

1.3.1 站内搜索

场景:

核心需求:

分词准确 -> 召回相关 -> 业务过滤 -> 排序合理 -> 聚合筛选项 -> 响应低延迟

1.3.2 日志检索与可观测性

场景:

典型链路:

应用/Agent -> Filebeat/OpenTelemetry -> Kafka -> Logstash/Connector -> Elasticsearch -> Kibana

这类场景通常是写多读少、按时间分区、保留周期明确,适合索引生命周期管理。

1.3.3 数据分析

场景:

Elasticsearch 可以对大量文档执行聚合,但不是替代所有数仓的工具。它的优势是低延迟交互式分析,劣势是复杂 Join、大规模扫描和精确去重成本较高。

1.3.4 安全与风控

场景:

常见组合是规则引擎、实时特征、Elasticsearch 检索和离线模型训练。

1.3.5 向量与混合搜索

Elasticsearch 8.x 增强 dense_vector 与 kNN 搜索,可用于:

向量搜索通常和关键词搜索组合使用,也就是混合搜索。

1.4 与其他系统对比

1.4.1 Elasticsearch vs MySQL

维度 Elasticsearch MySQL  
数据模型 JSON 文档 关系表  
查询语言 Query DSL、SQL、ES QL SQL
全文搜索 强,倒排索引与分词 弱,LIKE 或全文索引有限  
事务 不支持通用 ACID 事务 支持完整事务  
关联查询 弱,避免复杂 Join  
聚合分析 强,适合交互式分析 适合确定型报表  
更新 文档级替换,代价较高 行级更新成熟  
一致性 近实时,默认秒级可见 事务提交后可见  

常见分工:

MySQL:事实源、事务、账务、唯一约束
Elasticsearch:搜索投影、分析视图、日志检索

1.4.2 Elasticsearch vs Redis

维度 Elasticsearch Redis
定位 搜索与分析引擎 内存键值与缓存
延迟 通常毫秒到几百毫秒 亚毫秒到毫秒
数据结构 文档、倒排、向量 String、Hash、ZSet 等
全文搜索 基本不具备
聚合 有限
内存成本 JVM Heap + Page Cache 核心数据在内存

常见组合:Redis 缓存热点结果,Elasticsearch 承担搜索召回和聚合。

1.4.3 Elasticsearch vs Kafka

维度 Elasticsearch Kafka
定位 搜索与分析存储 分布式事件日志
数据保留 索引生命周期 retention 滚动保留
消费模型 查询式拉取 offset 连续消费
回放 不适合作为原始事件回放源 强项
分析 本身不做分析

常见链路:

业务 -> MySQL -> CDC -> Kafka -> Elasticsearch

Kafka 保证传输与回放,Elasticsearch 提供查询视图。

1.4.4 Elasticsearch vs OpenSearch

OpenSearch 是从 Elasticsearch 7.10 分叉出的开源项目,两者核心思想相近,但版本演进、许可证、API 细节、插件生态和云服务支持逐渐分化。

选型时要关注:

  1. 目标版本许可证;
  2. 是否需要官方 Elasticsearch 能力;
  3. Kibana 与 OpenSearch Dashboards 生态;
  4. 安全、SQL、向量检索能力;
  5. 云厂商托管方案;
  6. 团队运维经验。

1.5 为什么搜索不能只靠数据库

搜索系统通常分为四个阶段:

理解查询 -> 召回候选 -> 过滤排序 -> 返回结果与统计

数据库更擅长“精确条件查询”,例如:

SELECT * FROM product WHERE id = 10001;
SELECT * FROM product WHERE category_id = 3 AND price < 5000;

搜索更擅长“模糊语义匹配”,例如:

用户输入:苹果手机充电快
匹配字段:title、brand、category、tags、description
期望结果:相关品牌、相关类目、相关描述
排序依据:文本相关性 + 销量 + 新品 + 库存 + 业务权重

这需要分词、倒排索引、词频、文档频率、字段权重、过滤器缓存和聚合能力。Elasticsearch 正是围绕这些问题设计的。

1.6 近实时是什么意思

Elasticsearch 通常被称为近实时搜索引擎。

写入文档后,数据先进入内存 buffer 和 translog,经过 refresh 生成可搜索的 segment。默认情况下,refresh 大约每秒一次,所以写入后通常需要等待不到一秒才能被搜索到。

写入 -> translog + buffer -> refresh -> 可搜索
                  |
                  +-> flush -> fsync + 清空 translog

这不是“实时数据库”的强一致可见性。业务如果要求写入后立即可见,需要:

  1. 调用 GET_id 读取;
  2. 手动 refresh,但这会带来性能成本;
  3. 在业务层等待或异步确认;
  4. 重新设计一致性链路。

不要把 Elasticsearch 当作 MySQL 的强一致替代品。

1.7 Elasticsearch 的基本组件

概念 类比 说明
Node 数据库实例 一个 ES 进程
Cluster 数据库集群 一组 Node
Index 表或文档集合 逻辑搜索命名空间
Document 一行数据 JSON 文档
Field 文档中的字段
Mapping 表结构 字段类型与分析方式
Shard 分区 Lucene 实例,数据物理分片
Replica 副本 主分片拷贝,提供容灾和读并发
Segment 内部索引文件 不可变倒排索引单元
Alias 视图或软链接 指向一个或多个索引

注意:Index 与数据库中的“索引”不是同一个概念。ES 的 Index 更像“表的集合”,真正用于搜索的是每个分片里的 Lucene 索引。

1.8 学习 Elasticsearch 的常见误区

误区 实际情况
ES 可以替代数据库 大多数业务仍需要数据库作为事实源
分片越多越好 分片过多会增加内存、调度和查询开销
ES 查询永远很快 深分页、大聚合、 wildcard、脚本都可能很慢
Mapping 可以随便动态生成 错误类型会导致后续重建索引
写入后立刻能查到 默认近实时,通常有刷新延迟
副本越多越好 副本增加磁盘、写入放大和内存开销
聚合结果是绝对精确的 有些场景存在近似算法与终端归并误差

1.9 一个最小学习环境

本章不展开安装细节,只给出学习路径:

1. 启动 Elasticsearch
2. 启动 Kibana
3. 打开 Dev Tools
4. 创建 products 索引
5. 写入 3 条商品文档
6. 执行 match 查询
7. 执行 terms 聚合

具体安装与配置见第 3 章。

1.10 本章小结

1.11 思考题

  1. 你的系统里哪些数据适合放 Elasticsearch?哪些必须留在 MySQL?
  2. “写入成功”和“写入后立即可搜索”在 Elasticsearch 中是否等价?为什么?
  3. 商品搜索和订单报表对 ES 的要求有什么不同?
  4. 如果让你把 MySQL 商品表同步到 ES,你会选择全量、增量还是 CDC?
  5. 为什么不能简单说“Elasticsearch 比 MySQL 快”?