ES 基础
1. 倒排索引
1.1 什么是倒排索引
倒排索引是一种 从内容到文档的映射 数据结构,它和“正向索引”相反。
- 正向索引:文档 → 内容
- 倒排索引:内容(词语) → 出现该词语的文档列表
它的核心作用是 快速找到包含某个词的文档,是搜索引擎(比如 ElasticSearch、Lucene)最核心的数据结构。
1.2 举例说明
假设我们有 3 篇文档:
| 文档ID | 内容 |
|---|---|
| D1 | 我喜欢苹果和香蕉 |
| D2 | 苹果很好吃 |
| D3 | 香蕉和橘子都是水果 |
Step 1: 分词(简单按空格或词语切分)
- D1 → 我, 喜欢, 苹果, 和, 香蕉
- D2 → 苹果, 很好吃
- D3 → 香蕉, 和, 橘子, 都是, 水果
Step 2: 构建倒排索引
把每个词对应出现的文档列出来:
| 词语 | 文档列表 |
|---|---|
| 我 | D1 |
| 喜欢 | D1 |
| 苹果 | D1, D2 |
| 和 | D1, D3 |
| 香蕉 | D1, D3 |
| 很好吃 | D2 |
| 橘子 | D3 |
| 都是 | D3 |
| 水果 | D3 |
1.3 倒排索引的结构

如上图所示,倒排索引有如下核心结构:
1️⃣ 词条(Term)
- 文档经过 分析器(Analyzer) 处理后得到的最小索引单位。
- 可以是单词、符号、或者中文分词后的词。
英文分词比较简单,常用分词器包括:
| 分词器 | 说明 |
|---|---|
| standard | 默认分词器,按照空格、标点符号切分,并做小写处理。 |
| simple | 按非字母字符切分,忽略大小写,不做停用词过滤。 |
| whitespace | 仅按空格分词,不做其他处理。 |
| keyword | 不拆分整个字段,作为一个整体索引,常用于精确匹配。 |
| stop | 类似 standard,但会去掉停用词(如 “the”, “is”)。 |
中文没有天然的空格分词,需要专门的中文分词器。ElasticSearch 官方没有默认中文分词器,但常用插件有:
| 分词器 | 来源/说明 |
|---|---|
| ik_max_word | IK 分词器插件,尽可能切分出所有可能的词(最大化匹配),适合搜索场景。 |
| ik_smart | IK 分词器插件,智能切分,倾向于最自然的分词,适合精确匹配或分析场景。 |
| jieba | 基于 Python 的中文分词库,ElasticSearch 可通过插件或自定义分析器集成。 |
es 分词器配置:
|
|
2️⃣ 词典(Dictionary / Term Dictionary)
- 保存了索引中 所有唯一词条的集合,通常按字典序排序。
- 作用是快速查找某个词条是否存在,并定位它在倒排表中的位置。
3️⃣ 倒排表(Posting List)
- 是倒排索引的核心数据结构,用于快速定位匹配文档。
- 倒排表通常包含以下几个部分:
| 字段 | 说明 |
|---|---|
| 词项(Term) | 被索引的词,比如 “苹果” |
| 文档ID(DocID) | 出现该词的文档标识 |
| 词频(TF) | 词在文档中出现的次数,可选 |
| 位置(Position) | 词在文档中的顺序,用于短语搜索 |
| 偏移量(Offset) | 词在原文中的起止字符位置,用于高亮显示 |
4️⃣ 倒排文件(Inverted File)
- 倒排索引在磁盘上的物理存储文件,通常包含 词典 + 倒排表。
- Lucene/ElasticSearch 会将倒排表和词典压缩存储,提高查询效率。
2. 主节点选举
| 方面 | Zen1 | Zen2 优势 |
|---|---|---|
| 脑裂防护 | 依赖 minimum_master_nodes 配置,容易出错 |
使用 quorum(法定票数)+任期(term) 自动保证单主节点,几乎杜绝脑裂 |
| 选举算法 | 基于 cluster state 版本和节点 ID | 基于 Raft 共识变种,有明确的 term、投票和 Candidate 状态,更严格和可靠 |
| 状态同步 | 广播集群状态,可能有延迟和冲突 | Leader-Follower 模型,新主节点选出后,自动与大多数节点对齐最新状态 |
| 选举稳定性 | 网络抖动时容易选出落后节点 | 随机重试时间 + 任期控制,选举冲突概率低,收敛快 |
| 操作简化 | 管理员需配置 minimum_master_nodes |
无需配置,集群自动计算 quorum,提高易用性 |
| 故障恢复 | 网络分区后恢复慢,可能丢失元数据 | 网络分区恢复快,新 Leader 能自动同步最新集群状态 |
3. 集群元数据
4. Elasticsearch 写入与存储机制
4.1 延迟写策略(近实时搜索)
-
写入不是直接 fsync 到磁盘,而是先写入内存(JVM 堆)和文件系统缓存(操作系统内存),提升写入性能,避免每条数据都触发磁盘 I/O。
-
刷新(Refresh)机制:
- 默认每秒自动刷新一次,每个分片生成一个新的 段(Segment)。
- 内存中的数据刷新到文件系统缓存后即可被搜索,但尚未真正持久化到磁盘。
- 手动刷新:
POST /_refresh或POST /index/_refresh。 - 可调
refresh_interval优化写入性能(如日志批量写入时可延长刷新间隔)。
4.2 事务日志(Translog)保证数据安全
-
内存 + Translog 机制:
- 文档写入内存的同时,也追加写入事务日志。
- 避免断电或异常导致的数据丢失。
- Translog 用于重放未刷新到磁盘的写入。
4.3 Flush 机制(持久化)
-
触发条件:
- 内存数据或 Translog 达到一定大小(默认 512MB)
- 或时间超过阈值(默认 30 分钟)
-
操作:
- 内存数据写入新段(Segment)
- 文件系统缓存刷新到磁盘(fsync)
- 生成提交点(Commit Point)
- 清空旧 Translog,创建新的空日志
-
结果:保证数据持久化安全,即使重启或断电,也能通过提交点和 Translog 恢复所有数据。
4.4 核心流程图(文字版)
|
|
4.5 关键特点
- 近实时搜索:刷新后文档可搜索,但未必持久化。
- 高写入性能:延迟写减少频繁 fsync,利用内存和文件系统缓存。
- 数据安全:Translog + Flush 机制防止断电或重启丢失数据。
- 可调性:
refresh_interval和 flush 策略可根据业务需求优化写入性能或检索实时性。
5. term index
6. 参数调优
好的,我把你提供的文本内容整理成一个 Elasticsearch 性能优化参数表格,按参数/操作、作用、适用场景、注意事项列出:
| 参数 / 操作 | 作用 | 适用场景 | 注意事项 |
|---|---|---|---|
| 文档 ID 设计 | 使用有序、可压缩的序列模式 ID | 批量写入、Lucene 压缩优化 | 避免随机 UUID-4,会降低压缩比、拖慢索引性能 |
| Doc Values | 禁用不需要聚合/排序的字段的 Doc Values | 非聚合/排序字段 | 可以减少磁盘和内存开销,但无法用于聚合/排序 |
| 字段类型选择 | 不需要模糊检索的字段使用 Keyword 类型代替 Text 类型 | 精确匹配字段 | Keyword 字段不分词,索引更轻量 |
| refresh_interval | 调整索引刷新间隔 | 搜索结果不要求近实时 | 默认 1s,可改为 30s 提高写入性能 |
| refresh_interval(批量导入) | 导入期间设置为 -1 关闭刷新 | 大批量数据导入 | 导入完成后需恢复刷新,数据在导入期间不可搜索 |
| number_of_replicas | 导入期间设置为 0 关闭副本 | 大批量数据导入 | 导入完成后需恢复副本,否则节点宕机会丢数据 |
| 分页查询优化 | 使用 Scroll 查询代替深度分页 | 深度分页(from 很大)查询 | 避免普通分页造成的优先队列排序和 CPU 消耗 |
| 减少映射字段 | 只保留需要检索、聚合、排序的字段 | 高性能索引/查询 | 其他字段可存储在外部存储(如 HBase) |
| Routing | 创建索引和查询时指定路由值 | 精确查询、热点数据分片 | 路由值需保证数据均衡,避免单个分片压力过大 |
7. 向量数据库
在 7.3 版本开始,Elasticsearch 引入了 dense_vector 字段类型,用于存储和检索向量,逐步支持语义搜索、推荐系统、RAG 等场景。
所以现在 ES 既可以作为 全文搜索引擎,也能作为 向量数据库 使用。
7.1 向量存储方式
ES 提供两种主要的向量存储方式:
dense_vector
- 存储 浮点向量(dense vector)
- 典型用于存储 embedding 向量
- 可以指定维度(如
dims: 768)
例子:
|
|
sparse_vector
- 存储稀疏向量,通常用于 BM25 或传统稀疏表示
- 使用频率低于 dense_vector
7.2 相似度搜索
Elasticsearch 在向量检索上支持 ANN(Approximate Nearest Neighbor)索引,底层使用 HNSW (Hierarchical Navigable Small World) 图结构。
常见的相似度度量方式:
- cosine(余弦相似度,常用于语义搜索)
- l2_norm(欧几里得距离)
- dot_product(点积)
查询示例:
|
|
k: 返回的最近邻数量num_candidates: 候选数量,越大越准,但查询速度变慢
7.3 混合搜索 (Hybrid Search)
ES 向量检索的一大优势是可以直接和 全文检索 (BM25) 结合,实现 Hybrid Search。
常见模式:
- 向量搜索:语义相关性
- 关键字搜索:精确匹配
- 加权融合:比如 RRF(Reciprocal Rank Fusion)
例子:
|
|
7.4 向量数据库 vs 专门的向量引擎
Elasticsearch 的向量搜索和 Milvus / Weaviate / Pinecone / Qdrant 这些纯向量数据库相比,有以下特点:
优势
- 生态成熟:全文检索 + 向量检索一体
- 企业级安全、权限、集群、索引机制健全
- 混合搜索能力强,适合 RAG(LLM + ES)
- 内置 Kibana 可视化
劣势
- 索引和存储开销大(HNSW 内存占用高)
- 查询延迟比不上专门的向量库(但一般能接受)
- 向量写入更新性能略弱(HNSW 索引需要重构)