前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一文带你玩转数据同步方案

一文带你玩转数据同步方案

作者头像
lyb-geek
发布2024-04-18 12:39:56
2000
发布2024-04-18 12:39:56
举报
文章被收录于专栏:Linyb极客之路Linyb极客之路

一、数据同步场景有哪些?

1.1 数据迁移场景:

以Mysql数据库迁移为例,数据库常用迁移方案有停机迁移和平滑迁移。

停机迁移包括停服迁移与非停服迁移,停服迁移是选择某一时间点流量最少时停止所有服务,并在最短时间内完成数据迁移,此时需要注意停服时间;非停服迁移,即停止所有写数据服务,查询服务并不停止,同样要注意停服时间,防止对生产环境有较大影响。停机迁移完成后,还需要进行数据核对,通常首先要校验迁移前后数据量是否一致,其次还可对迁移前后数据逐条进行校验,还可进行流量回放,保证迁移前后业务表现完全一致。

平滑迁移又分为双写和CDC(数据变更抓取)。双写:所有的写操作必须同时写入旧表和新表,可直接在应用代码中实现,但会引入数据一致性问题,也就是说,双写操作必须在一个分布式事务中完成。CDC:通过数据源的事务日志log抓取数据源变更来进行数据同步。

1.2 数据同步场景

在我们实际开发过程中,会使用不止一种数据源,关系型数据库Mysql、OceanBase,缓存会使用Redis、MongoDB,搜索服务会使用ES、ClickHouse等。此时,数据同步问题就迫切需要解决。如何将实时变化的数据库中的数据同步到Redis/MongoBD或ES/ClickHouse中呢?

二、数据同步有哪些方案?

2.1 应用代码中同步

在增加、修改、删除之后,执行操作ES的逻辑代码。优点:实施比较简单,简单服务可直接使用。缺点:代码耦合度高,且与业务代码同步执行,效率变低。

代码语言:javascript
复制
public void updateStatus(String status, String goodsId){
    try{
        //更新mysql
        goodsService.updateStatus(status, goodsId);
        //数据写入es
        esClient.updateStatus(status, goodsId);
        //数据写入redis
        redisTemplate.save(status, goodsId);
    }catch(Exception e){
        throw new RuntimeException();
    }
}

2.2 定时任务同步

在数据库中执行完增、删、改操作后,通过定时任务定时将数据库的数据同步到Redis、ES中。目前常用的定时任务调度方案有:Quartz,XXLJOB、ElasticJob、SchedulerX或各公司自研的定时任务调度平台。

优点:同步Redis、ES的操作与业务代码完全解耦。缺点:数据的实时性较低。

执行定时任务时,可在关系型数据库中设置一个更新记录的时间戳字段,这样每次定时任务执行时只需要查询这段时间内变动的数据来同步就可以了,从而不需要再次查询数据表中的所有数据,避免了每次执行任务都会进行全表扫描。

2.3 通过MQ实现同步

在数据库中执行完增、删、改操作后,向MQ中发送一条消息,此时,同步程序作为MQ中的消费者,从消息队列中获取消息,然后执行同步Redis\ES索引库的逻辑。下图展示通过MQ实现数据同步的过程,我们可使用如下代码实现这个过程。

优点:业务代码解耦,并且能够做到准实时。目前很多公司数据同步都是采用这种方式。缺点:需要在业务代码中加入发送消息到MQ的代码,数据调用接口耦合。

代码语言:javascript
复制
public void updateStatus(String status, String goodsId){
    try{
        //更新mysql
        goodsService.updateStatus(ids, status);
        //发送kafka消息,消费者消费消息进行数据同步
        kafkaTemplate.send();
    }catch(Exception e){
        throw new RuntimeException();
    }
}

2.4 通过CDC实现实时同步

通过CDC来解析数据库的日志信息,来检测数据库中表结构和数据的变化,从而更新Redis/ES。优点:使用CDC可以做到业务代码完全解耦,API完全解耦,可以做到准实时。缺点:构建CDC系统较为复杂。

CDC(change data capture,数据变更抓取):通过数据源的事务日志抓取数据源变更,这能解决一致性问题(只要下游能保证变更应用到新库上)。各种数据源的变更抓取没有统一的协议,如MySQL 用 Binlog,PostgreSQL 用 Logical decoding 机制,MongoDB 则用 oplog。

Canal,纯Java开发,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费。目前canal只能支持row模式的增量订阅(statement只有sql,没有数据,所以无法获取原始的变更日志)。

基于日志增量订阅&消费支持的业务:数据库实时备份;多级索引 (卖家和买家各自分库索引);业务cache刷新;价格变化等重要业务消息。

三、数据接入策略

3.1 数据库直连同步

直连同步是指通过定义好的规范接口API和基于动态链接库的方式直接连接业务库,如 ODBC/JDBC 等规定了统一规范的标准接口。

3.2 数据文件同步

数据文件同步通过约定好的文件编码、大小、格式等,直接从源系统生成数据的文本文件,由专门的文件服务器,如FTP 服务器传输到目标系统后,加载到目标数据库系统中。

为了保证数据文件同步的完整性和安全性以及传输效率,可在传输数据文件的同时一并传输一个校验文件供目标系统校验,同时可对数据文件进行加密和压缩操作。(证券金融公司有交易日概念,用的比较多)。

3.3 数据库日志解析同步

大多数主流数据库都已经实现了使用日志文件进行系统恢复,因为日志文件信息足够丰富,而且数据格式也很稳定,完全可以通过解析日志文件获取发生变更的数据,从而满足增量数据同步的需求,比如mysql,一般是通过解析binlog日志方式来获取增量的数据更新,并通过消息订阅模式来实现数据的实时同步。

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-04-17,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 Linyb极客之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com