订阅更新

Elasticsearch 为什么搜索快?写入后为什么不能立刻搜到?

面试问 361 约 2 分钟读完

随机一题
本文目录
  1. 面试怎么回答
  2. 为什么搜索快:倒排索引
  3. 分片和副本
  4. 写入后为什么不能立刻搜到
  5. 写入优化

面试怎么回答

ES 基于 Lucene 的倒排索引,先分词再建立「词到文档列表」的映射,查询时直接取列表做交并集,所以全文检索快;排序和聚合则用列式的 doc values。索引拆成多个主分片并行处理,副本负责容灾和分担读。写入先进内存缓冲并记 translog,默认每秒 refresh 一次生成新 segment 才能被搜到,所以是近实时。大批量导入时我会调大 refresh 间隔、临时去掉副本、用 bulk 写入。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

日志检索、商品搜索常用 Elasticsearch,面试官会问:它为什么能快速做全文检索?数据刚写进去为什么查不到?

为什么搜索快:倒排索引

传统数据库按行存储,查「包含某个词的文档」要逐行扫描。

ES 底层的 Lucene 用倒排索引:先对文本分词,再建立「词 → 包含该词的文档列表」的映射。查询时直接找到词对应的文档列表,多个词的条件就是对几个列表做交集、并集。词典本身也有前缀压缩的索引结构,查词很快。

除了倒排索引,ES 还为字段建了列式存储(doc values),用于排序和聚合。

分片和副本

一个索引被拆成多个主分片,分布在不同节点上并行处理;每个主分片可以有副本,用于容灾和分担查询。主分片数在建索引时确定,之后修改需要重建索引,所以要提前按数据量规划。

写入后为什么不能立刻搜到

写入的数据先进入内存缓冲区,同时写 translog(类似 WAL)保证不丢;默认每隔 1 秒执行一次 refresh,把缓冲区的数据生成一个新的 segment,这时才能被搜索到。所以 ES 是近实时的,默认延迟在 1 秒左右。

segment 会越来越多,后台会合并(merge)小 segment;flush 会把数据真正落盘并清空 translog。

写入优化

大批量导入时可以临时把 refresh 间隔调大或关闭、把副本数设为 0,导入完成后再恢复;使用 bulk 批量写入;合理设置分片数,避免分片过多。