">必赢国际437437.com_必赢国际437在线游戏_437必赢国际网站

您现在的位置:必赢国际437437.com_必赢国际437在线游戏_437必赢国际网站 > 试题库 > 历年真题 >  > 正文

但为了在v2版本中实现时序性

2018-09-25 02:20http://www.baidu.com四川成人高考网

  中,我们为大家介绍了数据库同步的一些基本概念和在应用层做数据同步时普遍存在的痛点问题,这些问题大家平时工作或多或少也会遇到,读起来有些乏善可陈。

  所以,在这一部分,我们将为大家介绍数据同步中的另一个比较新鲜的话题:时序性保障。

  什么是时序性?时序性就是事件发生的先后顺序。对于数据库来讲,事件的最小单元就是事务(即Transaction,每提交一个事务就产生一个事件,无论事务涉及的数据量有多大或者参与的表有多少)。

  作为一个正常的OLTP数据库,可能每时每刻在每张表上都在发生事务性操作。类似于事件溯源(Event Sourcing)机制,我们希望将源库上的事务按照发生的时间先后顺序(也就是事务的提交顺序),依次应用在目的库上,这样就会保证源表和目的表数据状态的一致性和事务的不可撕裂性。

  所以,数据库的时序性有两个显著特征:一是以事务为单位,二是保持事务发生的先后顺序。

  普通情况下我们在应用层做数据同步,一个线程负责一张表的同步和数据处理,各个线程间互不干涉,也没有任何联系,这样会产生一些问题。

  假设有一个用户表和一个用户投资记录表,很显然用户投资记录表中有一个外键字段指向用户表的用户ID。如果单纯使用每张表/每线程的模式,很可能用户投资记录已经同步到目的表了,但是用户表的记录还没有同步过去,在目的库形成“子先于父存在”的情况。这不但让目的表不能像源表那样强制添加主外键约束,还会对目的端应用层的增量查询和数据汇总造成困扰。如果我们在同步过程中保持了时序性,则不会有此类问题发生。

  再举一个例子,出于修正数据的需要,假设源库在一个事务中对多张表做了更新操作,然后提交事务。作为同步工具,如果不以事务为单位进行同步,你会发现目的库上的数据是混乱的:某些表的记录可能已经更新成了最新值,某些表可能还是保留原来的值,这是因为你的同步进程把事务撕裂了。源库在历史上的任何时刻从来没有出现过像现在目的库这样的数据形态,换句话说,你破坏了源库数据的一致性。同步本身可以有延迟,但是,数据不能有不一致。假设你在源库的事务中把钱转给了张三,在目的库的某个时刻进行汇总查询,结果发现你的钱被扣除了,但是张三的账户并没有增加,这就比较尴尬了。必赢国际437437.com

  在上一部分“基础篇”中,我们也提到了数据总线(Data Bus)的概念,进而可以引申出数据发布、数据订阅、数据通知。在数据总线中流转的事件必须是按发生顺序排列好的,然后再依次发送给各方系统。所以时序性也是构建数据总线的前提条件。

  总之,时序性是衡量一个同步系统好坏的重要指标,接下来我们看看如何实施它。

  如果同步源是MySQL,我们使用了阿里开源的Otter/Canal框架,其基本原理是伪装成MySQL的Slave数据库。

  可以使用免费的Logminer,对在线日志或归档日志进行挖掘,从而解析出Redo SQL在目的库进行重放(Replay),还可以使用商业版的Oracle GoldenGate,这两种方式都是基于日志挖掘方式,其缺点是需要在数据库上进行诸多配置,对数据库不透明。

  可以使用LinkedIn的Databus,它基于trigger + ora_rowscn机制,在源表上添加trigger,需要部署多个存储过程包,侵入数据库更深。同时因为基于触发器,对源表写入有性能影响,也增加了发生死锁的可能性,部署这套东西会造成DBA的反感。

  比如阿里的yugong(愚公)开源项目,需要在每张源表上开启物化视图日志,并在目的库中创建物化视图,刷新物化视图读取源表增量更新。物化视图可以看做是变相的trigger,也不是特别好。

  (2)在纯应用层搞定(数据库只要开放select权限就行),对数据库透明,无需在数据库上动刀增加额外配置,更不需要DBA参与。