这次面试又是一场 Elasticsearch(ES)的硬仗,问题从分片设置到映射定义,涵盖了配置、功能、部署和架构对比。以下是我对每个问题的回答复盘,既整理思路,也找找不足。
1. ES 分片与副本设置及概念解析
面试官问:"ES 的分片和副本是什么?数量怎么设定?"这个问题挺基础,我尽量答得清晰。
我说,分片(Shard)和副本(Replica)是 ES 分布式存储的核心:
- 分片:索引被分成多个主分片,每个分片是一个独立的 Lucene 实例,负责存储部分数据。分片数决定了并行能力。
- 副本:主分片的拷贝,提供高可用和读性能。副本数不影响写入,但能分担查询压力。
设置数量时,我提到:
- 分片数:根据数据量和节点数,比如 10 亿数据、20 个节点,可以设 20-40 个主分片,单分片控制在 20-50GB。不能改,需提前规划。
- 副本数:默认 1 个,可根据读负载调到 2-3 个,能动态调整。
面试官问:"分片太多有啥问题?"我说会增加管理开销,浪费资源。我觉得自己答得还行,但可以再提一下集群扩展时的分片迁移。
2. ES 拼写纠错的实现原理
接着问:"ES 的拼写纠错怎么实现?"这个问题有点冷门,我之前没深入研究。
我说,ES 的拼写纠错主要靠 Suggester 功能,比如 term suggester
和 phrase suggester
:
- 原理 :基于词典和编辑距离(Levenshtein Distance),对比用户输入和索引中的词,找出相似词。
term suggester
针对单个词,phrase suggester
考虑词组上下文。 - 实现 :查询时加
suggest
字段,设置max_errors
(允许的错误数)和confidence
(置信度),返回候选词。
面试官没追问,我感觉自己答得有点浅,之后得看看底层 FST(有限状态转换器)怎么支持纠错的。
3. Linux 下部署 ES 的优化方法
第三个问题是:"部署 ES 时,Linux 上有哪些优化?"这偏运维,我结合经验回答。
我说,Linux 部署 ES 可以从这几方面优化:
- 文件句柄 :改
/etc/security/limits.conf
,设nofile
为 65535,避免 "Too many open files"。 - 虚拟内存 :调
vm.max_map_count
到 262144(sysctl -w
),支持 ES 的内存映射。 - 禁用 Swap :设
bootstrap.memory_lock: true
,避免内存交换影响性能。 - CPU 和 IO :用 SSD 提升 IO,绑定 CPU 核心(
thread_pool
设置)提高并发。
面试官问:"Swap 不关行不行?"我说可以,但性能会下降。这部分我觉得答得还算实用。
4. ES 安装的依赖组件
问到:"安装 ES 有哪些依赖组件?"这个问题简单,我直接列举。
我说,ES 的核心依赖是:
- Java:需要 JDK(8 或 11,推荐 OpenJDK),ES 内置 JVM 但得装对版本。
- 操作系统:支持 Linux、Windows 等,Linux 最常见。
- 网络:确保端口(默认 9200、9300)可用。
可选组件有 Kibana(可视化)、Logstash(数据导入)。面试官没深问,感觉这部分没问题。
5. ES 服务器的启动流程
接着是:"怎么启动 ES 服务器?"这个问题很操作性。
我说,启动 ES 很简单:
- 下载解压 ES 包(比如
elasticsearch-8.x.tar.gz
)。 - 修改
config/elasticsearch.yml
(如集群名、节点角色)。 - 终端运行
bin/elasticsearch
(Linux),或用bin/elasticsearch.bat
(Windows)。 - 检查日志(
logs/
)和接口(curl localhost:9200
)确认启动。
面试官问:"后台启动呢?"我说加 -d
参数。这部分答得流畅,挺自信。
6. ES Cluster 简述
问:"简单说说 ES Cluster?"我尽量简洁。
我说,ES Cluster 是多个节点的集合,共享一个集群名(cluster.name
)。由 Master 节点管理状态,数据节点存数据,协调节点处理请求。集群通过分片和副本实现高可用和分布式计算。
面试官没追问,感觉这部分没啥问题。
7. ES Node 简述
接着是:"ES Node 是什么?"我也简洁回答。
我说,Node 是 ES 集群中的单个实例,跑在一个 JVM 上。角色有:
- Master-eligible:可参与选举 Master。
- Data:存数据和执行查询。
- Coordinating:转发请求和合并结果。
一个节点可以多角色,默认全能。面试官满意,我觉得答得够简洁。
8. ES 与关系数据库的对比分析
问到:"ES 和关系数据库对比呢?"这个问题让我有点兴奋。
我说,二者区别明显:
- 数据模型:ES 用 JSON 文档,无固定 Schema;关系数据库用表和行列,Schema 严格。
- 查询方式:ES 用 REST API 和 DSL,擅长全文搜索;关系数据库用 SQL,适合结构化查询。
- 分布式:ES 天生分布式,分片副本支持扩展;关系数据库多单机,扩展靠分库分表。
- 适用场景:ES 适合搜索、日志分析;关系数据库适合事务性操作。
面试官问:"事务支持呢?"我说 ES 不支持 ACID,关系数据库强在这点。我觉得自己答得全面。
9. ES 中能否定义映射
最后一个问题是:"ES 能定义映射吗?"这个问题不难。
我说,可以,ES 用 Mapping 定义字段类型和索引方式:
- 动态映射 :默认自动推断类型(比如字符串变
text
)。 - 显式映射 :创建索引时用
PUT /index/_mapping
指定,比如{ "properties": { "name": { "type": "keyword" } } }
。 - 限制:已有字段类型不能改,只能加新字段。
面试官没追问,我觉得这部分答得挺好。