MySQL 和 Elasticsearch 之间的数据同步
MySQL 和 Elasticsearch 之间的数据同步是常见的需求,通常用于将结构化数据从关系型数据库同步到 Elasticsearch 以实现高效的全文搜索、聚合分析和实时查询。以下是几种常用的同步方案及其实现方法:
1. 应用层双写(双写模式)
原理
在业务代码中同时向 MySQL 和 Elasticsearch 写入数据,保证两者数据一致。
实现步骤
- 在写入 MySQL 的事务中,同步或异步写入 Elasticsearch。
- 需处理可能的写入失败问题(如 Elasticsearch 宕机),通过重试机制或补偿机制(如消息队列)确保最终一致性。
优点
- 实现简单,对架构改动较小。
- 实时性强,写入即生效。
缺点
- 双写可能引入数据不一致风险(如 MySQL 成功但 Elasticsearch 失败)。
- 业务逻辑耦合度高,维护成本增加。
适用场景
- 小规模数据同步,对实时性要求高。
- 业务逻辑简单,可接受双写风险。
2. 使用 Logstash 定时同步
原理
通过 Logstash 的 jdbc
插件定期轮询 MySQL,将增量或全量数据同步到 Elasticsearch。
实现步骤
- 配置 Logstash 输入(Input):使用
jdbc
插件连接 MySQL,定义 SQL 查询(如按时间戳增量拉取)。 - 配置 Logstash 输出(Output):将数据写入 Elasticsearch。
- 定时任务:通过
schedule
参数设置轮询间隔(如每分钟一次)。
示例 Logstash 配置
input {jdbc {jdbc_driver_library => "mysql-connector-java-8.0.26.jar"jdbc_driver_class => "com.mysql.cj.jdbc.Driver"jdbc_connection_string => "jdbc:mysql://localhost:3306/mydb"jdbc_user => "root"jdbc_password => "password"schedule => "* * * * *" # 每分钟执行一次statement => "SELECT * FROM products WHERE updated_at > :sql_last_value"use_column_value => truetracking_column => "updated_at"tracking_column_type => "timestamp"}
}
output {elasticsearch {hosts => ["http://localhost:9200"]index => "products"document_id => "%{id}"}
}
优点
- 配置简单,无需修改业务代码。
- 支持增量同步。
缺点
- 实时性较差(依赖轮询间隔)。
- 频繁轮询可能对 MySQL 造成压力。
适用场景
- 对实时性要求不高(如 T+1 数据同步)。
- 数据量较小,无需复杂转换的场景。
3. 基于 Binlog 的实时同步
原理
通过解析 MySQL 的 Binlog 日志(记录数据变更),将变更事件实时同步到 Elasticsearch。
常用工具:
- Canal(阿里开源工具)
- Debezium(基于 Kafka Connect)
- Maxwell
实现步骤(以 Canal 为例)
-
开启 MySQL Binlog:
# 在 MySQL 配置文件中启用 Binlog server-id = 1 log_bin = /var/log/mysql/mysql-bin.log binlog_format = ROW # 必须为 ROW 模式
-
部署 Canal Server:
- Canal 伪装为 MySQL 从库,订阅 Binlog 变更。
- 解析 Binlog 并转发到消息队列(如 Kafka)或直接调用 Elasticsearch API。
-
数据消费与写入 Elasticsearch:
- 编写消费者程序(如 Java/Python),将 Binlog 中的增删改事件转换为 Elasticsearch 的写入/更新/删除操作。
优点
- 实时性高(毫秒级延迟)。
- 对业务代码无侵入。
缺点
- 部署复杂度较高,需维护中间件(如 Canal、Kafka)。
- 需处理数据格式转换(如关系表到 JSON 文档)。
适用场景
- 大规模数据实时同步。
- 对数据一致性要求高的场景。
4. 使用消息队列解耦
原理
将 MySQL 的变更事件发送到消息队列(如 Kafka、RabbitMQ),由消费者异步写入 Elasticsearch。
实现步骤
- 捕获 MySQL 变更:
- 使用 Binlog 工具(如 Debezium)将变更事件发送到 Kafka。
- 消费 Kafka 消息:
- 编写消费者程序,处理消息并写入 Elasticsearch。
示例架构
MySQL → Debezium → Kafka → Consumer → Elasticsearch
优点
- 高可靠性,消息队列提供持久化和重试机制。
- 解耦生产者和消费者,扩展性强。
缺点
- 架构复杂度高,需维护多个组件。
适用场景
- 高并发、高可靠性的生产环境。
- 需要灵活扩展和数据缓冲的场景。
5. 第三方工具
工具推荐
- Go-MySQL-Elasticsearch:基于 Go 开发的工具,直接读取 MySQL Binlog 并同步到 Elasticsearch。
- Elasticsearch River(已弃用):旧版 Elasticsearch 插件,不建议使用。
实现步骤(以 Go-MySQL-Elasticsearch 为例)
- 配置 MySQL 连接信息和 Elasticsearch 地址。
- 定义表到索引的映射规则。
- 启动服务,自动监听 Binlog 并同步数据。
优点
- 开箱即用,无需开发代码。
缺点
- 灵活性和可定制性较差。
总结与选型建议
方案 | 实时性 | 复杂度 | 可靠性 | 适用场景 |
---|---|---|---|---|
应用层双写 | 高 | 低 | 中 | 小规模,强实时性 |
Logstash 定时同步 | 低 | 低 | 中 | 离线分析,非实时场景 |
Binlog 同步(Canal) | 高 | 高 | 高 | 大规模,实时性要求高 |
消息队列(Kafka) | 高 | 高 | 高 | 高并发,需解耦和扩展 |
第三方工具 | 中 | 中 | 中 | 快速实现,无需定制开发 |
注意事项
- 数据结构转换:需将 MySQL 的行数据转换为 Elasticsearch 的 JSON 文档,可能涉及嵌套对象或父子关系处理。
- 幂等性:确保同步操作的幂等性(如通过唯一ID),避免重复写入。
- 错误处理:监控同步失败的情况,提供重试或人工干预机制。
- 性能优化:
- 批量写入 Elasticsearch(使用
_bulk
API)。 - 调整 Elasticsearch 的刷新间隔(
refresh_interval
)提升写入性能。
- 批量写入 Elasticsearch(使用
通过合理选择方案并配合监控工具(如 Kibana、Prometheus),可实现高效可靠的 MySQL 到 Elasticsearch 数据同步。
相关文章:
MySQL 和 Elasticsearch 之间的数据同步
MySQL 和 Elasticsearch 之间的数据同步是常见的需求,通常用于将结构化数据从关系型数据库同步到 Elasticsearch 以实现高效的全文搜索、聚合分析和实时查询。以下是几种常用的同步方案及其实现方法: 1. 应用层双写(双写模式) 原…...
PS裁剪工具
裁剪: 多张图同一标准裁剪:裁剪–》前面的图像–》选择其他图像–》 确定 选区–》裁剪工具–》确定:选区制作矩形裁剪 裁剪–》拉直 裁剪–》内容识别:当裁剪大于图片大小,会自动填充空白区域 (栅格化图层…...

[Web 安全] PHP 反序列化漏洞 —— PHP 序列化 反序列化
关注这个专栏的其他相关笔记:[Web 安全] 反序列化漏洞 - 学习笔记-CSDN博客 0x01:PHP 序列化 — Serialize 序列化就是将对象的状态信息转化为可以存储或传输的形式的过程,在 PHP 中,通常使用 serialize() 函数来完成序列化的操作…...

QT入门--QMainWindow
从上向下依次是菜单栏,工具栏,铆接部件(浮动窗口),状态栏,中心部件 菜单栏 创建菜单栏 QMenuBar* mybar1 menuBar(); 将菜单栏放到窗口中 setMenuBar(mybar1); 创建菜单 QMenu *myfilemenu mybar1-…...
C++ | 高级教程 | 信号处理
👻 概念 信号 —— 操作系统传给进程的中断,会提早终止程序有些信号不能被程序捕获,有些则可以被捕获,并基于信号采取适当的动作 信号描述SIGABRT程序的异常终止,如调用 abortSIGFPE错误的算术运算,比如除…...
最新前端框架选型对比与建议(React/Vue/Svelte/Angular)
前端框架选型对比与建议(React/Vue/Svelte/Angular) 一、核心框架技术特性对比(基于最新版本) 维度React 19 25Vue 3.5 12Svelte 5 25Angular 19 5核心理念函数式编程、JSX语法、虚拟DOM渐进式框架、组合式API、模板语法编译时框…...

游戏引擎学习第123天
仓库:https://gitee.com/mrxiao_com/2d_game_3 黑板:线程同步/通信 目标是从零开始编写一个完整的游戏。我们不使用引擎,也不依赖任何库,完全自己编写游戏所需的所有代码。我们做这个节目不仅是为了教育目的,同时也是因为编程本…...
计算机网络:从底层原理到前沿应用,解锁数字世界的连接密码
计算机网络:从底层原理到前沿应用,解锁数字世界的连接密码 在信息如洪流般奔涌的时代,计算机网络宛如无形的脉络,贯穿于我们生活的每一个角落。它不仅是数据传输的通道,更是连接全球、驱动创新的核心力量。从日常的网络…...
grafana K6压测
文章目录 install and runscript.jsoptions最佳实践 report 解析 https://grafana.com/docs/k6/latest/get-started install and run install # mac brew install k6当前目录下生成压测脚本 # create file script.js k6 new [filename] # create file ‘script.js’ in …...
Vue的组合式API和选项式API有什么区别
Vue3的组合式API(Composition API)和选项式API(Options API)是两种不同的组件编写方式,主要区别如下: 1. 代码组织方式 选项式API: 按照选项(如data、methods、computed等࿰…...
ubuntu 安全策略(等保)
windows 三个帐号屏保设置组策略,密码超时次数/审计记录; linux 应具有登录失败处理功能,应配置并启用结束会话、限制非法登录次数和当登录连接超时自动退出等相关措施。 1、在系统中新建测试用户,使用此用户登录时多次输入错误密码&…...
c/c++蓝桥杯经典编程题100道(22)最短路径问题
最短路径问题 ->返回c/c蓝桥杯经典编程题100道-目录 目录 最短路径问题 一、题型解释 二、例题问题描述 三、C语言实现 解法1:Dijkstra算法(正权图,难度★★) 解法2:Bellman-Ford算法(含负权边&a…...
AI工具集合
设计相关 1. mastrtgo(暂时免费) :可以根据自然语言生成UI设计稿和前端代码 MasterGo 莫高设计 - AI 时代的数字界面生产平台 2. reddy.ai(暂时免费): 国外类似mastrtgo的平台 Readdy 3. midjourney (…...
CSDN 博客:CC++ 内存管理详解
CSDN 博客:C/C 内存管理详解 在软件开发过程中,内存管理是一个非常重要的环节。对于 C 和 C 这两种编程语言,它们都拥有独特的内存管理机制,理解这些机制对于编写高效、健壮的程序至关重要。本文将详细讲解 C/C 内存管理相关的内…...

表单制作代码,登录动画背景前端模板
炫酷动效登录页 引言 在网页设计中,按钮是用户交互的重要元素之一。一个炫酷的按钮特效不仅能提升用户体验,还能为网页增添独特的视觉吸引力。今天,我们将通过CSS来实现一个“表单制作代码,登录动画背景前端模板”。该素材呈现了数据符号排版显示出人形的动画效果,新颖有…...

嵌入式项目:STM32刷卡指纹智能门禁系统
本文详细介绍基于STM32的刷卡指纹智能门禁系统。 获取资料/指导答疑/技术交流/选题/帮助,请点链接: https://gitee.com/zengzhaorong/share_contact/blob/master/stm32.txt 1 系统功能 1.1 功能概述 本系统由STM32硬件端(下位机)…...
LeetCode 热题100 141. 环形链表
LeetCode 热题100 | 141. 环形链表 大家好,今天我们来解决一道经典的算法题——环形链表。这道题在 LeetCode 上被标记为简单难度,要求我们判断一个链表中是否存在环。下面我将详细讲解解题思路,并附上 Python 代码实现。 题目描述 给定一个…...
以绘图(绘制点、直线、圆、椭圆、多段线)为例子 通过设计模式中的命令模式实现
为了在命令模式的基础上实现撤销(Undo)和回退(Redo)功能,我们可以在每个命令类中记录一些必要的状态,允许我们撤销之前的操作,并在需要时回退操作。常见的做法是使用一个命令堆栈来存储历史命令…...

鹏哥c语言数组(初阶数组)
前言: 对应c语言视频54集 内容: 一维数组的创建 数组是一组相同元素的集合, 数组的创建方式 type_t就是数组的元素类型,const_n是一个常量表达式,用来指定数组的大小 c99标准之前的,数组的大小必须是…...

利用go-migrate实现MySQL和ClickHouse的数据库迁移
1. 背景 在使用gorm时 , 尽管已经有了自动建表和钩子函数 . 但是在面临希望了解到数据库的变更 , 和插入一些系统字段时 , 以及最关键的数据库迁移的工作 . gorm显得稍微有点不便 . 在了解到migrate这项技术后 , 就使用go-migrate开发了一个可以迁移MySQL和ClickHouse数据库的…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...

短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...