📌 一、Elasticsearch 是什么?
一句话定义:Elasticsearch 是基于 Lucene 的分布式、RESTful 风格的搜索与分析引擎。
核心定位:全文检索、实时数据分析、日志处理、APM 监控,是 ELK/Elastic Stack 的核心组件。
系统架构师学习平台(点击这里进入)
💡 简单理解:ES 就是一个“超级搜索引擎 + 大数据实时分析平台”,能对 GB 到 PB 级数据进行毫秒级查询。
📚 二、核心概念 (对比关系型数据库)
| Relational DB | Elasticsearch | 说明 |
|---|---|---|
| Database (数据库) | Index (索引) | 索引是文档的容器,类似库 |
| Table (表) | Type (类型) 已废弃 | 7.x 后移除,统一用 _doc |
| Row (行) | Document (文档) | JSON 格式,基本数据单元 |
| Column (列) | Field (字段) | 支持多种数据类型 |
| Schema (约束) | Mapping (映射) | 定义字段类型、分词器等 |
| SQL | DSL (Query DSL) | JSON 风格的查询语言 |
⚙️ 分片 (Shard) & 副本 (Replica)
- 主分片 (Primary Shard):索引水平扩展的基础,数据分布存储,创建后数量不可变。
- 副本分片 (Replica Shard):主分片的备份,提供高可用 + 提升查询吞吐量。
- 默认每个索引 1 个主分片 + 1 个副本分片,生产建议至少 3 节点。
🏗️ 三、集群架构 & 写入流程
🔹 节点角色
- 🔵 Master 节点:管理集群元数据、分片分配
- 🟢 Data 节点:存储数据、执行搜索聚合
- 🟡 Coordinating 节点:接收请求、路由分发、合并结果
- 🟠 Ingest 节点:预处理文档(管道)
📥 文档写入流程 (近实时 NRT)
- ① 客户端请求任意协调节点 → ② 路由计算确定主分片 → ③ 主分片写入内存 Buffer + translog → ④ 定时 refresh (默认1s) 生成可读的 Segment → ⑤ 数据变为可见,实现近实时搜索。
- translog 用于故障恢复,flush 操作将 Segment 落盘并清空 translog。
🚀 ES 不是实时搜索,而是近实时 (NRT),默认 1 秒延迟。可手动 refresh 或调整 refresh_interval。
🔍 四、倒排索引 (Inverted Index) —— ES 快的根本
正排索引:文档 → 关键词。倒排索引:关键词 → 文档列表 (Posting List)。
- Term Dictionary:词项字典,按字母排序,支持二分查找。
- Posting List:包含文档ID、词频、位置信息,压缩存储 (Frame of Reference, Roaring Bitmap)。
- FST (Finite State Transducer):内存中高效存储 Term Index,加速检索。
查询时:分词 → 查 Term Index → 读 Posting List → 合并结果 → 打分排序。
✂️ 五、分词器 (Analyzer) 与中文搜索
分词器由三部分组成:Character Filter→Tokenizer→Token Filter。
- 标准分词器 (standard):按词切分,适合英文。
- ik 分词器 (中文):ik_smart (粗粒度) / ik_max_word (细粒度),需安装插件。
- pinyin 分词器:支持拼音搜索。
- 自定义分词器:组合不同 filter ( lowercase, stop, synonym )。
📖 中文搜索必须使用 ik 分词器,否则会按单字切分,效果极差。
⚡ 六、强大的查询 DSL & 聚合分析
🔹 常用查询类型
- term / terms:精确匹配,不分析 (适用于 keyword 字段)。
- match / match_phrase:全文搜索,先分词再匹配。phrase 要求顺序相同。
- bool query:组合 must / should / must_not / filter。filter 不参与打分,可缓存。
- range:范围查询 (数值/日期)。
- wildcard / regexp:通配符/正则,性能差,慎用。
📊 聚合分析 (Aggregation) —— 替代 SQL GROUP BY
- Metric 聚合:sum, avg, min, max, stats, cardinality (去重计数)。
- Bucket 聚合:terms, range, date_histogram (按时间桶)。
- Pipeline 聚合:对聚合结果再次计算,如 moving average。
🌐 七、高可用与水平扩展
- 主从选举 (Zen Discovery / 7.x 后基于 Raft):master 节点负责集群管理,半数以上投票。
- 分片自动均衡:新增节点后自动迁移分片,实现负载均衡。
- 跨集群复制 (CCR):灾备或读写分离。
- 滚动升级 / 重启:通过分片恢复保证服务可用。
💡 生产建议:节点数 ≥ 3,副本数 ≥ 1,避免脑裂。配置 discovery.seed_hosts 和 cluster.initial_master_nodes。
📊 八、ES 对比与选型
| 对比维度 | MySQL | Elasticsearch | MongoDB |
|---|---|---|---|
| 数据模型 | 表/行/列 | JSON 文档 | JSON 文档 |
| 索引方式 | B+Tree | 倒排索引 + Doc Values | B-Tree |
| 搜索能力 | LIKE 模糊,效率低 | 全文检索、相关性打分、高亮 | 文本搜索较弱 |
| 聚合分析 | GROUP BY 有限 | 毫秒级聚合,支持复杂统计 | 聚合管道较慢 |
| 实时性 | 强一致 | 近实时 (1s 延迟) | 强一致 |
| 适用场景 | 事务型存储 | 搜索、日志、监控、分析 | 海量文档存储 |
⚙️ 九、性能优化 & 面试高频点
🚀 写入优化
- 批量写入 (Bulk API),单批次 5~15 MB。
- 增加 refresh_interval (如 30s),减少 segment 合并开销。
- 禁用不需要的 _source 或 doc_values (仅用于索引)。
- 调整 translog 刷盘策略 (durability: async)。
🔎 查询优化
- 尽量使用 filter 缓存 (不计算评分)。
- 避免深度分页 (from+size 过大),改用 search_after 或 scroll (流式)。
- 合理设置分片大小 (20GB~40GB 最佳)。
- 使用 index sorting 优化排序查询。
🔥 常见面试题
- ES 为什么搜索快?倒排索引 + FST + 内存优化 + 分片并行。
- ES 如何保证数据不丢?translog + flush + 副本机制,可配置同步刷盘。
- 什么是 forcemerge?手动合并 segment,减少文件句柄,提高查询性能。
- ES 深度分页问题?协调节点内存压力大,用 search_after 基于游标。
- ES 冷热分离架构?设置不同节点属性,热节点用 SSD,冷节点用 HDD。
- 聚合结果不精确?默认使用精度 trade-off (对于 terms 聚合可设置 shard_size)。
📦 十、ELK / Elastic Stack 生态
- 🪵 Logstash:数据采集、过滤、传输
- 📈 Kibana:可视化仪表盘、探索数据
- 🔄 Beats:轻量型采集器 (Filebeat, Metricbeat)
- 🧠 APM:应用性能监控
🎯 一句话总结:ES = 分布式 + 倒排索引 + 近实时 + 聚合分析,是搜索与日志分析领域事实标准。
适用场景:网站搜索、日志分析、监控告警、商品推荐、舆情分析、大数据存储与检索。