Elasticsearch 保姆级入门:从"找文件"到"秒级搜索"
- [Elasticsearch 保姆级入门:从"找文件"到"秒级搜索"](#Elasticsearch 保姆级入门:从“找文件”到“秒级搜索”)
-
- [1. 先讲个故事:从一个"超级笔记本"说起](#1. 先讲个故事:从一个“超级笔记本”说起)
- [2. Elasticsearch 是什么?](#2. Elasticsearch 是什么?)
- [3. Elasticsearch 的核心------Lucene](#3. Elasticsearch 的核心——Lucene)
- [4. Elasticsearch 的核心概念(让小白秒懂)](#4. Elasticsearch 的核心概念(让小白秒懂))
- [5. Elasticsearch 的架构(一图胜千言)](#5. Elasticsearch 的架构(一图胜千言))
-
- [5.1 集群(Cluster)](#5.1 集群(Cluster))
- [5.2 节点(Node)](#5.2 节点(Node))
- [5.3 分片(Shard)](#5.3 分片(Shard))
- [5.4 写入流程(简化)](#5.4 写入流程(简化))
- [5.5 查询流程(两阶段)](#5.5 查询流程(两阶段))
- [6. 为什么 Elasticsearch 搜索这么快?(通俗版)](#6. 为什么 Elasticsearch 搜索这么快?(通俗版))
-
- [6.1 倒排索引(Inverted Index)](#6.1 倒排索引(Inverted Index))
- [6.2 分词(Analysis)](#6.2 分词(Analysis))
- [6.3 段(Segment)合并与刷新](#6.3 段(Segment)合并与刷新)
- [7. 倒排索引 VS 数据库 B+ 树索引](#7. 倒排索引 VS 数据库 B+ 树索引)
- [8. 一个完整的例子(让你看到 JSON)](#8. 一个完整的例子(让你看到 JSON))
- [9. 总结一张表](#9. 总结一张表)
- [10. 学习路线(写给新手)](#10. 学习路线(写给新手))
Elasticsearch 保姆级入门:从"找文件"到"秒级搜索"
你有没有在几万份 Word 里搜过一个关键词,等了几分钟才出结果?
如果数据是 1TB 的日志、10 亿条订单,用普通方法可能等到天荒地老。
Elasticsearch(ES) 就是解决"海量数据快速搜索"的利器。
1. 先讲个故事:从一个"超级笔记本"说起
你有一本 10000 页的百科全书,想找出所有提到"熊猫"的地方。
- 传统方法(数据库 like 查询):从第一页翻到最后一页,一页一页看。翻完一本书要 2 小时。
- ES 的方法 :先给全书编一个目录------把每个词出现在哪些页记下来。以后查"熊猫",直接翻目录,1 秒钟就找到所有页码。
ES 做的就是这个事:它先给数据建立"倒排索引",然后搜索的时候直接查索引,而不是翻原文。
2. Elasticsearch 是什么?
一句话定义 :
Elasticsearch 是一个开源的、分布式、RESTful 风格的实时搜索和分析引擎。
- 开源:免费使用,社区活跃。
- 分布式:可以扩展到成千上万台服务器,处理 PB 级数据。
- RESTful:用 HTTP 接口 + JSON 数据,任何编程语言都能调用。
- 实时:数据写入后,近实时(约 1 秒)就能被搜索到。
- 搜索+分析:不仅能查,还能做聚合统计(比如按月份统计销售额)。
ES 最著名的应用场景:
- 全文搜索(维基百科、GitHub、电商商品搜索)
- 日志分析(ELK 技术栈:Elasticsearch + Logstash + Kibana)
- 指标监控(比如每秒请求量、错误率)
3. Elasticsearch 的核心------Lucene
ES 并非从零发明,而是基于一个叫 Lucene 的 Java 库构建的。
Lucene 是什么?
- 一个高性能、全功能的文本搜索引擎库。
- 它提供了索引和搜索的核心能力:倒排索引、分词、相关性排序等。
- 但它只是一个库,不是开箱即用的服务。你需要自己写 Java 代码来调用它,处理并发、分布式、集群管理等。
Elasticsearch 做了什么?
把 Lucene 包装成一个分布式、易用的服务:
- 把 Lucene 的索引变成了分片(shard),可以分布到多台机器。
- 提供 HTTP API,不再需要写 Java。
- 自动处理节点发现、故障转移、数据均衡。
类比:Lucene 是发动机 ,ES 是整车。发动机很牛,但普通人没法直接坐发动机上跑;ES 把发动机装进车里,配上方向盘、座椅、导航,你只管开。
4. Elasticsearch 的核心概念(让小白秒懂)
| ES 概念 | 类比 MySQL | 解释 |
|---|---|---|
| Index(索引) | Database | 一类相似文档的集合,比如"订单索引""商品索引"。 |
| Type(类型) | Table | 7.x 版本已经废弃,一个索引通常只放一种文档。 |
| Document(文档) | Row | 一条 JSON 数据,比如某条订单。 |
| Field(字段) | Column | JSON 里的一个键值对。 |
| Mapping(映射) | Schema | 定义字段类型(字符串、数字、日期等),类似表结构。 |
| Shard(分片) | 水平分表 | 把一个索引切成多份,分散到不同服务器。 |
| Replica(副本) | 从库/备份 | 每个分片的备份,提高查询性能和数据可靠性。 |
一个更生活化的比喻
- Index:一个大抽屉柜(比如"档案室")。
- Document:抽屉里的一个档案袋(里面装着一个人的信息)。
- Shard:把抽屉柜拆成几个小抽屉,分到不同房间存放。
- Replica:每个小抽屉都复制一份放到另一个房间,防止失火烧毁。
5. Elasticsearch 的架构(一图胜千言)
┌─────────────┐
│ App / Kibana │
└───────┬─────┘
│ HTTP (JSON)
┌────────────────┼────────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Node1 │ │ Node2 │ │ Node3 │
│ (Master) │ │ │ │ │
├──────────┤ ├──────────┤ ├──────────┤
│ 主分片0 │◄───►│ 副本分片0│ │ 主分片1 │
│ 主分片2 │ │ 主分片1 │◄───►│ 副本分片1│
│ 副本分片2│ │ 副本分片0│ │ 副本分片2│
└──────────┘ └──────────┘ └──────────┘
5.1 集群(Cluster)
- 一组 Node 的集合,共同持有完整数据。
- 有一个主节点(Master Node),负责管理集群状态(创建/删除索引、分配分片)。
5.2 节点(Node)
- 一台服务器上的 ES 实例。
- 角色可分为:Master(管理节点)、Data(存储数据)、Ingest(预处理)、Coordinating(路由请求)。
5.3 分片(Shard)
- 主分片(Primary Shard) :索引被拆分成若干份,每一份是一个主分片。
例如,你创建索引时指定number_of_shards: 3,那么数据会被分成 3 份,每份包含一部分文档。 - 副本分片(Replica Shard) :主分片的完整拷贝。
副本不能和主分片在同一个节点上。提高查询吞吐量和容错性。
5.4 写入流程(简化)
- 客户端请求发到任意 Node(协调节点)。
- 协调节点计算文档应该去哪个主分片(通过路由公式
hash(routing) % number_of_shards)。 - 请求转发到主分片所在的 Node。
- 主分片写入 Lucene 索引,同时将请求发送到所有副本分片。
- 至少等待
replication数量的副本成功(默认是 1,即主分片成功即可),然后返回成功。
5.5 查询流程(两阶段)
- 分散阶段(Query Phase):协调节点将查询发送到所有分片(主或副都可以)。每个分片执行搜索,返回文档 ID 和排序值(不是完整文档)。
- 聚合阶段(Fetch Phase):协调节点对返回的 ID 列表全局排序,选出真正需要的那一页(比如前 10 条),再去各个分片拉取完整的文档内容。
这个机制保证了即使数据分布在几十个节点上,搜索依然快如闪电。
6. 为什么 Elasticsearch 搜索这么快?(通俗版)
6.1 倒排索引(Inverted Index)
这是 Lucene 的"杀手锏"。
对于每个词(term),记录它出现在哪些文档里。
示例 :
文档1:我喜欢熊猫
文档2:熊猫爱吃竹子
建立的倒排索引:
| 词 | 出现文档 |
|---|---|
| 我 | Doc1 |
| 喜欢 | Doc1 |
| 熊猫 | Doc1, Doc2 |
| 爱吃 | Doc2 |
| 竹子 | Doc2 |
搜索"熊猫"时,直接查到 Doc1, Doc2,不需要扫描全文。
6.2 分词(Analysis)
搜索"我喜欢熊猫",如果原封不动去匹配,可能找不到"熊猫爱吃竹子"。
ES 在索引时会把句子切成一个个独立的词(分词器),搜索时也会把查询词切分。
这样"熊猫"就能匹配到含有"熊猫"的文档。
6.3 段(Segment)合并与刷新
Lucene 把索引分成多个不可变的"段"。
- 新增文档会先写入内存缓冲区,定期生成新的段。
- 删除不是物理删除,而是记录在".del"文件里。
- 段过多会影响性能,后台线程会自动合并小的段成大的段。
这样保证了:写入不阻塞搜索,搜索时最多只查询几个段,效率高。
7. 倒排索引 VS 数据库 B+ 树索引
| 对比 | B+树索引(如MySQL) | 倒排索引(Lucene/ES) |
|---|---|---|
| 适合场景 | 精确查询、范围查询、更新频繁 | 全文搜索、模糊匹配、相关性排序 |
| 查询原理 | 从根节点遍历到叶子,找到数据行 | 根据词直接跳到文档列表 |
| 模糊查询 | 通常走全表扫描(慢) | 支持分词后部分匹配(快) |
| 相关性排序 | 不支持(除非手工算TF-IDF) | 内置BM25算法自动排序 |
| 写性能 | 较好(就地更新) | 较差(需要重建段,不能原地修改) |
所以 ES 不适合做频繁更新 的强事务系统,它最擅长的是海量数据快速检索。
8. 一个完整的例子(让你看到 JSON)
json
// 创建一个名为 "goods" 的索引
PUT /goods
// 插入一条商品文档
POST /goods/_doc/1
{
"name": "Apple iPhone 14 Pro",
"price": 7999,
"tags": ["手机", "苹果", "5G"]
}
// 搜索:找名字里包含 "iPhone" 的商品
GET /goods/_search
{
"query": {
"match": {
"name": "iPhone"
}
}
}
ES 返回的结果中包含:
- 命中的文档
- 每个文档的相关性得分
_score - 汇总信息(总共命中多少条)
9. 总结一张表
| 问题 | 答案 |
|---|---|
| ES 是什么? | 分布式、实时的搜索分析引擎。 |
| Lucene 是什么? | 底层的 Java 搜索库,提供倒排索引能力。 |
| ES 和 Lucene 关系? | ES 把 Lucene 封装成分布式、易用的服务。 |
| 核心数据结构? | 倒排索引(词→文档列表)。 |
| 如何分布式? | 索引拆成多个分片,分散到不同节点,每个分片可有副本。 |
| 为什么快? | 倒排索引 + 段合并 + 内存缓存 + 轻量级通信。 |
| 不适合做什么? | 频繁更新、多表关联、事务强一致场景。 |
10. 学习路线(写给新手)
- 本地安装 :去官网下载 Elasticsearch,解压,运行
bin/elasticsearch。 - 学用 REST API :用
curl或 Postman 练习创建索引、增删改查。 - 安装 Kibana:可视化工具,还有 Dev Tools 控制台,方便测试。
- 学查询语法 :
term、match、bool、range、aggregation。 - 理解分词 :用
_analyzeAPI 查看分词结果。 - 深入原理:倒排索引、段合并、分片分配、故障转移。
当你用 ES 能在 1 秒内从 1TB 日志里找到某个错误信息时,你会爱上它的。
最后送你一句话:
数据库是存数据的仓库,Elasticsearch 是找东西的百度。
它们不是替代关系,而是黄金搭档------数据库负责可靠存储,ES 负责闪电检索。
希望这篇博客能帮你推开全文搜索的大门。有问题欢迎留言讨论~