专栏首页架构专题希望一个数据同步,包治百病

希望一个数据同步,包治百病

哎!这是一个脏活,而且是个高风险的活。

大多数情况下,应用架构设计不好,引入什么新存储,引入什么DDD,治标不治本,都是扯淡。

但万一灵验呢?这就是数据同步的需求基础。且看下面需求场景。

应用场景

  • 业务数据发展到一定水平,需要将大部分冷热数据从熟悉的DB迁移到其他存储进行复杂查询和分析
  • 分库分表后,某些报表类查询无法工作,需要汇总到单库表进行操作
  • 分库分表有多个维度,需要拷贝多份数据达成冗余
  • 通过伪数据共享(没办法引入MQ、无法共享库表)进行业务改造
  • 慢存储→Cache之间的同步
  • 不停服数据迁移/scheme变更
  • 导数据导数据
  • 归档

很多时候,DataBus提供的仅仅是一个工具集。要完成最终的功能,大多数需要引入其他组件,如MQ、JOB等进行配合。同时,大部分数据同步工具需要有规范的数据库支持。所以,在忙着进行数据同步之前,需要对遗留数据进行一次集中数据治理。

一般数据同步,可以应用驱动双写:应用层同时向数据库或者多个存储写数据。因为代码在自己手中,这种方式在直觉上是简单可控的。但它引入的一致性问题将会是非常大的减分,因为没有复杂的协调协议(比如两阶段提交协议或者paxos算法),当出现问题时,很难保证多个存储处于相同的锁定状态。两个系统需要精确完成同样的写操作,并以同样的顺序完成序列化。如果写操作是有条件的或是有部分更新的语义,那么事情就会变得更麻烦。

基于数据库日志:将数据库作为唯一真实数据来源,并将变更从事务或提交日志中提取出来。这可以解决一致性问题,但是很难实现,MySQL这样的数据库有私有的交易日志格式和复制冗余解决方案,难以保证版本升级之后的可用性。由于要解决的是处理应用代码发起的数据变更,然后写入到另一个数据库中,冗余系统就得是用户层面的,而且要与来源无关。对于快速变化的技术公司,这种与数据来源的独立性非常重要,可以避免应用栈的技术锁定,或是绑死在二进制格式上。


数据同步方式

目前的数据同步解决方案,大体有以下三种:

  • 针对特定AB方数据同步进行的私有定制,如trigger
  • binlogwal日志级别的精确数据同步
  • 基于lastUpdateTime的查询结果集数据同步

针对于数据同步方式,有增量和全量同步两种:

  • 全量 一次性导出倒入完毕
  • 增量 数据随到随倒,小溪汇大海~

数据同步考虑的因素

基本特性

  • 同机房同步实时性(RTT)
  • 增量同步/全量同步策略
  • 事务支持粒度
  • 峰值应对策略 (消峰降级、延迟写入、扩容策略)

多机房(X一般公司不到这水平)

  • 数据库异地灾备
  • 多机房同步延迟
  • 机房切换(单元化切流/全站切流)
  • 数据对其方案
  • 双活

AB端数量和质量

  • 支持常见的SQL,如MySQLPostgres
  • 其他AB端支持,如:RedisMongoES
  • 数据同步的
  • 扩展方式和社区活跃度

高吞吐、低延迟

  • 并行化(并行读、并行写)
  • 顺序场景串行化

高可用

  • 监控、故障恢复
  • A(源端)端故障感知
  • B (目的端)端故障感知
  • 主从切换(或为对等节点)
  • 支持服务演练
  • 动态配置、故障重启

数据完整性

  • 较高的SLA高可用服务水准
  • 故障数据有回放机制和降级策略
  • A/B端数据自动校验功能(一致性验证)

其他

  • 数据过滤机制
  • 学习、部署成本
  • 硬件成本

实现

我们从几个典型实现、来看一下数据同步的复杂性。阿里在数据同步上可谓吓足了功夫,如:datax(ETL工具)、canal、otter、drc、dts、drds愚公精卫等。其中,使用最广泛的就是canal和datax。 另外,还有一些其他较活跃的工具,如sqoop、Maxwell 、debezium等

基于数据库的组件,一般都是伪装成一个DB的从库接收一份数据,剩下的都是框架内玩的事情了。如MySQL一般使用基于row的binlogpostgres基于wal日志进行复制。以MySQL为例、如果通过Binlog方式,将数据同步到ESHbase等其他盲区,就需要手写大量代码,包括组装数据、批量、顺序、HA等等很多场景都需要考虑。

我们限定一下一个最简单的使用场景,然后追踪在其上需要哪些工作量,又有哪些优缺点。场景如下: 将MySQL数据库的数据,同步一份数据到Postgres

Canal

最新的Canal已经支持MQ

如上图,除了需要搭建canal服务,将其伪装成一个slave,然后通过zookeeper做HA。我们还需要编码一个Canal Client服务,用来读取和解析数据。更多的情况,可能要引进一个MQ组件,用来缓解Canal的压力并承担一些扩展性功能。

一些限制

  • Canal源端只支持MySQL,并且只支持基于ROW模式的同步复制
  • 同步的表必须要有主键,无主键表update会是一个全表扫描 ,如果出现重复记录的话,同步会导致数据错乱
  • 支持部分ddl同步,ddl语句不支持幂等性操作,所以出现重复同步时,会导致同步挂起,可通过配置高级参数:跳过ddl异常,来解决这个问题(支持create table / drop table / alter table / truncate table / rename table / create index / drop index,其他类型的暂不支持,比如grant,create user,trigger等等)
  • 不支持带外键的记录同步
  • 数据库慎用或者禁用trigger
  • Canal是吃内存的,注意内存相关的调优
  • 堆积能力有限,这也是外部MQ的优势

maxwell

maxwell干脆就将这个过程更近了一步:直接将binlog解析成json存储在kafka中。用户使用的时候,直接订阅kafkatopic即可。

数据可能长这样:

mysql> update test.maxwell set daemon = 'firebus!  firebus!' where id = 1;
  maxwell: {
    "database": "test",
    "table": "maxwell",
    "type": "update",
    "ts": 1449786341,
    "xid": 940786,
    "commit": true,
    "data": {"id":1, "daemon": "Firebus!  Firebus!"},
    "old":  {"daemon": "Stanislaw Lem"}
  }

maxwell为用户提供了默认的解决方式,需要额外引入kafka组件,这也是大部分数据分发共享的思路。由其github star数看来,要小canal一个数量级。在此基础上,有类似bireme更专某个场景的产品,不过都偏小众。

debezium

我觉得有必要提一下debezium。随着postgres的性能和特性越来越强,国内采用PG的公司逐渐增多。像这种场景,canal就无能为力了,debezium同时支持源端MySQLPostgresMongoDB,值得一试。同maxwell类似,同样需要kafka的支持。 缺点也是显而易见的,文档的质量不高,实践资料太少。

DataBus

Linkedin开源作品。Databus支持多种数据来源的变更抓取,包括OracleMySQL。是一个低延迟、可靠的、支持事务的、保持一致性的数据变更抓取系统。 大同小异,databus在MySQL的处理方式上,也是通过解析binlog的方式进行数据抓取。使用MySQL Binlog解析库,我们也可以构造一个自己的数据同步中间件。DataBus做了更多的缓冲区relay、事件优化和回溯处理。在整个技术架构中,可以充当数据总线的作用。

DataX

Databus类似,DataX是一个在异构的数据库/文件系统之间高速交换数据的工具,实现了在任意的数据处理系统之间的数据交换,更像是一个ETL工具。 DataX支持的AB端数据源非常丰富,但因为它使用的定时抓取的方式,其延迟相比较Canal等基于日志的方式,是比较大的。同时,DataX对数据的要求较高,比如你的数据库如果没有最后更新时间之类的字段,从源端读取变更数据将有一定的困难。

总结

整体而言,CanalDataXDataBus的使用人数多,社区活跃,框架也比较成熟。在满足应用场景的前提下,优先选择,它们都有自己的HA方案,代价适中。

CanalDataBus源端支持类型有限,但延迟低,需要手写Client来处理数据。大多数情况下需要加入MQ进行配合。

DataX支持丰富,使用简单,但延迟较大(依赖获取频率),只需要手写规则文件,对复杂同步自定义性不强。

本文分享自微信公众号 - 小姐姐味道(xjjdog),作者:小姐姐养的狗

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-04-30

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 你能搞懂connectTimeout和socketTimeout的区别么?

    有时候,由于业务的复杂性,在JVM中拼装一些数据,会造成资源的极大浪费。举个例子,从MySQL中查询出一个List,然后在代码里循环查询数据库,进行一些字段的填...

    xjjdog
  • 数据库中间件详解(精品长文)

    互联网当下的数据库拆分过程基本遵循的顺序是:垂直拆分、读写分离、分库分表(水平拆分)。每个拆分过程都能解决业务上的一些问题,但同时也面临了一些挑战。

    xjjdog
  • 记一次操蛋的方案降级(云上冷热分离的坎坷之路)

    系统的数据,就是公司的生命。哪怕是狗屎,我们也要将它冷冻起来冰封以备后用。垃圾的产品设计就比较让人费解,会时不时从冰柜中将屎取出,想要品尝其中残留的味道。

    xjjdog
  • Qt Model/View教程——只读Table

    一直想学习Qt Model/View,最终还是看的官方教程,现在将官方教程重新在梳理下。

    用户5908113
  • 美国运通印度分公司数据库曝光,致70万人信息泄露

    10月23日,Mongo数据库曝出漏洞,通过这个漏洞,任何人都能对数据库进行查看、编辑操作。

    FB客服
  • 58同城数据库架构设计思路

    (1)可用性设计 解决思路:复制+冗余 副作用:复制+冗余一定会引发一致性问题 保证“读”高可用的方法:复制从库,冗余数据,如下图 ? 带来的问题:主从不一致 ...

    用户1263954
  • 肖风:未来三到五年内,一个去中心化的分布式AI平台或将出现

    在新智元AI WORLD 2018世界人工智能峰会上,中国万向控股有限公司副董事长兼执行董事肖风分享了他对AI、数据隐私保护和区块链的独到看法。 肖风认为,随...

    辉哥
  • 深度学习的核心工作流程之一:如何训练数据!

    -免费加入AI技术专家社群>> 今天我们将讨论深度学习中最核心的问题之一:训练数据。深度学习已经在现实世界得到了广泛运用,例如:无人驾驶汽车,收据识别,道路缺陷...

    企鹅号小编
  • 大数据风控 PK 传统信用评级?谁赢? | 数据猿专访耀盛中国集团总裁原旭霖

    数据猿导读 耀盛中国集团总裁原旭霖接受数据猿采访时提到,中小企业常常面临产业升级、店面扩张、上下游资金周转等问题,对金融服务的需求相对大企业而言更为迫切。作为中...

    数据猿
  • 苹果在华建第二个iCloud数据中心;腾讯医疗AI开启国际化 | DT数读

    过去一周,国际、国内的大数据相关公司都有哪些值得关注的新闻?数据行业都有哪些新观点和新鲜事?DT君为你盘点解读。

    DT数据侠

扫码关注云+社区

领取腾讯云代金券