数据同步-Mysql同步到ElasticSearch

news/2024/12/23 6:39:42/

Mysql同步到ElasticSearch

  • 数据同步
    • 1、定时任务
    • 2、双写
    • 3、MQ异步写入
    • 4、Logstash
    • 5、Canal

数据同步

一般情况下,如果做查询搜索功能,使用 ES 来模糊搜索,但是数据是存放在数据库 MySQL 里的,所以说我们需要把 MySQL 中的数据和 ES 进行同步,保证数据一致(以 MySQL 为主)。

数据同步包含:全量同步 (首次) + 增量同步(新数据)。

首次安装完 ES,把 MySQL 数据全量同步到 ES 里,写一个单次脚本。

public class FullSyncPostToEs implements CommandLineRunner {@Resourceprivate PostService postService;@Resourceprivate PostEsDao postEsDao;@Overridepublic void run(String... args) {List<Post> postList = postService.list();if (CollectionUtils.isEmpty(postList)) {return;}List<PostEsDTO> postEsDTOList = postList.stream().map(PostEsDTO::objToDto).collect(Collectors.toList());final int pageSize = 500;int total = postEsDTOList.size();log.info("FullSyncPostToEs start, total {}", total);for (int i = 0; i < total; i += pageSize) {int end = Math.min(i + pageSize, total);log.info("sync from {} to {}", i, end);postEsDao.saveAll(postEsDTOList.subList(i, end));}log.info("FullSyncPostToEs end, total {}", total);}
}

增量同步有五种方式:

1、定时任务

  • 定时任务:比如1 分钟 1 次,找到 MySQL 中过去几分钟内(至少是定时周期的 2 倍)发生改变的数据,然后更新到 ES。
public class IncSyncPostToEs {@Resourceprivate PostMapper postMapper;@Resourceprivate PostEsDao postEsDao;/*** 每分钟执行一次*/@Scheduled(fixedRate = 60 * 1000)public void run() {// 查询近 5 分钟内的数据Date fiveMinutesAgoDate = new Date(new Date().getTime() - 5 * 60 * 1000L);List<Post> postList = postMapper.listPostWithDelete(fiveMinutesAgoDate);if (CollectionUtils.isEmpty(postList)) {log.info("no inc post");return;}List<PostEsDTO> postEsDTOList = postList.stream().map(PostEsDTO::objToDto).collect(Collectors.toList());final int pageSize = 500;int total = postEsDTOList.size();log.info("IncSyncPostToEs start, total {}", total);for (int i = 0; i < total; i += pageSize) {int end = Math.min(i + pageSize, total);log.info("sync from {} to {}", i, end);postEsDao.saveAll(postEsDTOList.subList(i, end));}log.info("IncSyncPostToEs end, total {}", total);}
}

优点:简单易懂、占用资源少、不用引入第三方中间件;
缺点:有时间差;
应用场景:数据时间内不同步影响不大、或者数据几乎不发生修改;

2、双写

  • 双写:写数据的时候,必须去写入到ES,更新、删除都需要操作ES(加事务:可能存在写入某一方出现失败,形成脏数据)。

3、MQ异步写入

  • MQ异步写入:在写入数据库时,通过MQ异步写入ES,同样可能存在数据写入不一致问题。

4、Logstash

  • ES的Logstash数据同步管道:Logstash 事件处理管道有三个阶段:输入过滤器输出

下载地址:https://www.elastic.co/guide/en/logstash/7.17/installing-logstash.html
inputs 模块负责收集数据,filters 模块可以对收集到的数据进行格式化、过滤、简单的数据处理,outputs 模块负责将数据同步到目的地,Logstash的处理流程,就像管道一样,数据从管道的一端,流向另外一端。

inputs 和 outputs 支持编解码器,使您能够在数据进入或离开管道时对数据进行编码或解码,而无需使用单独的过滤器。
在这里插入图片描述
启动Logstash,添加一个conf配置文件,便可完成同步任务。

 C:\Windows\system32> cd C:\logstash-7.17.23\C:\logstash-7.17.23> .\bin\logstash.bat -f .\config\syslog.conf

syslog.conf:数据同步的配置文件。

举个例子:

输入事件:

input {jdbc {jdbc_driver_library => "mysql-connector-java-5.1.36-bin.jar"  //数据库驱动jdbc_driver_class => "com.mysql.jdbc.Driver"                 //连接数据库jdbc_connection_string => "jdbc:mysql://localhost:3306/mydb"jdbc_user => "mysql"jdbc_password => "mysql"statement => "SELECT * from songs where artist = :favorite_artist"  //执行sql语句parameters => { "favorite_artist" => "Beethoven" }   //预编译  schedule => "* * * * *"    //corn表达式,多久进行同步}
}

:sql_last_value 可以设置每次查询结果中updatetime为最后的时间,作为下次增量同步的开始时间(需要对时间进行排序才能保证最后一条数据为时间最大的)。

input {jdbc {statement => "SELECT id, mycolumn1, mycolumn2 FROM my_table WHERE updatetime > :sql_last_value order  by updatetime desc"use_column_value => truetracking_column => "updatetime "# ... other configuration bits}
}

输出事件:

output {
stdout { codec => rubydebug }
elasticsearch {
hosts => "127.0.0,1:9200"  //写入到ES
index => "post_v1"        //ES对应的索引
document_id => "%{id)"	    //取数据库查询出的id作为ES中的唯一id
}
}

过滤事件:

filter {
mutate {
rename => {
"updatetime" =>"updateTime"    //给字段重命名
"userid"     => "userId"
"createtime" =>"createTime"
"isdelete"   =>"isDelete"
remove_field =>["thumbnm""favournum"]   //移除不需要同步到ES中的字段

更多参数,可参考官方文档进行配置:https://www.elastic.co/guide/en/logstash/7.17/output-plugins.html。

5、Canal

  • Canal

优点:实时同步,实时性非常强;
原理:数据库每次修改时,会修改 binlog 文件,只要监听该文件的修改,就能第一时间得到消息并处理;
canal: 帮你监听 binlog,并解析 binlog 为你可以理解的内容,它伪装成了 mysql 的从节点,获取主节点给的 binlog。

在这里插入图片描述

参考文档:https://github.com/alibaba/canal/wiki/QuickStart

后记
👉👉💕💕美好的一天,到此结束,下次继续努力!欲知后续,请看下回分解,写作不易,感谢大家的支持!! 🌹🌹🌹


http://www.ppmy.cn/news/1524351.html

相关文章

【CSS】样式水平垂直居中

行内元素&#xff1a; 如果被设置元素为文本、图片等行内元素时&#xff0c;水平居中是通过给父元素设置 text-align:center <body> <div class"txtCenter">我想要在父容器中水平居中显示。</div> </body>div是文本元素的父元素 因此我们对…

基于SpringBoot+Vue前后端分离的在线宠物商店详细设计实现(协同过滤算法)【原创】

一.系统设计背景与需求分析 设计背景 在近年来&#xff0c;随着社会经济的飞速发展和人们生活水平的显著提升&#xff0c;养宠物已经成为了许多人日常生活中不可或缺的一部分。宠物不仅为人们带来了欢乐和陪伴&#xff0c;还成为了表达个性和生活态度的一种方式。随着养宠物的…

docker-compose部署MySQL高可用工具orchestrator

主要对一个MySQL主从架构部署orchestartor进行高可用验证&#xff0c;orchestrator部署在主从架构的从节点上&#xff0c;当然最好是部署在其他机器上&#xff0c;后端数据库采用的直接是MySQL的从库&#xff0c;所以没有创建orchestrator的后端数据库的流程。 创建yaml文件 m…

Web安全之XSS跨站脚本攻击:如何预防及解决

1. 什么是XSS注入 XSS&#xff08;跨站脚本攻击&#xff0c;Cross-Site Scripting&#xff09;是一种常见的Web安全漏洞&#xff0c;通过注入恶意代码&#xff08;通常是JavaScript&#xff09;到目标网站的网页中&#xff0c;以此在用户浏览网页时执行。攻击者可以通过XSS获取…

【人脸检测】SCRFD:训练数据采样和计算分配策略结合的高效人脸检测方法

Sample and Computation Redistribution for Efficient Face Detection 论文链接&#xff1a;http://arxiv.org/abs/2105.04714 代码链接&#xff1a;https://github.com/deepinsight/insightface/tree/master/detection/scrfd 一、摘要 文中指出训练数据采样和计算分配策略…

Rust 变量基础知识

文章目录 发现宝藏一、 Rust变量与可变性二、变量与常量三、变量隐藏&#xff08;shadowing&#xff09; 发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【宝藏入口】。 一、 Rust变量与可变性…

Zabbix自定义监控项与触发器

当我们需要获取某台主机上的数据时&#xff0c;直接利用 zabbix 提供的模板可以很方便的获得需要的数据,但是有些特别的数据&#xff0c;利用这些现有的模板或监控项是无法实现的&#xff0c;例如网站状态信息的监控、mysql数据库主从状态等信息。这是就需要自己定义键值和监控…

【玩转贪心算法专题】406. 根据身高重建队列【中等】

【玩转贪心算法专题】406. 根据身高重建队列【中等】 1、力扣链接 https://leetcode.cn/problems/queue-reconstruction-by-height/ 2、题目描述 假设有打乱顺序的一群人站成一个队列&#xff0c;数组 people 表示队列中一些人的属性&#xff08;不一定按顺序&#xff09;。…