写在前面

在当今互联网行业,尤其是现在分布式、微服务开发环境下,为了提高搜索效率,以及搜索的精准度,会大量使用Redis、Memcached等NoSQL数据库,也会使用大量的Solr、Elasticsearch等全文检索服务。那么,这个时候,就会有一个问题需要我们来思考和解决:那就是数据同步的问题!如何将实时变化的数据库中的数据同步到Redis/Memcached或者Solr/Elasticsearch中呢?

互联网背景下的数据同步需求

在当今互联网行业,尤其是现在分布式、微服务开发环境下,为了提高搜索效率,以及搜索的精准度,会大量使用Redis、Memcached等NoSQL数据库,也会使用大量的Solr、Elasticsearch等全文检索服务。那么,这个时候,就会有一个问题需要我们来思考和解决:那就是数据同步的问题!如何将实时变化的数据库中的数据同步到Redis/Memcached或者Solr/Elasticsearch中呢?

例如,我们在分布式环境下向数据库中不断的写入数据,而我们读数据可能需要从Redis、Memcached或者Elasticsearch、Solr等服务中读取。那么,数据库与各个服务中数据的实时同步问题,成为了我们亟待解决的问题。

试想,由于业务需要,我们引入了Redis、Memcached或者Elasticsearch、Solr等服务。使得我们的应用程序可能会从不同的服务中读取数据,如下图所示。

本质上讲,无论我们引入了何种服务或者中间件,数据最终都是从我们的MySQL数据库中读取出来的。那么,问题来了,如何将MySQL中的数据实时同步到其他的服务或者中间件呢?

注意:为了更好的说明问题,后面的内容以MySQL数据库中的数据同步到Solr索引库为例进行说明。

数据同步解决方案

1.在业务代码中同步

在增加、修改、删除之后,执行操作Solr索引库的逻辑代码。例如下面的代码片段。

public ResponseResult updateStatus(Long[] ids, String status){
try{
goodsService.updateStatus(ids, status);
if("status_success".equals(status)){
List<TbItem> itemList = goodsService.getItemList(ids, status);
itemSearchService.importList(itemList);
return new ResponseResult(true, "修改状态成功")
}
}catch(Exception e){
return new ResponseResult(false, "修改状态失败");
}
}

优点:

操作简便。

缺点:

业务耦合度高。

执行效率变低。

2.定时任务同步

在数据库中执行完增加、修改、删除操作后,通过定时任务定时的将数据库的数据同步到Solr索引库中。

定时任务技术有:SpringTask,Quartz。

哈哈,还有我开源的mykit-delay框架,开源地址为:https://github.com/sunshinelyz/mykit-delay

这里执行定时任务时,需要注意的一个技巧是:第一次执行定时任务时,从MySQL数据库中以时间字段进行倒序排列查询相应的数据,并记录当前查询数据的时间字段的最大值,以后每次执行定时任务查询数据的时候,只要按时间字段倒序查询数据表中的时间字段大于上次记录的时间值的数据,并且记录本次任务查询出的时间字段的最大值即可,从而不需要再次查询数据表中的所有数据。

注意:这里所说的时间字段指的是标识数据更新的时间字段,也就是说,使用定时任务同步数据时,为了避免每次执行任务都会进行全表扫描,最好是在数据表中增加一个更新记录的时间字段。

优点:

同步Solr索引库的操作与业务代码完全解耦。

缺点:

数据的实时性并不高。

3.通过MQ实现同步

在数据库中执行完增加、修改、删除操作后,向MQ中发送一条消息,此时,同步程序作为MQ中的消费者,从消息队列中获取消息,然后执行同步Solr索引库的逻辑。

我们可以使用下图来简单的标识通过MQ实现数据同步的过程。

我们可以使用如下代码实现这个过程。

public ResponseResult updateStatus(Long[] ids, String status){
try{
goodsService.updateStatus(ids, status);
if("status_success".equals(status)){
List<TbItem> itemList = goodsService.getItemList(ids, status);
final String jsonString = JSON.toJSONString(itemList);
jmsTemplate.send(queueSolr, new MessageCreator(){
@Override
public Message createMessage(Session session) throws JMSException{
return session.createTextMessage(jsonString);
}
});
}
return new ResponseResult(true, "修改状态成功");
}catch(Exception e){
return new ResponseResult(false, "修改状态失败");
}
}

优点:

业务代码解耦,并且能够做到准实时。

缺点:

需要在业务代码中加入发送消息到MQ的代码,数据调用接口耦合。

4.通过Canal实现实时同步

Canal是阿里巴巴开源的一款数据库日志增量解析组件,通过Canal来解析数据库的日志信息,来检测数据库中表结构和数据的变化,从而更新Solr索引库。

使用Canal可以做到业务代码完全解耦,API完全解耦,可以做到准实时。

Canal开源地址:https://github.com/alibaba/canal

重磅福利

关注「 冰河技术 」微信公众号,后台回复 “设计模式” 关键字领取《深入浅出Java 23种设计模式》PDF文档。回复“Java8”关键字领取《Java8新特性教程》PDF文档。回复“限流”关键字获取《亿级流量下的分布式限流解决方案》PDF文档,三本PDF均是由冰河原创并整理的超硬核教程,面试必备!!

好了,今天就聊到这儿吧!别忘了点个赞,给个在看和转发,让更多的人看到,一起学习,一起进步!!

写在最后

如果你觉得冰河写的还不错,请微信搜索并关注「 冰河技术 」微信公众号,跟冰河学习高并发、分布式、微服务、大数据、互联网和云原生技术,「 冰河技术 」微信公众号更新了大量技术专题,每一篇技术文章干货满满!不少读者已经通过阅读「 冰河技术 」微信公众号文章,吊打面试官,成功跳槽到大厂;也有不少读者实现了技术上的飞跃,成为公司的技术骨干!如果你也想像他们一样提升自己的能力,实现技术能力的飞跃,进大厂,升职加薪,那就关注「 冰河技术 」微信公众号吧,每天更新超硬核技术干货,让你对如何提升技术能力不再迷茫!

【Canal】互联网背景下有哪些数据同步需求和解决方案?看完我知道了!!的更多相关文章

  1. 深度剖析HashMap的数据存储实现原理(看完必懂篇)

    深度剖析HashMap的数据存储实现原理(看完必懂篇) 具体的原理分析可以参考一下两篇文章,有透彻的分析! 参考资料: 1. https://www.jianshu.com/p/17177c12f84 ...

  2. linux下实现web数据同步的四种方式(性能比较)

    实现web数据同步的四种方式 ======================================= 1.nfs实现web数据共享2.rsync +inotify实现web数据同步3.rsyn ...

  3. &ldquo;互联网+&rdquo;背景下使用微信公众号增强班主任工作与整合教学资源(泰微课)

    前记:此文是我爱人一项作业.因为我本人对于微信这一块比较熟悉,就参与这项作业中.此文已经参加移动和教育相关活动.作者是我爱人,如有转载请署名作者. 一.什么是"互联网+"? 早在1 ...

  4. 美团DB数据同步到数据仓库的架构与实践

    背景 在数据仓库建模中,未经任何加工处理的原始业务层数据,我们称之为ODS(Operational Data Store)数据.在互联网企业中,常见的ODS数据有业务日志数据(Log)和业务DB数据( ...

  5. DB 数据同步到数据仓库的架构与实践

    背景 在数据仓库建模中,未经任何加工处理的原始业务层数据,我们称之为ODS(Operational Data Store)数据.在互联网企业中,常见的ODS数据有业务日志数据(Log)和业务DB数据( ...

  6. 基于 MySQL Binlog 的 Elasticsearch 数据同步实践 原

    一.背景 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品.订单等数据的多维度检索. 使用 Elasticsearch 存储业务数据可以 ...

  7. SSIS数据同步实践

    SSIS数据同步实践   背景 在已初步验证不同实例下同构表数据同步方案之后,为了实现数据持续同步,需使用SSIS把之前的生成脚本和执行脚本的两个步骤组合在一起部署成包之后,通过JOB定时去执行: 测 ...

  8. 用canal监控binlog并实现mysql定制同步数据的功能

    业务背景 写任何工具都不能脱离实际业务的背景.开始这个项目的时候是因为现有的项目中数据分布太零碎,零零散散的分布在好几个数据库中,没有统一的数据库来收集这些数据.这种情况下想做一个大而全的会员中心系统 ...

  9. 开源数据同步神器——canal

    前言 如今大型的IT系统中,都会使用分布式的方式,同时会有非常多的中间件,如redis.消息队列.大数据存储等,但是实际核心的数据存储依然是存储在数据库,作为使用最广泛的数据库,如何将mysql的数据 ...

  10. 阿里Canal框架(数据同步中间件)初步实践

    最近在工作中需要处理一些大数据量同步的场景,正好运用到了canal这款数据库中间件,因此特意花了点时间来进行该中间件的的学习和总结. 背景介绍 早期,阿里巴巴B2B公司因为存在杭州和美国双机房部署,存 ...

随机推荐

  1. 原生JS:Math对象详解

    Math对象 本文参考MDN做的详细整理,方便大家参考MDN Math 也是一个内置对象, 为数学常量和数学函数提供了属性和方法,而不是一个函数对象. 与其它全局对象不同的是, Math 不是一个构造 ...

  2. 单例模式——Singleton

    模式分类: 从目的来看: 1.创建型(Creational)模式:负责对象创建. 2.结构型(Structural)模式:处理类于对象间的组合. 3.行为型(Behavioral)模式:类与对象交互中 ...

  3. Unity3d - 初学篇 Event Functions 的 继承 机制

    我们知道Start() Update() 等之类的 事件函数 在Unity 主线程中是依次调用的.至于调用的顺序可以查手册. 由此继承机制也会发生一些改变. 测试一: public class MyT ...

  4. IOS UIActivityIndicatorView 等待指示器

    自己做的一个 等待指示器 #import <UIKit/UIKit.h> @interface RockIndicatorView : UIView { } @property(nonat ...

  5. Android ImageView

       如上图,drawable中不只是可以放bitmap  还可以定制不同形状 <?xml version="1.0" encoding="utf-8"? ...

  6. C++ 动态分配类对象

    1.概念 在C++中,类的对象建立分为两种,一种是静态建立,如A a:另一种是动态建立,如A* ptr=new A:这两种方式是有区别的. 静态建立一个类对象,是由编译器为对象在栈空间中分配内存,是通 ...

  7. okHttp基础用法

    获取okHttp..jar.包 1.联网获取jar包 2.本地添加 okHttp的使用 get请求 1.创建okHttpClient对象new OkHttpClient(); 2.创建一个请求对象Re ...

  8. [CF697D]Puzzles 树形dp/期望dp

    Problem Puzzles 题目大意 给一棵树,dfs时随机等概率选择走子树,求期望时间戳. Solution 一个非常简单的树形dp?期望dp.推导出来转移式就非常简单了. 在经过分析以后,我们 ...

  9. linux内核参数注释与优化

    目录 1.linux内核参数注释 2.两种修改内核参数方法 3.内核优化参数生产配置 参数解释由网络上收集整理,常用优化参数对比了网上多个实际应用进行表格化整理,使查看更直观. 学习linux也有不少 ...

  10. 执行shell脚本出错&#39;\r&#39;: command not found

    在linux中执行脚本时出错 $'\r': command not found 错误原因是在脚本中有空行,如果脚本是在Windows下进行编辑之后上传到linux上去执行的话,就会出现这个问题. 因为 ...