Mysql和ES、Redis数据同步方案汇总

news2025/2/27 17:21:59

文章目录

      • 前言
    • 一、数据同步方案
      • 1.同步双写
      • 2.异步双写([MQ](https://so.csdn.net/so/search?q=MQ&spm=1001.2101.3001.7020)方式)
      • 3.基于Mysql表定时扫描同步
      • 4.基于[Binlog](https://so.csdn.net/so/search?q=Binlog&spm=1001.2101.3001.7020)实时同步
    • 二、[数据迁移](https://so.csdn.net/so/search?q=数据迁移&spm=1001.2101.3001.7020)同步工具选型
      • 总结

前言

我们一般会使用Mysql用来存储数据,用Es来做全文检索和特殊查询,用redis来做数据的缓存

那么如何将数据优雅的从Mysql同步到Es以及redis呢?

一、数据同步方案

1.同步双写

这是一种最为简单的方式,在将数据写到mysql时,同时将数据写到ES或者redis。

这个方法的缺点是代码严重耦合,需要手动维护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);
    }

  • 优点:
    1、业务逻辑简单
    2、实时性高
  • 缺点:
    1、 硬编码,有需要写入mysql的地方都需要添加写入ES的代码;
    2、 业务强耦合;
    3、 存在双写失败丢数据风险;
    4、 性能较差:本来mysql的性能不是很高,再加一个ES,系统的性能必然会下降。
  • 双写失败风险,包括以下几种:
    1) ES系统不可用;
    2) 程序和ES之间的网络故障;
    3) 程序重启,导致系统来不及写入ES等。
    针对这种情况,有数据强一致性要求的,就必须双写放到事务中来处理,而一旦用上事物,则性能下降更加明显。

2.异步双写(MQ方式)

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

在执行完向Mysql中写入数据的逻辑后,发送MQ,告诉消费端这个数据需要写入Es,消费端收到消息后执行向Es写入数据的逻辑。这个方式的优点是Mysql和Es数据维护分离,开发Mysql和Es的人员只需要关心各自的业务。缺点是依然需要维护发送、接收MQ的逻辑,并且引入了MQ组件,增加了系统的复杂度。
在这里插入图片描述

伪代码:

    @Transactional(rollbackFor = Exception.class)
    public boolean parseJdDb(String keyword) throws IOException {
        //向数据库中插入
        List<JdGoods> jdGoods = htmlParseUtil.parseJd(keyword);
        //批量更新Mysql
        boolean b = this.saveBatch(jdGoods);
        log.info("异步同步至ES");
        rabbitTemplate.convertAndSend("es.exchange","es.renew.key", jdGoods);
        return b;
    }

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

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

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

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

如果对实时性要求不高的情况下,可以考虑用定时器来处理,具体步骤如下:
1、数据库的相关表中增加一个字段为timestamp的字段,任何crud操作都会导致该字段的时间发生变化;
2、原来程序中的CURD操作不做任何变化;
3、增加一个定时器程序,让该程序按一定的时间周期扫描指定的表,把该时间段内发生变化的数据提取出来;
4、逐条写入到ES中。

如下图所示:

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

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

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

业界目前较为流行的方案:Canal实现Mysql数据同步至Redis、Elasticsearch

4.基于Binlog实时同步

上面三种方案要么有代码侵入,要么有硬编码,要么有延迟,那么有没有一种方案既能保证数据同步的实时性又没有代入侵入呢?
当然有,可以利用mysql的binlog来进行同步。其实现原理如下:
在这里插入图片描述
具体步骤如下:
1) 读取mysql的binlog日志,获取指定表的日志信息;
2) 将读取的信息转为MQ;
3) 编写一个MQ消费程序;
4) 不断消费MQ,每消费完一条消息,将消息写入到ES中。

优点:
1、没有代码侵入、没有硬编码;
2、原有系统不需要任何变化,没有感知;
3、性能高;
4、业务解耦,不需要关注原来系统的业务逻辑。
缺点:
1、构建Binlog系统复杂;
2、如果采用MQ消费解析的binlog信息,也会像方案二一样存在MQ延时的风险。
在这里插入图片描述

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

数据迁移同步工具的选择比较多样,下表仅从 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进行数据同步的常见方案进行了汇总说明。

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

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

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

相关文章

MySQL常用配置详解

目录 一、MySQL 查看配置信息二、MySQL 查看服务器当前运行状态的信息三、MySQL 常用配置详解1、mysql&#xff08;使用mysql命令登录数据库时的默认的设置&#xff09;2、client &#xff08;客户端默认设置内容&#xff09;3、mysqld&#xff08;服务端端配置&#xff09; 四…

Elasticsearch 的页面工具kibana中 dev tool 菜单使用

首先来到kibana 页面&#xff0c;找到 dev tool 菜单&#xff0c;选择Console ​​​​​​es的页面工具kibana中 dev tool 菜单使用_kibana中的dev tools 在哪里_nandao158的博客-CSDN博客 1、查所有的索列表 GET /_cat/indices?v 或者 GET /_cat/indices 2、创建索引 PO…

【VSCode设置单个子文件时不要平级显示】

打开VSCode 的菜单 【文件】》【首选项】》【设置】&#xff0c;搜索输入【compact】&#xff0c;然后将 Explorer:Compact Folder的勾选去掉即可

Python数据容器——列表、元组、字符串、集合、字典

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 本文专栏&#xff1a;Python专栏 专栏介绍&#xff1a;本专栏为免费专栏&#xff0c;并且会持续更新python基础知识&#xff0c;欢迎各位订阅关注。 目录 一、了解数据容器 1. 为什么需要数据容器&#xff1f…

vscode在mac上保存项目文件提示保存失败

原因&#xff1a;可能是由于创建命令时使用“sudo xxxx” 解决办法&#xff1a; 进入访达–》选中简介–》打开锁–》选中自己用户–》输入密码–》结束 注意&#xff1a;由于这个设置只适用于本目录&#xff0c;内部目录还是有权限限制&#xff0c;解决办法点边上的小点–》…

Linux 文件 目录管理

Linux 文件 基本属性 Linux 系统是一种典型的多用户系统&#xff0c;为了保护系统的安全性&#xff0c;不同的用户拥有不同的地位和权限。Linux 系统对不同的用户访问同一文件&#xff08;包括目录文件&#xff09;的权限做了不同的规定。 可以使用命令&#xff1a;ll 或 ls –…

科目二倒车入库

调整座位和后视镜 离合踩到底大腿小腿成130-140 上半身90-100 座椅高度能看到前方全部情况 后视镜调节到能看到后门把手&#xff0c;且后门把手刚好在后视镜上方边缘、离车1/3处。 保持直线&#xff1a; 前进&#xff1a; 车仪表盘中央的原点和地面上的黄线擦边&#xff…

Android 10.0 系统开启和关闭黑白模式主题功能实现

1. 概述 在10.0的rom系统开发定制化中,在系统SystemUI的下拉状态栏中,产品开发功能需求要求添加黑白模式功能开关的功能,就是打开黑白模式,系统颜色就会变成黑白颜色, 关闭黑白模式开关系统就会变成彩色模式,所以就需要了解下系统是怎么设置黑白模式和彩色模式的,然后添…

现代循环神经网络-门控循环单元(GRU)

理论 门控隐状态 门控循环单元与普通的循环神经网络之间的关键区别在于&#xff1a; 前者支持隐状态的门控。 这意味着模型有专门的机制来确定应该何时更新隐状态&#xff0c; 以及应该何时重置隐状态。 这些机制是可学习的&#xff0c;并且能够解决了上面列出的问题。 例如&…

WPF 控件专题 RadioButton样式一

RadioButton样式示例 Style样式修改如下&#xff1a;通过改下RadioButton的ControlTemplate&#xff0c;修改控件所呈现的外观形状和颜色&#xff1b;通过IsChecked属性触发器样式变化。 <UserControl.Resources><Style x:Key"defaultRadioStyle" TargetT…

Ubuntu中安装Anaconda 如何将 路径导入为全局变量

第一步&#xff1a;将你的anaconda 路径复制下来&#xff0c;在终端输入对应路径。 echo export PATH"/home/你的用户名/anaconda3/bin:$PATH" >> ~/.bashrc 第二步&#xff1a;在终端输入下面命令或者重启系统。 source ~/.bashrc 在对应的anaconda安装目…

RocketMQ 发送事务消息

文章目录 事务的相关理论事务ACID特性CAP 理论BASE 理论 事务消息应用场景MQ 事务消息处理处理逻辑 RocketMQ 事务消息处理流程官网事务消息流程图 rocketmq-client-java 示例&#xff08;gRPC 协议&#xff09;创建事务主题生产者消费者 rocketmq-client 示例&#xff08;Remo…

pycharm中恢复原始界面布局_常用快捷键_常用设置

文章目录 1 恢复默认布局1 .1直接点击file→Manage IDE Settings→Restore Default Settings&#xff08;如下图所示&#xff09;&#xff1a;1.2 直接点击Restore and Restart&#xff0c; 然后Pycharm就会自动重启&#xff0c;重启之后的界面就是最原始的界面了 2 改变主题2.…

(NDK编译)详解使用Android.mk编译的C/C++程序过程

想要在Android设备上运行C/C程序可执行文件&#xff0c;可采用一个方法就是使用NDK编译&#xff0c;很多时候要比gcc编译更适合&#xff0c;这里我采用的是imx6q开发板上面装载了自己编写的Android6.0.1镜像&#xff0c;在Ubuntu64位系统上采用NDK编译。 目录 1.准备文件 2.…

任意文件的上传和下载

1.任意文件下载&#xff08;高危&#xff09; 定义 一些网站由于业务需求&#xff0c;往往需要提供文件查看或文件下载功能&#xff0c;但若对用户查看或下载的文件不做限制&#xff0c;则恶意用户就能够查看或下载任意敏感文件&#xff0c;这就是文件查看与下载漏洞。 可以下载…

BCC介绍

本文参考以下博文&#xff1a; bcc/ebpf使用介绍一文看懂eBPF、eBPF的使用&#xff08;超详细&#xff09; ebpf之bcc程序入门 特此致谢&#xff01; BCC&#xff08;有时也写作bcc&#xff09;的全称是BPF Compiler Collection&#xff0c;即BPF编译器集合。BCC是一个开源项…

QT实现钟表

1、 头文件 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QPaintEvent> //绘制事件类 #include <QDebug> //信息调试类 #include <QPainter> //画家类 #include <QTimerEve…

vue3+vite3项目打包优化

vue3vite3项目打包优化 1、前言2、视图分析工具rollup-plugin-visualizer3、路由懒加载4、第三方库CDN引入5、使用 gzip 压缩6、按需引入第三方库7、使用 Tree Shaking8、剔除console和debugger9、分包策略10、图片压缩 1、前言 Vue项目开发完毕后&#xff0c;对项目进行打包发…

数据预处理方式合集

删除空行 #del all None value data_all.dropna(axis1, howall, inplaceTrue) 删除空列 #del all None value data_all.dropna(axis0, howall, inplaceTrue) 缺失值处理 观测缺失值 观测数据缺失值有一个比较好用的工具包——missingno&#xff0c;直接传入DataFrame&…

windows 查看端口被占用

1. 使用netstat -ano | findstr 8181 命令查看被占用的端口所在的pid 2. 查看是被哪个应用占用tasklist|findstr "pid" 3.杀死他 taskkill -pid 19200 -f