【技术选型】Mysql和ES数据同步方案汇总

news2024/10/7 6:48:00

文章目录

  • 背景
  • 一、Mysql和ES各自的特点
    • 为什么选用Mysql
    • 为什么选用 ES
  • 二、数据同步方案
    • 1、同步双写
    • 2、异步双写(MQ方式)
    • 3、基于Mysql表定时扫描同步
    • 4、基于Binlog实时同步
    • 5、业界目前较为流行的方案:使用canal监听binlog同步数据到es
  • 三、数据迁移同步工具选型
  • 总结
  • 参考资料

背景

在实际项目开发中,我们经常将Mysql作为业务数据库,ES作为查询数据库,用来实现读写分离,缓解Mysql数据库的查询压力,应对海量数据的复杂查询。

这其中有一个很重要的问题,就是如何实现Mysql数据库和ES的数据同步,今天和大家聊聊Mysql和ES数据同步的各种方案。

一、Mysql和ES各自的特点

为什么选用Mysql

MySQL 在关系型数据库历史上并没有特别优势的位置,Oracle/DB2/PostgreSQL(Ingres) 三老比 MySQL 开发早了 20 来年, 但是乘着 2000 年的互联网东风, LAMP 架构得到迅速的使用,特别在中国,大部分新兴企业的 IT 系统主数据沉淀于 MySQL 中。

核心特点:开源免费、高并发、稳定、支持事务、支持SQL查询

  • 高并发能力:MySQL 内核特征特别适合高并发简单 SQL 操作 ,链接轻量化(线程模式),优化器、执行器、事务引擎相对简单粗暴,存储引擎做得比较细致

  • 稳定性好:主数据库最大的要求就是稳定、不丢数据,MySQL 内核特征反倒让其特点鲜明,从而达到很好的稳定性,主备系统也很早就 ready ,应对崩溃情况下的快速切换,innodb 存储引擎也保障了 MySQL 下盘稳定

  • 操作便捷:良好、便捷的用户体验(相比 PostgreSQL) , 让应用开发者非常容易上手 ,学习成本较低

  • 开源生态:MySQL 是一款开源产品,让上下游厂商围绕其构建工具相对简单,HA proxy、分库分表中间件让其实用性大大加强,同时开源的特质让其有大量的用户

为什么选用 ES

ES 几个显著的特点,能够有效补足 MySQL 在企业级数据操作场景的缺陷,而这也是我们将其选择作为下游数据源重要原因

核心特点:支持分词检索,多维筛选性能好,支持海量数据查询

  • 文本搜索能力:ES 是基于倒排索引实现的搜索系统,配合多样的分词器,在文本模糊匹配搜索上表现得比较好,业务场景广泛

  • 多维筛选性能好:亿级规模数据使用宽表预构建(消除 join),配合全字段索引,使 ES 在多维筛选能力上具备压倒性优势,而这个能力是诸如 CRM, BOSS, MIS 等企业运营系统核心诉求,加上文本搜索能力,独此一家

  • 开源和商业并行:ES 开源生态非常活跃,具备大量的用户群体,同时其背后也有独立的商业公司支撑,而这让用户根据自身特点有了更加多样、渐进的选择

二、数据同步方案

1、同步双写

这是一种最为简单的方式,在将数据写到mysql时,同时将数据写到ES。
在这里插入图片描述

  • 伪代码:
/**
 * 新增商品
 */
@Transactional(rollbackFor = Exception.class)
public void addGoods(GoodsDto goodsDto) {
     //1、保存Mysql
     Goods goods = new Goods();
     BeanUtils.copyProperties(goodsDto,goods);
     GoodsMapper.insert();
 
     //2、保存ES
     IndexRequest indexRequest = new IndexRequest("goods_index","_doc");
     indexRequest.source(JSON.toJSONString(goods), XContentType.JSON);
     indexRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
     highLevelClient.index(indexRequest);
}
  • 优点:

    • 业务逻辑简单
    • 实时性高
  • 缺点:

    • 硬编码,有需要写入mysql的地方都需要添加写入ES的代码;
    • 业务强耦合;
    • 存在双写失败丢数据风险;
    • 性能较差:本来mysql的性能不是很高,再加一个ES,系统的性能必然会下降。
  • 附:
    上面说的双写失败风险,包括以下几种:

    • ES系统不可用;
    • 程序和ES之间的网络故障;
    • 程序重启,导致系统来不及写入ES等。

针对这种情况,有数据强一致性要求的,就必须双写放到事务中来处理,而一旦用上事物,则性能下降更加明显。

2、异步双写(MQ方式)

针对多数据源写入的场景,可以借助MQ实现异步的多源写入,这种情况下各个源的写入逻辑互不干扰,不会由于单个数据源写入异常或缓慢影响其他数据源的写入,虽然整体写入的吞吐量增大了,但是由于MQ消费是异步消费,所以不适合实时业务场景。

在这里插入图片描述

  • 优点:

    • 性能高
    • 不易出现数据丢失问题,主要基于MQ消息的消费保障机制,比如ES宕机或者写入失败,还能重新消费MQ消息。
    • 多源写入之间相互隔离,便于扩展更多的数据源写入
  • 缺点:

    • 硬编码问题,接入新的数据源需要实现新的消费者代码
    • 系统复杂度增加:引入了消息中间件
    • 可能出现延时问题:MQ是异步消费模型,用户写入的数据不一定可以马上看到,造成延时。

3、基于Mysql表定时扫描同步

上面两种方案中都存在硬编码问题,也就是有任何对mysq进行增删改查的地方要么植入ES代码,要么替换为MQ代码,代码的侵入性太强。

如果对实时性要求不高的情况下,可以考虑用定时器来处理,具体步骤如下:

  • 数据库的。m字段,任何crud操作都会导致该字段的时间发生变化;
  • 原来程序中的CURD操作不做任何变化;
  • 增加一个定时器程序,让该程序按一定的时间周期扫描指定的表,把该时间段内发生变化的数据提取出来;
  • 逐条写入到ES中。

如下图所示:
在这里插入图片描述

该方案的典型实现是借助logstash实现数据同步,其底层实现原理就是根据配置定期使用sql查询新增的数据写入ES中,实现数据的增量同步。

具体实现可以参考:通过Logstash实现mysql数据定时增量同步到ES
在这里插入图片描述

  • 优点:
  • 不改变原来代码,没有侵入性、没有硬编码;
  • 没有业务强耦合,不改变原来程序的性能;
  • Worker代码编写简单不需要考虑增删改查;
  • 缺点:
  • 时效性较差,由于是采用定时器根据固定频率查询表来同步数据,尽管将同步周期设置到秒级,也还是会存在一定时间的延迟。
  • 对数据库有一定的轮询压力,一种改进方法是将轮询放到压力不大的从库上。

4、基于Binlog实时同步

上面三种方案要么有代码侵入,要么有硬编码,要么有延迟,那么有没有一种方案既能保证数据同步的实时性又没有代入侵入呢?

当然有,可以利用mysql的binlog来进行同步。其实现原理如下:
在这里插入图片描述

  • 具体步骤如下:

    • 读取mysql的binlog日志,获取指定表的日志信息;
    • 将读取的信息转为MQ;
    • 编写一个MQ消费程序;
    • 不断消费MQ,每消费完一条消息,将消息写入到ES中。
  • 优点:

    • 没有代码侵入、没有硬编码;
    • 原有系统不需要任何变化,没有感知;
    • 性能高;
    • 业务解耦,不需要关注原来系统的业务逻辑。
  • 缺点:

  • 构建Binlog系统复杂;

  • 如果采用MQ消费解析的binlog信息,也会像方案二一样存在MQ延时的风险。

5、业界目前较为流行的方案:使用canal监听binlog同步数据到es

在这里插入图片描述

  • canal ,译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费。

    说白了就是,根据Mysql的binlog日志进行增量同步数据。要理解canal的原理,就要先了解mysql的主从复制原理:

    • 所有的create update delete操作都会进入MySQLmaster节点
    • master节点会生成binlog文件,每次操作mysql数据库就会记录到binlog文件中
    • slave节点会订阅master节点的binlog文件,以增量备份的形式同步数据到slave数据
  • canal原理就是伪装成mysql的从节点,从而订阅master节点的binlog日志,主要流程为:

    • canal服务端向mysql的master节点传输dump协议
    • mysql的master节点接收到dump请求后推送binlog日志给canal服务端,解析binlog对象(原始为byte流)转成Json格式
    • canal客户端通过TCP协议或MQ形式监听canal服务端,同步数据到ES

三、数据迁移同步工具选型

数据迁移同步工具的选择比较多样,下表仅从 MySQL 同步 ES 这个场景下,对一些笔者深度使用研究过的数据同步工具进行对比,用户可以根据自己的实际需要选取适合自己的产品。

特性\产品CanalDTSCloudCanal
是否支持自建ES
ES对端版本支持丰富度
支持ES6和ES7

支持ES5,ES6和ES7

支持ES6和ES7
嵌套类型支持join/nested/objectobjectnested/object
join支持方式基于join父子文档&反查基于宽表预构建&反查
是否支持结构迁移
是否支持全量迁移
是否支持增量迁移
数据过滤能力
-仅全量可添加where条件

-全增量阶段where条件

-全增量阶段where条件
是否支持时区转换
同步限流能力
任务编辑能力
数据源支持丰富度
架构模式订阅消费模式
需先写入消息队列
直连模式直连模式
监控指标丰富度
性能指标监控

性能指标监控

性能指标、资源指标监控
报警能力无 针对延迟、异常的电话报警针对延迟、异常的钉钉、短信、邮件报警
任务可视化创建&配置&管理能力
是否开源
是否免费否 是社区版、SAAS版免费
是否支持独立输出否依赖云平台整体输出
是否支持SAAS化使用

总结

本文主要对Mysql和ES进行数据同步的常见方案进行了汇总说明。

  • 同步双写是最简单的同步方式,能最大程度保证数据同步写入的实时性,最大的问题是代码侵入性太强。
  • 异步双写引入了消息中间件,由于MQ都是异步消费模型,所以可能出现数据同步延迟的问题。好处是在大规模消息同步时吞吐量更、高性能更好,便于接入更多的数据源,且各个数据源数据消费写入相互隔离互不影响。
  • 基于Mysql表定时扫描同步 ,原理是通过定时器定时扫描表中的增量数据进行数据同步,不会产生代码侵入,但由于是定时扫描同步,所以也会存在数据同步延迟问题,典型实现是采用 Logstash 实现增量同步。
  • 基于Binlog实时同步 ,原理是通过监听Mysql的binlog日志进行增量同步数据。不会产生代码侵入,数据同步的实时也能得到保障,弊端是Binlog系统都较为复杂。典型实现是采用 canal 实现数据同步。

参考资料

MySQL 数据实时同步到 Elasticsearch 的技术方案选型和思考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/461036.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java学习笔记-01

目录 jdk安装及环境配置 java前置知识 编写一个HelloWorld 常量 数据类型 变量 类型转换 算数运算符 一元运算符( --) 关系运算符 逻辑运算符(与或非,逻辑异或) 三元(三目)运算符 Scanner类的简单使用 jdk安装及环境配置 看到的一篇文章,…

Vue 过渡与动画的使用

transition 标签的作用:在插入 更新或 移除 DOM 元素时 可以给元素添加动画效果. transition 标签配合的 class 类有: - v-enter:进入的起点。 - v-enter-active:进入时的效果。 - v-enter-to:进入的终点。 - v-leave:离开的起点。 - v-leave-active:离…

USB-C为什么可以取代传统接口?消费类电子产品如何改用TYPE-C接口?

现如今,越来越多的设备选择使用Type-C接口来取代之前传统的接口。例如:手机去掉了之前的Micro USB接口,而选择Type-C;还有好多笔记本也取消了很多传统的传输接口,而采用Type-C来替代它们。那为何Type-C可以取代那么多的…

chatGPT电脑端怎么安装-chatgpt国内怎么用

chatgpt怎么用 ChatGPT是一个大型语言模型,可以用于自然语言生成和理解任务,比如对话系统、文本生成、翻译、摘要等。您可以使用以下步骤来使用ChatGPT: 选择一个平台:ChatGPT可以在不同的平台上运行,比如Python、JavaScript、Jav…

【Java基础练习题】多线程IO流操作实现文件的复制(举一反三)

前言:时不我待,忽而已春,初夏将至。然惊觉自身Java基础仍薄弱不堪,虽“雄关万道真如铁”,只得“万里关山从头越”。把基础打扎实才是根本,对于日后的工作而言也是极为重要。通过不断的学习和理解加上手动实…

使用vue2搭建项目的流程

论坛项目 服务器地址: http://172.16.11.18:9090 http://xawn.f3322.net:10004/ swagger地址: http://172.16.11.18:9090/doc.html http://xawn.f3322.net:10004/doc.html 前端h5地址: http://172.16.11.18:9099/h5/#/ http://xawn.f3322.net:10005/h5/# 前端管理系统…

回文自动机(PAM)入门路线 + P3649 【模板】[APIO2014] 回文串(PAM)

个人比较推荐的回文自动机学习路径: 回文自动机学习博客: 回文树(讲的最严谨,oiwiki上的) 回文自动机(Palindrome Automanton PAM)(讲的最通俗易懂,知乎上的&#xff09…

Docker快速部署springboot项目

有很多开发者在项目部署过程中都会遇到一些繁琐的问题,比如打包、上传、部署等。而使用Docker可以非常方便地解决这些问题。在本文中,将详细讲解如何使用IDEA中的docker打包插件,将代码打包并直接发布到服务器上。这样,我们就可以…

CSS中的 clip 属性

参考:https://baijiahao.baidu.com/s?id1757136902803734131&wfrspider&forpc 作用: clip 属性用来设置元素的形状,用于剪裁绝对定位的元素。当一幅图像的尺寸大于包含它的元素时,clip 属性允许规定一个元素的可见尺寸…

blender 制作城市建筑模型

我不是很会用blender 但是他可以直接制作一篇区域的建筑模型 BlenderGIS插件 城市建筑3D模型自动生成 教程_Zhichao_97的博客-CSDN博客 学习了两种 一种是通过geo.json自己加了一堆mesh 或者geometry 自己用three 做的模型 另一种是用blender 做一个整个的模型直接导入进去 …

Java企业电子招标采购系统源码Spring Boot + Mybatis + 前后端分离 构建企业电子招采平台之立项流程图

项目说明 随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以及…

LVS+keepalives高可用负载均衡

keepalived是一个基于vrrp协议来实现的LVS服务高可用方案,可解决静态路由器出现的单点故障问题 解决单点故障。 通过主备来保证高可用性, vrrp回忆 vlan区分广播域,vlan if 虚拟接口 vrrp只有一种报文:Advertisement报文(通告…

SparkStreaming学习之——无状态与有状态转化、遍历kafka的topic消息、WindowOperations

目录 一、状态转化 二、kafka topic A→SparkStreaming→kafka topic B (一)rdd.foreach与rdd.foreachPartition (二)案例实操1 1.需求: 2.代码实现: 3.运行结果 (三)案例实操2 1.需求: 2.代码实现: 3.运行结果 三、W…

代码在洛谷上跑得慢怎么办?

前言 你有没有试过以下几种情况: 代码在别的OJ上能过,在洛谷上就T了你的代码和同学的几乎相同,但他的AC了,你的却TLE了 遇到这些情况,你可能要花上一个多小时才能解决,甚至难以解决,将问题一…

【springboot-04】ElasticSearch8.7搜索

为什么学?因为它查询速度很快,而且是非关系型数据库 (NoSql) 一些增删改查已经配置好了,无需重复敲码 ElasticSearch 更新快,本篇文章将主要介绍一些常用方法。 对于 spirngboot 整合 Es 的文章很少&#x…

看了这一篇文章,你还不懂MySQL体系结构,你来找我

前言 工作很长时间了,对于数据库的掌握程度却仅仅停留在表面的CRUD阶段,对于深层次的原理和技术知识了解的少之又少,随着岁数不断的增长。很多时候,出去找工作很迷茫,被面试官问的感觉自己很菜。现在利用工作休息时间&…

微信小程序第五节——登录那些事儿(超详细的前后端完整流程)

📌 微信小程序第一节 ——自定义顶部、底部导航栏以及获取胶囊体位置信息。 📌 微信小程序第二节 —— 自定义组件 📌 微信小程序第三节 —— 页面跳转的那些事儿 📌 微信小程序第四节—— 网络请求那些事儿 😜作 …

人工智能时代背景下,如何发展与应用自动化测试?

人工智能时代为自动化测试提供了机会和挑战。在发展自动化测试方面,是人工智能领域下的一个应用方向,和无人驾驶、机器人等一样,都是AI技术的应用场景。从技术的发展角度看,自动化测试一共经历了四代发展变化。从最早提出自动化测…

关于 变量

关于局部变量和静态变量&#xff08;基于有一定指针基础&#xff09; #include<stdio.h> void aaa() {int n10;} int main() {printf("%d",n);return 0; } 在这个代码里&#xff0c;很明显会报错&#xff0c;未定义该n标识符&#xff0c;因为这个n是局部变量…

在程序里面执行system(“cd /某个目录“),为什么路径切换不成功?

粉丝提问&#xff1a; 彭老师&#xff0c;问下&#xff0c;在程序里面执行system(“cd /某个目录”)&#xff0c;这样会切换不成功&#xff0c;为啥呢 实例代码&#xff1a; 粉丝的疑惑是明明第10行执行了cd /media操作&#xff0c; 为什么12行执行的pwd > test2.txt 结…