文章目录
- 数据来源
- 数据同步
- 直连同步
- 数据文件同步
- 数据库日志解析同步
- 数据仓库同步方式
- 批量数据同步
- 实时数据同步
- 数据同步遇到的问题和解决办法
- 分库分表的处理
- 增量与全量同步的合并
- 数据漂移的处理
数据来源
关系型数据库的结构化数据:MySQL、Oracle、DB2、SQL Server
非关系型数据库的非结构化数据:OceanBase、HBase、MongoDB、来源于文件系统的结构化或非结构化数据(通常以文件形式存储)
数据同步
直连同步
通过定义好的规范接口API和**基于动态链接库的方式(ODBC/JDBC等)**连接业务库。直连同步示意图如下图所示:
优点:配置简单,实现容易。适合操作性业务系统的数据同步。
缺点:对源系统的性能影响较大,当数据量较大时,不适合从业务系统到数据仓库系统的同步。
数据文件同步
通过设定好的文件编码、大小、格式等,直接从源系统生成数据的文本文件,由文件服务器传输到目标系统并加载到目标数据库系统中。数据文件同步示意图如下所示:
应用场景:当数据源包含多个异构的数据库系统(如MySQL、Oracle、SQL Server等)
优点:简单实用。互联网的日志类数据通常以文本形式存储,适合使用数据文件同步方式。
数据库日志解析同步
数据文件被传输到目标系统后,可通过数据加载模块完成数据的导入,从而实现数据从源系统到目标系统的同步。
优点:
1.日志文件信息足够丰富,数据格式稳定,通过解析日志文件满足增量数据同步的需求。
2.通过网络协议,确保数据文件的正确接收,提供网络传输冗余,保证数据的完整性。
3.实现了实时与准实时同步的能力,延迟控制在毫秒级别。
缺点:
1.当数据更新量超出系统处理峰值,会导致数据延迟。
2.投入较大,需要在源数据库和目标数据库之前部署一个实时抽取数据系统。
3.数据漂移和遗漏。
数据仓库同步方式
数据同步特点:数据来源的多样性,数据量大。
批量数据同步
要实现各类数据库系统和数据仓库系统之间的批量双向数据同步,就需要先将数据转换为中间状态,统一数据格式。由于这类数据都是结构化的,且均支持标准的 SQL 语言查询,所以所有的数据类型都可以转换为字符串类型。因此,我们可以通过将各类源数据库系统的数据类型统转换为字符串类型的方式,实现数据格式的统一。
架构设计图如下:
Job:数据同步作业。
Splitter:作业切分模块,将大任务分解成多个可以并行的小任务
Sub_Job:数据同步作业切分后的小任务。
Reader:数据读入模块,负责运行切分后的小任务,将数据从源系统装载到异构数据转换系统。
Channel:Reader和Writer通过Channel交换数据。
Writer:数据写出模块,负责将数据导入目标数据系统。
实时数据同步
有一些数据应用,需要对业务系统产生的交易数据进行实时处理,实现秒级的数据刷新。具体来说,就是建立一个日志数据交换中心,从每台服务器源源不断地读取日志数据,将增量数据以数据流的方式不断同步到日志交换中心。实时数据传输平台具有高性能、实时性、顺序性、高可靠性、高可用性、可扩展性等特点。
优点:
1.读写分离,消费不影响发送。
2.支持订阅历史数据,随意设置订阅位置,方便用户回补数据。
3.强大的属性过滤功能。
数据同步遇到的问题和解决办法
分库分表的处理
问题:
目前主流数据库系统都提供了分布式分库分表方案来提升系统的扩展能力和高并发大数据量的处理能力。但是对于数据同步来说,分库分表的设计加大了同步处理的复杂度。
解决办法:
分布式数据库的访问引擎通过建立中间状态的逻辑表来整合统一分库分表的访问。
- 在持久框架之下、JDBC驱动之上的中间件
- 与JDBC规范保持一致,解决了分库分表的规则引擎问题
- 实现SQL解析、规则极端、表名替换、选择执行单元并合并结果集的功能
- 解决了数据库表的读写分离、高性能主备切换的问题
增量与全量同步的合并
问题:
数据量比较大时,按周期全量同步的方式会影响处理效率。可以每次只同步新变更的增量数据,然后与上一个同步周期获得的全量数据合并,从而获得最新版本的全量数据。
解决方案:
传统的数据整合方案,合并技术以merge方法为主(update+insert),现在大数据平台基本不支持update,比较推荐全外连接(full outer join)+ 数据全量覆盖重新加载(insert overwrite),如日调度。当天的增量数据和前一天的全量数据做全外连接,重新加载最新全量数据。可以采用分区方式,每天保存一个最新的全量版本。
提出了基于负载均衡思想的数据同步方案:
- 通过目标数据库的元数据 估算 同步任务的总线程数
- 系统预先定义的期望同步速度 估算首轮同步的线程数
- 业务优先级决定同步线程的优先级。
数据漂移的处理
数据漂移通常是指ODS表的同一个业务日期数据中包含前一天或后一天凌晨附件的数据或者丢失当天的变更数据。
问题:
由于ODS需要承接面向历史的细节数据查询需求,这就需要物理落地到数据仓库的ODS表按时间段来切分进行分区存储,通常的做法是按某些时间戳字段来切分,而实际上往往由于时间戳字段的准确性问题导致发生数据漂移。
时间戳字段分为四类:
- 数据库表中用来标识数据记录更新时间的时间戳字段(modified_time)
- 数据库日志中用来标识数据记录更新时间的时间戳字段(log_time)
- 数据库表中用来记录具体业务发生时间的时间戳字段(proc_time)
- 标识数据记录被抽取到时间的时间戳字段(extract_time)
理论上这几个时间应该是一致的,但是在实际生产中,往往会出现差异,时间戳字段不同的原因如下:
- 数据抽取需要时间,extract_time往往会晚于前三个时间
- 未及时更新modified_time
- 由于网络或系统压力,log_time或modified_time会晚于proc_time
数据漂移的几种场景:
- 根据extract_time获取数据。这种情况数据漂移的问题最明显。
- 根据modified_time限制,在实际情况中最常见,往往会发生不更新modified_time而导致数据遗漏,或者凌晨时间产生的数据记录漂移到后一天。
- 根据log_time限制。由于网络或者系统压力,导致凌晨时间产生的数据记录漂移到后一天。
- 根据proc_time限制。仅根据proc_time限制,所获取的ODS表只是包含一个业务过程所产生的记录,会遗漏很多其他过程的变化记录,违背了ODS和业务系统保持一致的设计原则。
解决办法:
(1)多获取后一天的数据
在ODS每个时间分区中向前、向后多冗余一些数据,保障数据只会多不会少。
(2)通过多个时间戳字段限制来获取相对准确的数据
- 首先格局log_time分别冗余前一天最后15分钟的数据和后一天凌晨开始15负责的数据,并用modified_time过滤非当天数据,确保数据不会因为系统问题而遗漏。
- 然后根据log_time获取后一天15分钟的数据,针对此数据,按照主键根据log_time做升序排列去重。
- 最后将前两步的结果数据做全外连接,通过限制业务时间proc_time来获取我们所需要的数据。