zoukankan      html  css  js  c++  java
  • 深入数据库同步技术(3)-da-syncer介绍

    在上一部分《深入数据库同步技术(2)- 时序性保障”》中,我们为大家介绍了数据同步时序性的概念和重要意义,以及在da-syncer中如何利用Oracle闪回版本查询实现时序性。

    在这一部分,我们将为大家介绍我们自研的同步工具da-syncer。

    一、da-syncer实现了哪些功能

    da-syncer是我们数据聚合项目中的一个数据同步工具,可以通过简单地点击鼠标完成表数据同步的工作,它包含了两个代码工程:

    mconsole:提供管理控制台,前后端分离,是一个常规的Spring Boot工程

    pyworker:Worker进程,核心同步引擎,使用Python完成

    首先抱歉在这里澄清一下,在本系列文章的“深入数据库同步技术(1)- 基础篇”中,我们基于Java/JDBC视角做了很多用例说明,因为毕竟Java是主流编程语言,用它来做说明大家普遍更能接受一些。但实际上我们的核心同步引擎是Python做的。

    至于为什么选择Python,主要原因是Java的笨重。Python是敏捷型语言,更轻量级,在短时间内能更快速地交付项目,且大大缩减我们的代码量(注:本人无意挑起语言层面孰优孰劣的无谓争论)。

    比如像pyworker工程里面大量存在的Python Style的语句(见图1):

    图1:简洁的Python代码

    写起来很简洁,如果换成Java实现的话,可能每一句都会拆解成十几条甚至几十条子句。目前pyworker的所有代码加起来还不到100K。

    另外,Python有众所周知的GIL锁的问题,pyworker没有使用多进程而是使用多线程,主要是因为数据同步本身是一个典型的网络I/O密集型而非CPU密集型的业务场景,所以其实影响还是比较小的。

    简单总结一下,目前da-syncer支持的功能点包括:

    (1)实现了Oracle到Oracle/MySQL,或者MySQL到Oracle/MySQL的全量和增量同步

    (2)支持数字,字符,日期,二进制等常用字段类型

    (3)自动化创建目的表后完成全量同步,对于有单一主键的大表,还支持大表分段同步

    (4)可以在运行时自由切换以源表或目的表的表结构作为模板,完成同步

    (5)可选择last_modified_date、ora_rowscn、greatest函数索引等多种增量同步策略

    (6)支持数据比对,以解决源端有物理删除记录的情况

    (7)提供管理控制台界面,让用户可以方便地注册数据源,管理同步任务,获悉同步内部详细信息,对同步参数进行管理等

    (8)当同步任务失败或遇到异常时,提供告警功能,通过邮件通知管理员

    (9)当同步出现错误时,将同步错误记录保存到单独的一张表,并在错误修复后,自动重试。比如,源端增加了字段长度,目的端感知不到,在源端插入一个长数据后,目的端不能插入,这种错误会被记录下来,在人工干预加长目的端字段长度后,同步恢复正常

    (10)在部署环境中,经常会遇到网络拥塞、抖动,以及各种中间件不稳定的情况,使用类似指数退避算法,重试直至成功为止

    (11)支持websocket信息推送,可以在管理控制台看到实时同步日志流

    (12)对于Oracle源,支持去重机制。如果只增量同步不选择全局同步机制,因为ora_rowscn默认基于Oracle数据块,这样大量无效数据被同步,可以开启去重,将真正发生改变的记录同步到目的端

    (13)对于Oracle同步源,得益于闪回版本查询,我们实现了:

    ????同步时序性

    ????通过全局同步机制,只检索发生实际改变的记录版本,相比单纯使用ora_rowscn机制,大大减少检索、网络传输量(减少到万分之一),缩短同步时间(几个小时到几分钟)

    ????自动检测Delete操作,并在目的表同步删除

    ????可以开启每个分段内的版本记录功能,写入单独的表,消费该表可实现DataBus数据总线功能(如数据发布、数据订阅、数据通知)

    (14)支持同步拦截、预处理机制

    可以在运行时登记Python脚本,在数据记录被插入或更新到目的表之前,进行一些预处理,比如修改记录某个/些字段的值、或合并两个字段值到另外一个字段等。

    (15)支持数据脱敏

    可以在运行时登记Python脚本,在同步时完成数据脱敏的工作,如将身份证或手机号等敏感信息替换成*等。

    总起来说,我们不是每样功能都做,需要提供什么功能完全是业务需求驱动的。

    未来可能支持的功能点包括:

    (1)目的表Sharding

    针对源表是巨型表的情况,可以提供分区策略,自动进行目的表的Sharding分区,这样可以将源表分散到多张目的表中,提高上层查询、聚合效率。

    备注:一些大表已经到了4亿级别的量,靠使用InnoDB存储引擎的单表加上索引很难再满足应用层的查询性能要求,必须要考虑分表了。

    (2)支持其他NoSQL作为同步源或目的端

    比如支持从MongoDB中读取数据,保存到数据库;或从数据库读取数据,保存到MongoDB。

    备注:一些业务方系统由于自身业务需要,开始尝试使用Schema Free的数据库,比如MongoDB,对于da-syncer也需要同步跟上。

    (3)弃用Otter/Canal框架

    使用Otter/Canal框架的原因是它帮助我们解决了MySQL源的同步时序性问题,同时不用在源表强制添加last_modified_date字段,但这样会造成我们维护两套技术体系,一个是基于Java的Otter/Canal(说实话Otter这个东西并不好用,它把全量和增量同步硬生生地割裂开来,配置复杂、选项多,但很多都用不了,也用不上。每次麻烦DBA帮忙配置线上的Otter同步任务时,都像要杀了他似的),一个是基于Python的da-syncer。

    未来,我们在pyworker中可能会集成pymysqlreplication模块,由pyworker自身解析binlog文件,以实现MySQL源的时序性。

    这样一来,无论是Oracle源还是MySQL源,时序性就可以在pyworker中统一实现了。

    二、da-syncer 管理控制台展示

    下面,我们从da-syncer管理控制台mconsole中挑选了两个界面,给大家介绍一下:

    (1)添加新同步任务

    图1是添加一个新的同步任务时的界面。

    1:添加一个新同步任务

    a) 搜索并选择一个源库

    b) 选定一个源库后,库里面的所有表名、表大致记录数、表上的comment备注就会显示在源表下拉框中,搜索并选定一个源表

    c) 选择同步策略

    d) 选择目的库

    e) 输入目的表表名,点击“生成建表SQL”,可以干预生成的建表SQL,如添加额外索引

    f) created_at和updated_at字段是自动生成并添加在目的表的两个元字段,作用是为了方便上层应用做增量聚合查询

    g) 确定各种参数和开关,点击确定按钮即可开始全量同步

    (2)查看实时同步日志

    通过websocket将pyworker产生的实时日志输出推送到客户浏览器端,方便了解同步任务内部状态、所处阶段、相应步骤及其耗时等(见图2)。

    图2:websocket实时推送

    a) 可以输入关键字在推送的信息中进行简单搜索(结果highlight显示)

    b) 可以复制信息到其他地方,比如记事本

    c) 可以暂停信息滚动

    d) 服务器端实现信息暂存(只保留最近的2000条)

    关于da-syncer就到这里,我们的计划是未来将da-syncer开源,以方便那些跟我们在数据同步领域有相同痛点的同行们。

    “深入数据库同步技术”系列3个部分至此全部介绍完毕,限于篇幅关系且本人能力有限,很多细节讲的不是很到位,如果有什么问题,欢迎大家沟通交流!

  • 相关阅读:
    HTTP报文详解
    常用的HTTP协议
    URL详解
    log4net工作原理(2)
    《Linux内核设计与实现》读书笔记(十七)- 设备与模块
    《Linux内核设计与实现》读书笔记(十六)- 页高速缓存和页回写
    《Linux内核设计与实现》读书笔记(十五)- 进程地址空间(kernel 2.6.32.60)
    《Linux内核设计与实现》读书笔记(十四)- 块I/O层
    随手记代码
    记录一下WPF中自寄宿asp.net服务添加urlacl的问题
  • 原文地址:https://www.cnblogs.com/syncnavigator/p/10189570.html
Copyright © 2011-2022 走看看