核心原理
倒排索引
关系数据库常从记录定位字段,全文检索则需要从词项反查文档。Elasticsearch 分析文本后建立“词项 → 文档”的倒排索引,并保存词频、位置等信息用于匹配与相关性计算。
text
文档 1: distributed search engine
文档 2: distributed log system
distributed -> [1, 2]
search -> [1]
log -> [2]写入成功后,新文档需要经过 Refresh 才能被搜索,因此 Elasticsearch 是近实时搜索;按 ID 获取文档与搜索走的路径不同,不能用刚写入后暂时搜不到来判断数据丢失。
集群对象
| 对象 | 作用 |
|---|---|
| Cluster | 共享集群状态的一组节点 |
| Node | 一个 Elasticsearch 实例,可承担主节点、数据节点或协调节点等角色 |
| Index | 具有统一 Mapping 和 Settings 的文档集合 |
| Primary Shard | 数据分片的主副本,决定索引的水平拆分数量 |
| Replica Shard | 主分片副本,提供容灾并分担读取 |
| Segment | Lucene 中不可变的索引片段,后台会合并 |
主分片数影响数据分布和长期扩展边界,副本数可以动态调整。分片不是越多越好:每个分片都会消耗堆内存、文件句柄和集群状态资源。
写入流程
默认路由依据文档 _id 计算。自定义 routing 可以把相关文档放入同一分片,但查询也必须携带相同 routing,并要避免热点键。
搜索流程
搜索通常分为两个阶段:
- Query 阶段由协调节点向相关分片广播,各分片返回排序后的文档 ID 和分数。
- Fetch 阶段由协调节点获取最终命中的
_source,再合并返回。
深分页会让每个分片维护大量候选结果。交互式翻页使用 search_after,批处理遍历使用 Point in Time 配合 search_after,避免长期使用很大的 from + size。
故障与一致性边界
- 主分片不可用时,该分片不能写入;选举出新的主分片后恢复。
- 副本只有分布在不同节点上才具有节点级容灾价值。
- 文档更新本质上是生成新版本并使旧版本失效,不是原地修改 Lucene Segment。
- 并发更新可使用
_seq_no与_primary_term做乐观并发控制。 - Elasticsearch 不提供关系数据库式的跨文档事务、外键和 Join 语义,数据建模通常采用反范式。