为什么要使用 ElasticSearch?和传统关系数据库(如 MySQL)有什么不同?

#中间件#面试八股

为什么要使用 ElasticSearch?和传统关系数据库(如 MySQL)有什么不同?

结论先行:MySQL 擅长“按主键或索引精确定位、强事务、行级更新”,Elasticsearch(ES)擅长“全文检索、相关性排序、海量数据聚合”。用 MySQL 做 like '%关键词%' 是全表扫描且无法排序相关性;用 ES 做账务扣减则没有事务。两者是互补关系,不是替代关系。

一、能力对照

维度MySQLElasticsearch
数据模型行 + 列,强 SchemaJSON 文档,动态映射
索引结构B+ 树倒排索引 + DocValues 列存
检索方式等值、范围、前缀分词、模糊、短语、相关性打分
事务ACID,行锁无跨文档事务,单文档原子
实时性提交即可见近实时,默认 1 秒 refresh
扩展分库分表,改造量大原生分片,水平扩展
聚合group by,大数据量吃力terms/date_histogram,亿级可接受
存储成本低高(倒排 + 正排 + 副本)

二、典型使用姿势

-- MySQL:前缀匹配还能走索引,前后模糊只能全表扫
SELECT id, title FROM article WHERE title LIKE '%分布式锁%';
// ES:分词后按 term 匹配,还能按相关性排序
GET /article/_search
{
  "query": {
    "match": { "title": "分布式锁" }
  },
  "sort": ["_score", { "publish_time": "desc" }]
}

match 会先对查询词分词,再与倒排索引求交,最后用 BM25 算相关性;like '%x%' 只能逐行比较字符串,数据量大时必然超时。

三、什么场景该上 ES

场景说明
站内搜索商品、文章、日志的关键词检索 + 排序 + 高亮
日志分析ELK 组合,按时间范围 + 关键字 + 聚合统计
多维筛选电商筛选项组合(品牌、价格区间、标签)
模糊匹配拼音、同义词、纠错、分词
大表聚合亿级数据的 terms 统计,MySQL 难以承受

四、什么场景不该上 ES

场景原因
强事务(转账、库存扣减)无跨文档事务与回滚
频繁更新同一条记录更新是“标记删除 + 新建文档”,段合并成本高
精确主键查询为主MySQL 更省资源,ES 反而更慢更贵
数据量很小引入集群运维成本不划算
需要 joinES 的 join 能力弱,nested 有性能代价

五、引入 ES 的真实成本

成本项说明
存储倒排 + 正排 + _source,通常是原文的 2~3 倍,还要乘副本数
机器检索吃 CPU 与堆外内存,需要独立集群,不能和业务混部
同步链路双写或 binlog 订阅,多一条必须监控的链路
运维分片规划、段合并、快照备份、版本升级都有坑
一致性只能做到最终一致,前端要接受秒级延迟

只有当“检索体验带来的收益”大于这些成本时才值得上;如果只是按 ID 查详情,MySQL 加索引更划算。

常见追问

  • 追问:能不能用 ES 做主存储?不建议。它没有事务、近实时、段合并会抖动,恢复与备份能力也弱于数据库;主流做法是 MySQL 存权威数据,ES 做检索副本。
  • 追问:ES 会不会丢数据?默认 refresh_interval=1s、translog 每 5 秒或每次请求后落盘,极端情况下可能丢最后一段时间的数据;可以设 translog.durability=request 换取更高可靠性。
  • 追问:两者数据怎么同步?双写、事务消息、binlog 订阅(Canal)三条路,工程上多用 binlog 订阅 + 补偿对账。

小结

  • MySQL 保正确性,ES 保检索体验,职责不同。
  • 倒排索引 + 相关性打分是 ES 的独有能力,B+ 树做不到。
  • ES 无跨文档事务、近实时、写入放大,不适合当权威存储。
  • 上 ES 之前先问:是否真的需要分词、相关性、海量聚合。
笔记加载中…