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 中。
相关推荐
建筑工程企业管理系统2 小时前
erp工程项目管理系统落地价值:实现工程多项目成本精细化核算与管控
大数据·数据库·人工智能
AI大模型-小华2 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
foolishlee3 小时前
Neon wal日志处理流程2
数据库
2601_965798473 小时前
Is Hygia Good for Maid & Janitorial Sites? Technical Audit
服务器·网络·数据库
Cloud云卷云舒4 小时前
海山数据库(HaishanDB)面向工业云场景技术方案
数据库·haishandb·工业云·移动云海山数据库·天工云
逃逸线LOF4 小时前
Spring配置数据源{连接池}(Druid、c3p0)
java·数据库·spring
Elasticsearch5 小时前
跳过编写告警规则:NGINX OTel 集成中内置 6 个现成的 ES|QL 模板
elasticsearch
严同学正在努力6 小时前
从备份到恢复:我用 30 分钟恢复了误删的核心业务表
android·java·数据库·ai
#六脉神剑7 小时前
myBuilder新版本(8月,Office文件预览、Oracle数据库支持)
数据库·oracle·开发平台·数字化工具·mybuilder
花青泽7 小时前
5-数据库-SQL注入-联合查询-AND/OR绕过-day13
数据库·sql