ES中的倒排索引是什么?

242 阅读3分钟

你好,我是风一样的树懒,一个工作十多年的后端专家,曾就职京东、阿里等多家互联网头部企业。公众号“吴计可师”,已经更新了过百篇高质量的面试相关文章,喜欢的朋友欢迎关注点赞

Elasticsearch中的倒排索引(Inverted Index)是搜索引擎最核心的数据结构,也是其实现毫秒级搜索的关键。下面从本质原理、数据结构、工作流程、生产优化四个维度深度解析


deepseek_mermaid_20250716_7baf80.png

核心区别

  • 正排索引:通过文档ID查找内容(类似数据库主键查询)
  • 倒排索引:通过关键词查找文档ID(类似书籍末尾的索引表)

二、倒排索引的底层数据结构(Lucene级详解)

1. 核心组成部件

组件作用物理文件数据结构
词项字典(Term Dictionary)存储所有唯一词项.timFST压缩字典
词项索引(Term Index)加速词项字典定位.tip前缀树索引
倒排列表(Postings List)存储包含词项的文档ID及词频.docFOR压缩编码
位置数据(Positions)存储词项在文档中的位置.posDelta编码
偏移量(Offsets)存储词项在文档中的起止位置.pay差分编码

2. 倒排列表的物理结构

| 文档ID (DocID) | 词频 (TF) | 位置 (Position) | 偏移量 (Offset) |
|----------------|-----------|----------------|----------------|
| 1001           | 3         | [5, 20, 45]    | [0-4, 15-19]   |
| 1005           | 1         | [12]           | [50-54]        |

三、倒排索引的工作流程(以搜索"Java"为例)

sequenceDiagram
    participant User
    participant ES_Coordinator
    participant Shard1
    participant Lucene
    
    User->>ES_Coordinator: 搜索"Java"
    ES_Coordinator->>Shard1: 路由到目标分片(hash("Java")%shards)
    Shard1->>Lucene: 查询词项字典
    Lucene->>Lucene: 加载.tip文件(FST前缀匹配)
    Lucene->>Lucene: 定位.tim文件中的"Java"词项
    Lucene->>Lucene: 读取.doc文件中的倒排列表
    Lucene->>Shard1: 返回DocID[1001,1005]
    Shard1->>ES_Coordinator: 返回文档ID
    ES_Coordinator->>User: 合并展示结果

关键步骤

  1. 词项定位:通过FST在内存中快速定位词项
  2. 倒排表读取:从磁盘加载压缩的倒排列表
  3. 文档过滤:结合过滤器(如布隆过滤器)跳过无关文档

四、倒排索引的极致优化技术

1. 压缩算法对比

算法适用场景压缩率解码速度
FOR (Frame of Reference)有序整数数组3-5x★★★★
PForDelta (Patched Frame of Reference)大数值数组4-6x★★★☆
Roaring Bitmaps稀疏文档ID集合5-10x★★★★★

2. 内存加速策略

// 启用文档值(Doc Values)加速聚合
PUT /products
{
  "mappings": {
    "properties": {
      "price": {
        "type": "integer",
        "doc_values": true  // 列式存储加速聚合
      }
    }
  }
}

3. 防止词项爆炸(Term Explosion)

# 限制字段长度避免内存溢出
PUT /logs
{
  "settings": {
    "index.mapping.ignore_malformed": true  // 跳过格式错误文档
  },
  "mappings": {
    "properties": {
      "message": {
        "type": "text",
        "ignore_above": 8192  // 忽略超过8KB的文本
      }
    }
  }
}

五、生产环境最佳实践

1. 分片设计黄金法则

- **分片大小**:20GB-50GB(SSD)/ 10GB-30GB(HDD)
- **分片数量**`数据总量(GB) / 30GB` + 2(冗余)
- **热冷分离**:对时间序列数据使用ILM(Index Lifecycle Management)

2. 高性能写入优化

# 批量写入配置(logstash场景)
output {
  elasticsearch {
    hosts => ["es-node:9200"]
    flush_size => 10000      # 每1万条刷新
    idle_flush_time => 10     # 空闲10秒刷新
    index => "logs-%{+YYYY.MM.dd}"
  }
}

3. 查询加速技巧

// 使用constant_score跳过相关性计算
GET /products/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": { "category": "electronics" }
      }
    }
  }
}

六、倒排索引的典型应用场景

场景倒排索引的作用优化重点
商品搜索快速匹配商品名称/描述中文分词优化
日志分析关键词过滤(如errorcode=500)稀疏字段压缩
用户画像标签组合查询(性别=男&兴趣=体育)Roaring Bitmaps
法律文本检索精确短语匹配(“专利侵权”)位置数据索引

今天文章就分享到这儿,喜欢的朋友可以关注我的公众号,回复“进群”,可进免费技术交流群。博主不定时回复大家的问题。 公众号:吴计可师