ElasticSearch 面试题

6 阅读13分钟

ElasticSearch 面试题集锦

整理自真实面试问答,涵盖 ES 核心概念、索引结构、查询优化、集群管理等高频考点。


一、基础概念

Q1: ElasticSearch 用的是哪个版本?

A: ElasticSearch 版本众多,当前主流版本为:

  • ES 7.x / 8.x(最新稳定版)
  • 7.x 版本引入了新的集群协调子系统,去除了 Type 的概念
  • 8.x 版本默认开启了安全特性(HTTPS、安全配置向导)

生产环境推荐使用 7.x 或 8.x 稳定版,避免使用过旧的 5.x/6.x。


Q2: ElasticSearch 的默认端口是多少?

A:

  • 9200:RESTful API 端口,用于客户端通信
  • 9300:节点间通信(Transport)端口,用于集群内部通信

访问示例:http://localhost:9200


Q3: 为什么要用 ElasticSearch?

A:

对比维度MySQL/关系型数据库ElasticSearch
数据量千万级以下高效亿级数据毫秒响应
搜索方式LIKE 模糊查询(全表扫描)倒排索引(精准高效)
全文检索能力弱强大,支持分词、相关性排序
实时性实时写入近实时(NRT ≈ 1秒)
扩展性垂直扩展为主水平扩展,天然分布式
聚合分析聚合能力强大

典型使用场景

  • 海量数据全文检索
  • 日志分析(ELK)
  • 商品搜索、站内搜索
  • 复杂条件组合查询

Q4: ElasticSearch 为什么快?

A:

  1. 倒排索引(Inverted Index)

    • 词 → 文档的映射,查询时 O(1) 定位
    • 无需扫描全表
  2. 分片机制(Sharding)

    • 数据分散到多个分片,并行查询
    • 天然支持横向扩展
  3. 多种缓存

    • Segment Cache(段级缓存)
    • Filter Cache(过滤器缓存)
    • Query Cache(查询缓存)
  4. 零跳跃(Skip List / FST)

    • 使用 FST(Finite State Transducer)实现前缀树压缩
    • 查询跳表加速定位
  5. 写入优化

    • 写入时先写内存和 Translog,定期刷盘生成 Segment
    • 段文件只读不可变,避免随机写

二、索引与数据结构

Q5: ElasticSearch 的索引结构是啥样的?

A: ES 索引的层级结构:

Index(索引)
├── Shard(分片)
│   ├── Primary Shard(主分片)
│   └── Replica Shard(副本分片)
├── Segment(段)
│   ├── _segments.json(元数据)
│   ├── FST(倒排索引)
│   ├── doc_values(列式存储)
│   └── norms(评分因子)
└── Translog(事务日志)

核心特点

  • 每个分片是一个独立的 Lucene 索引
  • Segment 是实际存储数据的文件集合,只读不可变
  • 新数据先写入内存 buffer,定期刷新(flush)生成新 Segment
  • Translog 保证数据可靠性(类似 MySQL redo log)

Q6: ElasticSearch 深度分页问题怎么解决?

A: 问题本质:深度分页(如第 10000 页)需要汇总大量分片数据,资源消耗巨大。

解决方案

方案说明
Scroll API适合大数据导出,滚动翻页,内部维护快照
Search After基于排序值游走,适合实时翻页,不支持跳页
PIT(Point In Time)ES 7.x+ 引入,比 Scroll 更灵活
限制 max_result_window默认 10000 条,超出需申请

Search After 示例

GET /index/_search
{
  "size": 10,
  "sort": [{"create_time": "desc"}, {"_id": "asc"}],
  "search_after": [1640000000000, "doc_id_123"]
}

Q7: ElasticSearch 的算分方式有哪些?

A: ES 使用 TF-IDF 相关性评分算法,核心公式基于 Lucene 的 Practical Scoring Function:

score(q,d) = queryNorm(q) · coord(q,d) · Σ(t in q) [ tf(t in d) · idf(t)² · t.getBoost() · norm(t,d) ]

关键算分因素

因子说明
TF(词频)词在文档中出现次数越多,相关性越高
IDF(逆文档频率)词在越少文档中出现,权重越高
boost字段/查询权重提升
norm字段长度归一化因子
coord查询词命中比例

常用算分模型

  • BM25(ES 5.0+ 默认,可配置参数 k1、b)
  • boolean(不做评分,返回 0/1)
  • constant_score(固定分数)
  • function_score(自定义函数评分)

Q8: ElasticSearch 的分词算法有哪些?

A: 按粒度分类

  • Standard(标准分词):按单词切分,适合英文
  • Simple:按非字母字符切分
  • Whitespace:按空格切分
  • Keyword:不分词,保留原样
  • Pattern:正则分词

中文分词器

  • IK:最常用,支持细粒度和智能分词
  • jieba:结巴分词,Python 生态常用
  • hanlp:支持多种分词模式
  • THULAC:清华开源,标注式分词

分词器组成

分词器(Analyzer)= 字符过滤器(Character Filter+ 分词器(Tokenizer)+ 词元过滤器(Token Filter

三、项目实战

Q9: 项目中数据量有多少?怎么还用 ES 了?

A: 回答思路

  1. 说明数据量规模(如:日增 100 万+,总量数亿)
  2. 阐述业务痛点(MySQL 查询慢、无法满足复杂检索)
  3. ES 带来的效果(毫秒级响应、用户体验提升)

示例回答

项目中我们有约 5000万+ 的商品数据,高峰期日增 50 万。使用 MySQL 的 LIKE 查询在千万级数据下响应超过 3 秒,用户体验很差。引入 ES 后,通过倒排索引和分片并行查询,P99 响应时间控制在 50ms 以内,同时支持复杂的组合条件查询和全文检索。


Q10: 项目中 ElasticSearch 的使用步骤?

A:

1. 数据同步
   ├── Logstash / Canal 监听 MySQL binlog
   ├── 定时任务全量/增量同步
   └── MQ 消息队列异步写入

2. 索引设计
   ├── 定义 Mapping(字段类型、分词器)
   ├── 配置分片数(建议 3-5 个 Primary Shard)
   └── 设置副本数(一般 1-2 个 Replica)

3. 数据写入
   ├── Bulk API 批量写入
   └── 控制写入频率(避免写入过快导致集群压力)

4. 查询开发
   ├── Bool Query 组合查询
   ├── 高亮显示
   └── 聚合统计

5. 性能优化
   ├── 冷热数据分离
   ├── 路由优化(routing)
   └── 缓存优化

Q11: 什么场景适合使用 ElasticSearch?

A:

场景说明
全文检索站内搜索、商品搜索、文档检索
日志分析ELK 日志收集与分析
数据分析聚合统计、实时仪表盘
地理搜索LBS 附近的人/商家
模糊匹配拼音搜索、错别字容错
复杂查询多条件组合、嵌套查询

不适合场景

  • 强事务要求(使用 MySQL/PostgreSQL)
  • 频繁更新/删除(段合并开销大)
  • 简单 K-V 查询(使用 Redis/HBase)

四、ELK 生态与集成

Q12: ELK 知道是啥吗?

A: ELK 是 Elastic Stack 的简称:

组件作用
Elasticsearch搜索引擎、存储、检索
Logstash数据收集、过滤、转换
Kibana数据可视化、Web UI
Beats轻量级数据采集器(Filebeat、Metricbeat 等)

数据流向

日志源 → Beats/Logstash → Elasticsearch → Kibana
         (采集/过滤)    (存储检索)    (可视化)

Q13: ElasticSearch 和 MySQL 的数据如何保证一致性?

A: 同步方案对比

方案原理优点缺点
双写写 MySQL 时同步写 ES实现简单一致性难以保证
异步双写MQ 异步同步解耦、可用性高延迟、数据丢失风险
Canal 监听监听 binlog 同步侵入性低运维复杂
DataX/ETL定时全量/增量同步简单可靠实时性差

最佳实践

  • 核心交易数据:Canal + MQ 保证最终一致性
  • 日志类数据:Logstash 直接采集,允许短暂不一致
  • 定期对账补偿机制

Q14: ElasticSearch 的倒排索引解释下,跟正排索引有什么区别?

A: 正排索引(Forward Index)

文档 → 词列表
doc1 → [词A, 词B, 词C]
doc2 → [词B, 词D]

查询时需要遍历所有文档,复杂度 O(n)。

倒排索引(Inverted Index)

词 → 文档列表
词A[doc1, doc3]B[doc1, doc2]

查询时根据词直接定位文档,复杂度 O(1)。

ES 倒排索引结构

Term Dictionary(词字典)→ Term Index(FST 前缀树)→ Posting List(倒排列表)
                                                   ├── doc ID
                                                   ├── frequency
                                                   └── position

Q15: ElasticSearch 的底层基于什么技术开发的?

A:

  • 核心引擎:Apache Lucene(Java 开发的全文搜索引擎库)
  • 通信层:Netty(高性能网络框架)
  • 分布式协调:ZooKeeper / 自行实现(ES 7.x+ 自研 ZenDiscovery)
  • 底层语言:Java(JVM 运行时)
  • 数据结构:FST(有限状态自动机)、Skip List、B-Tree

ES 在 Lucene 基础上实现了分布式、RESTful API、高可用等企业级特性。


Q16: ElasticSearch 跟 MySQL 有啥区别?

A:

维度MySQLElasticSearch
定位事务型数据库搜索引擎/文档数据库
数据结构行存储、严格 Schema文档存储、Schema-less
索引B-Tree 主键/辅助索引倒排索引 + 多类型索引
事务ACID 完整支持无事务(文档级原子性)
关联查询JOIN 支持嵌套文档/宽表设计
写入性能较高写入延迟较大(先写内存再刷盘)
查询性能复杂查询较慢全文检索、聚合分析快
数据量千万级亿级+

最佳实践:MySQL 作为主数据源,ES 作为检索/分析引擎,二者配合使用。


Q17: ElasticSearch 的体系结构是啥样的?

A:

┌─────────────────────────────────────────────────┐
│                  Cluster(集群)                  │
│  ┌─────────────────────────────────────────┐    │
│  │               Node(节点)               │    │
│  │  ┌─────────────────────────────────┐    │    │
│  │  │       Index(索引)              │    │    │
│  │  │  ┌───────────┐ ┌───────────┐   │    │    │
│  │  │  │ Primary   │ │ Replica   │   │    │    │
│  │  │  │  Shard    │ │  Shard    │   │    │    │
│  │  │  └─────┬─────┘ └─────┬─────┘   │    │    │
│  │  │        ↓             ↓         │    │    │
│  │  │     ┌───────────────────┐       │    │    │
│  │  │     │     Segment      │       │    │    │
│  │  │     │  (Lucene Index)  │       │    │    │
│  │  │     └───────────────────┘       │    │    │
│  │  └─────────────────────────────────┘    │    │
│  └─────────────────────────────────────────┘    │
└─────────────────────────────────────────────────┘

关键概念

  • Cluster:由多个 Node 组成,共享同一 Cluster Name
  • Node:ES 实例,分 Master/Data/Ingest/Coordinating 角色
  • Index:逻辑数据组织单位,类似数据库
  • Shard:数据分片,Primary Shard 负责写入,Replica Shard 负责备份和查询
  • Segment:Lucene 底层数据文件,只读不可变

五、Mapping 与分词

Q18: 项目中搜索对应的 ES 索引库映射关系有哪些字段?

A: 示例商品索引 Mapping

{
  "mappings": {
    "properties": {
      "id": { "type": "keyword" },
      "title": { 
        "type": "text", 
        "analyzer": "ik_max_word",
        "fields": { "keyword": { "type": "keyword" } }
      },
      "description": { "type": "text", "analyzer": "ik_smart" },
      "category_id": { "type": "keyword" },
      "price": { "type": "double" },
      "stock": { "type": "integer" },
      "brand": { "type": "keyword" },
      "tags": { "type": "keyword" },
      "location": { "type": "geo_point" },
      "create_time": { "type": "date" },
      "status": { "type": "integer" }
    }
  }
}

字段设计原则

  • 需要分词检索的字段 → text + 分词器
  • 精确匹配/聚合/排序字段 → keyword
  • 数值范围查询 → integer/double/long
  • 地理搜索 → geo_point

Q19: 哪些字段是可分词的?

A:

  • text 类型:可分词,ES 默认对 text 字段进行分词处理
  • keyword 类型:不可分词,作为整体精确匹配

示例

{
  "title": {
    "type": "text",        // 可分词:用于全文检索
    "fields": {
      "keyword": {          // 不可分词:用于精确匹配、排序
        "type": "keyword"
      }
    }
  }
}

Q20: 分词器用的什么?

A: 中文分词器推荐

  • IK Analyzer:最成熟,生态好,支持细粒度和智能分词
    ik_max_word:最细粒度分词("中华人民共和国""中华人民共和国/中华人民/华人/人民/共和国/共和国")
    ik_smart:最粗粒度("中华人民共和国""中华人民共和国"

配置示例

PUT /index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_ik": {
          "type": "custom",
          "tokenizer": "ik_max_word",
          "filter": ["lowercase"]
        }
      }
    }
  }
}

Q21: ES 的分词器有几种?

A:

类别分词器说明
内置standardES 默认,英文按词切分
simple按非字母字符切分
whitespace按空格切分
keyword不分词,保留原样
pattern正则表达式分词
中文IK最流行,需安装插件
jieba社区活跃
hanlp多种分词模式
拼音pinyin搜索友好(拼音首字母)

Q22: ES 的字符串类型有几种?

A:

类型说明适用场景
text可分词,全文检索描述、标题、内容
keyword不可分词,精确匹配ID、分类、标签、排序字段
match_only_text7.6+,禁用打分优化存储日志场景

注意事项

  • ES 5.x 后移除了 string 类型,统一使用 text/keyword
  • 两者可以同时使用(multi-field):
    "field": {
      "type": "text",
      "fields": {
        "keyword": { "type": "keyword" }
      }
    }
    

六、查询类型

Q23: ES 有哪些查询类型?

A: 按查询方式分类

类型说明
全文检索match、multi_match、query_string
精确查询term、terms、range
复合查询bool、boosting、constant_score
模糊查询fuzzy、wildcard、regexp
地理位置geo_distance、geo_bounding_box
嵌套查询nested、has_child、has_parent
相似度more_like_this
脚本查询script

常用查询示例

GET /index/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "title": "手机" } }
      ],
      "filter": [
        { "term": { "category_id": "1" } },
        { "range": { "price": { "gte": 1000, "lte": 5000 } } }
      ]
    }
  }
}

Q24: ES 的聚合查询怎么用?

A: 主要聚合类型

类型说明示例
bucket分桶聚合terms、range、date_histogram
metric指标聚合avg、sum、max、min、stats
pipeline管道聚合sum_bucket、avg_bucket

示例

GET /index/_search
{
  "size": 0,
  "aggs": {
    "category_stats": {
      "terms": { "field": "category_id", "size": 10 },
      "aggs": {
        "avg_price": { "avg": { "field": "price" } },
        "max_price": { "max": { "field": "price" } }
      }
    }
  }
}

Q25: 用的是什么查询类型?

A: 常见最佳实践

场景推荐查询类型
全文检索bool + match
精确过滤bool + filter + term/range
排序 + 检索bool + match + sort
高亮展示match + highlight
关联嵌套文档nested + bool

推荐结构

{
  "query": {
    "bool": {
      "must": [
        { "match": { "title": "搜索词" } }
      ],
      "filter": [
        { "term": { "status": 1 } }
      ],
      "should": [
        { "match": { "brand": "品牌词" } }
      ]
    }
  }
}

Q26: 用于搜索的 Java API 类叫啥名字?

A: 原生 Java High Level REST Client

// 创建客户端
RestHighLevelClient client = new RestHighLevelClient(
    RestClient.builder(new HttpHost("localhost", 9200, "http"))
);

// 构建查询
SearchRequest searchRequest = new SearchRequest("index_name");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchQuery("title", "手机"));
sourceBuilder.from(0).size(20);
sourceBuilder.sort("create_time", SortOrder.DESC);
searchRequest.source(sourceBuilder);

// 执行搜索
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);

// 解析结果
SearchHits hits = response.getHits();
for (SearchHit hit : hits) {
    System.out.println(hit.getSourceAsString());
}

Spring Boot 集成

  • Spring Data Elasticsearch
  • Elasticsearch RestTemplate

七、集群与运维

Q27: ElasticSearch 有搭建集群吗?

A: 常见集群架构

架构说明适用场景
单机开发/测试开发环境
多节点集群生产标准中小规模(3-5 节点)
热温冷架构分层存储大规模日志/时序数据
跨机房集群高可用容灾核心业务

集群健康检查

GET /_cluster/health
# green: 所有分片正常
# yellow: 主分片正常,副本未分配
# red: 有主分片丢失

Q28: ElasticSearch 集群如果发生脑裂问题,如何解决?

A: 脑裂(Split-Brain): 集群因网络分区导致多个节点认为自己是主节点,破坏数据一致性。

原因

  • 网络抖动
  • Master 节点负载过高,响应超时
  • minimum_master_nodes 配置不当

解决方案

措施说明
正确配置minimum_master_nodes = (N/2) + 1(N 为合格节点数)
降低负载避免 Master 节点承担大量查询
网络隔离确保网络稳定,跨机架/机房合理部署
手动恢复确认合法 Master,剔除异常节点
重启集群极端情况下重启集群

配置示例

# elasticsearch.yml
discovery.zen.minimum_master_nodes: 2  # 3节点集群设为2
discovery.zen.ping_timeout: 3s

Q29: Elasticsearch 中的函数?

A: function_score 查询:允许使用函数影响文档评分。

函数说明示例
script_score自定义脚本计算分数基于字段运算
random_score随机评分打破评分相同时的排序
field_value_factor字段值因子点赞数影响排序
decay_functions衰减函数时间/距离衰减
weight固定权重boost 权重调整

示例:时间衰减

{
  "query": {
    "function_score": {
      "query": { "match": { "title": "手机" } },
      "gauss": {
        "create_time": {
          "origin": "now",
          "scale": "30d",
          "decay": 0.5
        }
      }
    }
  }
}

八、补充:高频追问

Q30: ES 的数据写入流程?

A:

客户端 → Coordinating Node → Primary Shard
                              ↓
                         写入内存 Buffer
                              ↓
                    定期 Refresh(默认1秒)
                              ↓
                      生成 Segment
                              ↓
                    写入 Translog
                              ↓
               定期 Flush(删除旧 Translog)

Q31: ES 如何保证高可用?

A:

  • 副本分片:每个 Primary Shard 可配置多个 Replica
  • 故障转移:Master 节点监控,异常时重新选主
  • 分片分配:自动均衡分配,避免单点
  • 脑裂防护minimum_master_nodes 机制

Q32: ES 优化建议?

A:

维度优化建议
写入批量写入、Bulk API、减少 Refresh 频率
查询避免 SELECT *、Filter 缓存、路由优化
索引合理分片数、Alias 切换零停机
硬件SSD、内存充足、CPU 高性能
分词选择合适分词器、冷热分离

📚 面试技巧:回答时结合实际项目经验,用数据说明效果(如:查询耗时从 3s 降到 50ms),比纯概念更有说服力。