MySQL到ES

一、 为什么非 ES 不可?(业务痛点)

在传统的 MySQL 架构中,当我们执行 WHERE title LIKE '%Java%' 时:

  1. 全表扫描:数据库必须逐行检查,查询效率随数据量增加呈线性下降。

  2. 无法分词:搜索"Java开发",MySQL 很难精准匹配到只包含"Java"或"开发"的记录。

ES 的核心价值:将搜索延迟从"秒级"降低到"毫秒级",并提供强大的相关性评分(搜索结果谁更匹配排在前面)。


二、 核心架构:像理解数据库一样理解 ES

Elasticsearch 关系型数据库 (MySQL) 说明
Index (索引) Database (数据库) 数据的逻辑容器
Type (类型) Table (表) ES 7.x 后已弱化,通常一个索引对应一类数据
Document (文档) Row (行) 最小的数据单元(JSON 格式)
Field (字段) Column (列) 数据的属性
Mapping (映射) Schema (表结构) 定义字段类型(text, keyword 等)

核心机制:分布式分片

  • Shard (分片):将一个大索引拆分成多个小块,分布在不同服务器上,实现横向扩展。

  • Replica (副本):分片的备份,保证某台服务器宕机时数据不丢失,并提升查询并发能力。


三、 必杀技:倒排索引 (Inverted Index)

这是 ES 为什么快的底层秘密。

  • 正排索引:文档 ID -> 文档内容(像看书,想找某个词得翻遍全书)。

  • 倒排索引:关键词 -> 文档 ID 列表(像查书后的索引表,直接定位页码)。

倒排索引表组成:

  1. Term Dictionary (词典):记录所有不重复的关键词。

  2. Posting List (倒排列表):记录该关键词在哪些文档出现过、出现的频率(TF)和位置。


四、 环境搭建:Linux 手动部署要点

对于 Java 全栈开发,理解 Linux 下的内核限制配置是面试常考的运维细节。

1. 核心系统配置

Bash

复制代码
# 1. 调整最大文件句柄数(ES 需要频繁读写大量小文件)
vim /etc/security/limits.conf
* soft nofile 65536
* hard nofile 65536

# 2. 调整虚拟内存限制(防止内存溢出)
vim /etc/sysctl.conf
vm.max_map_count=262144
sysctl -p

2. 关键配置 (elasticsearch.yml)

YAML

复制代码
cluster.name: my-application
node.name: node-1
network.host: 0.0.0.0       # 允许远程访问
http.port: 9200             # REST API 端口
http.cors.enabled: true      # 开启跨域,方便前端连接
http.cors.allow-origin: "*"

五、 IK 中分分词器:解决"中文搜索"

ES 自带的分词器会将中文按字拆分(如:重、头、写...),这不符合业务逻辑。

  • ik_smart:粗粒度拆分,节省空间。

  • ik_max_word:最细粒度拆分,搜索更全。

配置词典 :在 IKAnalyzer.cfg.xml 中配置 ext_dict,可以添加公司特有的专业术语(如你的项目名"Antigravity")。


六、 DSL 高级查询实战

这是你后端代码中构建查询逻辑的模版。

1. 布尔查询 (Bool Query) - 业务中最常用

JSON

复制代码
GET /order/_search
{
  "query": {
    "bool": {
      "must": [ 
        { "match": { "goods_name": "华为手机" } } 
      ],
      "filter": [ 
        { "range": { "price": { "gte": 2000, "lte": 5000 } } },
        { "term": { "status": "published" } }
      ]
    }
  }
}

面试点 :为什么用 filter?

答:filter 不计算相关性评分,且有缓存机制 ,性能远高于 must。


七、 Spring Boot 3.x 深度集成

现在企业主流使用的是 ElasticsearchJavaClient(替代了已过时的 High Level Client)。

1. 核心依赖

XML

复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

2. 实战:构建一个搜索 Service

Java

复制代码
@Service
public class GoodsSearchService {

    @Autowired
    private ElasticsearchClient client; // 2026年主流客户端

    public SearchResponse<Goods> searchGoods(String keyword) throws IOException {
        return client.search(s -> s
            .index("goods")
            .query(q -> q
                .bool(b -> b
                    .must(m -> m.match(t -> t.field("name").query(keyword)))
                    .filter(f -> f.term(t -> t.field("is_delete").value(0)))
                )
            ), Goods.class);
    }
}

八、 2 年经验必看的优化与面试追问

  1. 数据同步方案:MySQL 和 ES 怎么同步?

    • 方案 A (同步双写):代码中写完 MySQL 紧接着写 ES。优点是实时,缺点是耦合。

    • 方案 B (异步 MQ):MySQL 成功后发消息给 RabbitMQ,由消费者同步 ES。解耦,保证最终一致性。

    • 方案 C (Canal/CDC):监听 MySQL Binlog,全自动同步。对业务代码零侵入(大厂首选)。

  2. 深度分页问题:

    • 普通的 from + size 在翻到 10000 页以后会极慢(因为要汇总所有分片数据)。

    • 对策 :使用 search_after(类似游标)来处理海量数据的连续拉取。

  3. 索引预热:

    • 对于商城主页面,可以在系统启动时利用 ApplicationRunner 预先执行一次复杂查询,让 ES 将索引数据加载到操作系统的 Page Cache 中。
相关推荐
2401_896732133 小时前
MySQL小笔记
mysql
程序员清风4 小时前
数据处理脚本工程化:日志、配置、命令行与测试
服务器·开发语言·数据库
正在走向自律5 小时前
数据集成产品的技术底座:从日志解析原理到 KFS 同步链路搭建(含建表与增删改查完整代码)
数据库·oracle·信创·数据集成·国产数据库·kingbasees·全量+增量同步
程序员塔塔喵5 小时前
【MySQL篇|第七篇】MySQL事务
数据库·mysql·mysql事务
独隅6 小时前
Claude API 实战教程:从入门到完整项目
android·java·数据库·claude·claude code
_孤傲_6 小时前
快速掌握 MySQL 语法
数据库·后端·mysql
数字新视界8 小时前
一体化机柜在数据中心运维中的创新应用与优势分析
大数据·服务器·数据库·动环监控系统·动力与环境监控系统
SelectDB8 小时前
从 StarRocks 走向 Apache Doris:如何实现引擎平滑替换与架构升级?
大数据·数据库·数据分析
为思念酝酿的痛8 小时前
MySQL的操作
数据库·mysql
猫咪很可爱9 小时前
Oracle ORA-4031 错误分析与处理:SGA 内存不足导致 update/exp/expdp 失败
数据库·oracle