当前位置: 首页 > news >正文

【Elasticsearch】es初识,在项目架构中的用途,与mysql和kafka的配合使用,

ES是一个开源的高扩展的分布式全文检索引擎

在项目已有mysql增删改查的情况下,新增kafka,es流程

用户新增/修改商家(写MySQL)
↓
Kafka 生产者发送商家数据消息
↓
Kafka 消费者监听消息 → 写入 Elasticsearch
↓
前端搜索商家时 → 查询 Elasticsearch(不是 MySQL)

这个 Kafka + Elasticsearch 的写入同步 + 搜索解耦架构 是目前绝大多数中大型互联网企业的标准做法


一、为什么不能只查 MySQL而引入es查询?

传统做法的问题:

比如你在前端搜索商家名称“李大壮”,如果查的是 MySQL:

SELECT * FROM merchant WHERE name LIKE '%李大壮%' OR description LIKE '%李大壮%' LIMIT 10;

问题:

  • :LIKE + 多字段模糊查询在数据量大时性能非常差;
  • 不智能:MySQL 的模糊匹配不支持分词、不支持排序打分;
  • 不灵活:无法实现“相关度排序”“拼音搜索”“短语匹配”等搜索场景。

所以,企业通常引入 Elasticsearch(简称 ES)来替代 MySQL 作为 搜索引擎


二、为什么 MySQL 改动不直接同步到 Elasticsearch,而是先发 Kafka?

这是你最关键的问题:为什么加一层 Kafka?

原因一:解耦系统,避免写 ES 出错影响主业务

  • 如果你直接在写 MySQL 后同时写 ES,那么:

    • 如果 ES 挂了、网络抖动、接口异常等,会导致整个商家创建流程失败;
    • Kafka 相当于消息缓冲器 + 解耦层,即便 ES 挂了,Kafka 消息还能继续收集,等恢复后继续消费。

原因二:可支持异步、并发、大吞吐处理

  • Kafka 是高吞吐分布式系统,支持水平扩展(通过分区);
  • 消费者可以并行处理,批量写入 ES,系统更加稳定、可扩展。

原因三:可拓展更多下游系统,不只是 Elasticsearch

未来你可能还需要这些:

  • 同步商家数据到 Redis 缓存(做秒级展示);
  • 触发推送服务(比如新商家上线通知);
  • 同步用户画像系统、数据仓库。

如果有 Kafka,你只需要新增一个消费者;
如果没有 Kafka,你要改源代码、逻辑复杂,非常不利于维护。


三、流程总结:企业为什么这样做?

阶段系统作用
1MySQL业务主库,负责存储真实、结构化的数据
2Kafka消息中间件,做异步解耦、缓冲和流式处理
3Elasticsearch专用于搜索,支持全文检索、相关度评分等搜索功能
4前端直接查 ES,提升搜索速度、支持搜索功能增强

四、图示结构(简化):

      用户操作前端↓后端写 MySQL(商家表)↓┌────→ Kafka ←────┐│                 │Kafka Consumer     │(可以多个系统消费)↓                 ↓
ElasticSearch     Redis/OLAP等其他系统↓
前端搜索

es查询使用案例

query := map[string]interface{}{// DSL 查询主体"query": map[string]interface{}{"bool": map[string]interface{}{ // bool 组合查询(企业中常用)"must": []interface{}{ // must 表示“必须匹配”的条件,全部满足才返回map[string]interface{}{"multi_match": map[string]interface{}{ // 多字段模糊匹配"query":  in.Keyword, // 用户输入的搜索关键词(如“口腔”)"fields": []string{"name", "business", "address"},"type":   "most_fields", // type: most_fields → 各字段各自打分后相加,适合字段内容差异大;另一个选项 cross_fields 更适合字段语义接近。},},},"filter": filters, // 精准过滤器(如按省市区筛选,不能容忍模糊匹配)"should": []interface{}{ // 加分项,提升命中相关性map[string]interface{}{"match_phrase": map[string]interface{}{ "name": in.Keyword, // 要求关键词“完整连续地”出现在 name 中才能加分(如“牙科诊所”)},},map[string]interface{}{"match_phrase": map[string]interface{}{"business": in.Keyword, // business 完整短语匹配},},},// 注:should 不设置 minimum_should_match 时,不满足不会过滤掉,只是不加分},},// 分页设置"from": (in.Page - 1) * in.PerPage, // 从第几条开始取数据(起始位置)"size": in.PerPage,                // 每页返回多少条// 排序设置"sort": []interface{}{map[string]interface{}{"order_score": "desc", // 业务字段排序:order_score 是你在 merchant 映射里定义的字段,值越大代表权重越高。// 通常用于控制:优质商家排前面(如人工打分、运营配置)},},
}// -----------------
// 构造查询DSL// DSL:Domain-Specific Language(领域特定语言)// 这里表示一段用于构建或解析 Elasticsearch 查询语句的逻辑query := map[string]interface{}{"query": map[string]interface{}{"bool": map[string]interface{}{"must": []interface{}{map[string]interface{}{"multi_match": map[string]interface{}{ // multi_match 该字段使得查询支持不同类型的匹配模式// type 参数控制多字段匹配的方式,主要有两种:"query":  in.Keyword,"fields": []string{"name", "business", "address"},"type":   "most_fields", // 1.most_fields:把多个字段匹配结果 分开 算分,最后相加// 2.cross_fields:把多个字段 和在一起 匹配(适合同一个词,可能出现在name和business这种的情况)// 分数(score):Elasticsearch内部计算的相关度分值,用于衡量文档与查询的匹配程度,// 数值越大说明匹配越好,搜索结果排序默认会根据这个分数降序排列。},},},"filter": filters,// 其中should字段,主要作用是在满足上述条件下,增加相关度,缩小搜索范围。"should": []interface{}{ // should:表示“或”关系,满足should中条件的文档会被加分,提高其相关度排序,// 但文档不一定非要满足should中的条件才能匹配整个查询(除非设置minimum_should_match)。// 下面2map的效果:如果传入的name和business是能完全匹配的,则会获得更高的相关度评分。map[string]interface{}{"match_phrase": map[string]interface{}{ // match_phrase 是短语匹配,要求查询词,是顺序的不拆分的,否则匹配失败。"name": in.Keyword,},},map[string]interface{}{"match_phrase": map[string]interface{}{"business": in.Keyword,},},},},},"from": (in.Page - 1) * in.PerPage,"size": in.PerPage,"sort": []interface{}{ // 按照评分排序map[string]interface{}{"order_score": "desc"}, // 降序},}

https://github.com/0voice

相关文章:

  • 网站显示已备案微信公众号怎么开通
  • 公司内部网站创建百度广告一天多少钱
  • 网站添加微信支付功能百度账户登录
  • 大学生一个人做网站软文云
  • 电子商务网站成本如何做好口碑营销
  • 网站业务原创文章代写
  • .NET 7.0 EF Core:一、创建Web API 项目基础框架和用户表的增删改查
  • C++ 第二阶段项目三:图形绘制库
  • PDF24 Creator(PDF工具箱)
  • 中文PDF解析准确率排名
  • 设计模式:揭秘Java原型模式——让复杂对象的创建不再复杂
  • 使用pyflink编写demo并将任务提交到yarn集群
  • 【启发式算法】RRT*算法详细介绍(Python)
  • 一篇文章了解XML
  • LeetCode 3298.统计重新排列后包含另一个字符串的子字符串数目2
  • aspose.word在IIS后端DLL中高并发运行,线程安全隔离
  • 50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | BackgroundSlider(背景滑块)
  • Web项目开发中Tomcat10+所需的jar包
  • 机器学习复习
  • 自动驾驶数据特征提取实战:用Python打开智能驾驶的新视角
  • C++包管理工具:conan2使用教程
  • 在vscode中,Python程序的内置对象、关键字、自定义函数名/类名、字符串进行着色,说明分别是什么颜色?
  • ant+Jmeter+jenkins接口自动化,如何实现把执行失败的接口信息单独发邮件?
  • Jenkins Pipeline 与 Python 脚本之间使用环境变量通信
  • Flutter 百题斩#8 | 说说 State 抽象类持有的成员变量
  • Flutter MobX 响应式原理与实战详解