数据仓库系列(5):数据同步

一、技术路线图

二、数据库直连同步

由于对于数据仓库系统而言,业务系统的数据多种多样,但由于技术惯性等原因,现有业务数据大多存储在Mysql或者Postgresql中,并且以结构化的方式进行存储。通过定义好的规范接口,以API的形式同步,是常见的数据库直连同步,调用数据库标准方法即可实现。这种方式配置简单,实现非常容易,但是对于业务系统的影响较大。通常情况下,业务系统会采用主备的策略来实现架构,因而从备用数据库中抽取数据,可以避免对于线上业务系统产生影响。由于备用数据库也存在数据同步的周期,因而采用这种方式需要考虑在备用数据库比较空闲的时候进行同步。

三、数据库文件同步

由于数据库直接同步,不论怎么处理,都会对业务系统产生一定的影响,因而很多情况下我们采用数据文件直接同步到方式来进行优化,通过约定好的文件编码、大小、格式等,直接从原系统生成数据的文本文件,由专门的插件同步到处理服务器,能够提高文件传输的效率。这种方式会遇到两个问题,一个是网络波动可能会丢包,另一个是源文件比较大需要进行压缩传输。因而通常在传输数据文件的同时,会上传一个校验文件,检测数据量、文件大小等信息,以保证数据同步的准确性。

四、数据库日志解析同步

随着技术的不断进步,大多数主流数据库都可以通过日志文件的方式进行系统的恢复,并且由于日志文件的信息记录非常完整,格式解析也很稳定,因而完全可以通过解析数据库日志文件来获得发生变更的数据,再更新离线系统以最大提升效率。

以阿里Canal组件为例,早期阿里巴巴因为杭州和美国双机房部署,存在跨机房同步的业务需求,从2010年开始,业务逐步尝试数据库日志解析获取增量变更进行同步,由此衍生出了大量的数据库增量订阅和消费业务。MySQL主备复制原理为:Mysql Master将数据变更写入二进制binary log日志,Mysql Slave将Master的binary log拷贝到它的中继relay log日志,Mysql Slave重放relay log中事件,将数据变更反映它自己的数据。在此基础上,Canal工作原理为:Canal模拟Mysql Slave的交互协议,伪装自己为Mysql Slave,向Mysql Master发送dump协议,Mysql Master收到dump请求,开始推送binary log给Canal,Canal解析binary log对象,获得数据变更信息。

由于数据库日志解析实现了准实时同步的能力,对业务系统的影响也很小,因而广泛的应用在了从业务系统到数据仓库的增量数据同步应用之中。值得注意的是,由于数据仓库对于更新操作支持比较差,通常会采用先删除、再插入的方式来模拟更新操作。

有一种比较常见的情况,是由于源系统操作比较频繁,存在同一条数据多次更新的情况,需要根据数据库id,将同一条数据的变更情况进行倒叙排序,以获得最后状态变化的情况。其实有时候业务数据并不是真正意义上的删除,而是业务系统根据需要做逻辑上的删除,但数据会继续保留,这时候具体的业务处理逻辑,要看产品统计需求再做决定。

该方式会存在一定的问题,主要是:数据延迟、处理数据量较大及数据漂移,因而中间系统的建设也需要进行一定的编码开发,以消除数据不一致的情况。

五、分库分表处理

随着业务的不断增长,业务系统的数据也在不断增加,设计分库分表的方式变成了几乎必然的数据库设计方案。在同步分库分表数据问题时,需要引入中间插件,通过建立中间状态的形式,来统一分库分表的访问。

阿里巴巴同样有一个TDDL的插件来实现这种中间状态,不得不说阿里的一些开源插件还是很不错的。类似的插件还包括Amoeba、Cobar、MyCAT等,具体的技术选择还需要看自身的业务需求。

六、批量数据同步

批量数据同步有两个特点,一个是数据来源多种多样,网页Web日志和客户端日志只是统称,实际中各类图片、视频等也是常见的数据源;另一个是数据量非常庞大,稍微大点的公司每天10TB以上规模非常正常,像阿里能达到PB级别。

以Hadoop系统为例,由于存在行存储和列存储两种形态,因而数据格式的要求是高度统一的,势必要求同步工具能够将数据处理成结构化、半结构化的形态,能够支持标准Sql查询,所有数据类型统一为字符串类型,进而可以通过Hive等工具做二次加工处理。

由于现在的大数据平台基本都不支持Update操作,因而再进行数据合并时,通常采用merge的方式进行,常见的有全外连接+重新加载,即full outer join + insert overwrite的方式进行,也就是当天的增量数据和前一天的全量数据做全外连接,然后再重新加载。

七、实时数据同步

对于一部分业务数据而言,需要统计实时的数据项,例如电商平台大促期间的总金额统计,需要源数据不经过离线系统,直接通过消息队列进入到Storm等流式计算平台,直接产出数据。但同时部分数据配置信息需要从Mysql中获取,因而binlog日志也需要做同步来实时获得配置信息的变化情况。对于实时数据而言,这个阶段虽然PV、总金额等数据比较容易统计,但UV数据就显得有些困难。这个时候可以采用近似统计的方式,先算出一个大概,再通过离线系统进行精确数据的更新。具体做法可以通过布隆过滤器等模型来实现,数据能够放在内存中进行统计。

八、Flume工具类介绍

目前大多数公司对于批量数据同步都采用Flume等框架,一来配置比较简单,二来可靠性比较好,三来是与Hadoop的兼容性不错。Flume数据流模型如下:Event是流经Flume 代理(agent)的一个数据单元。Event从Source经Channel流向Sink,这个过程通过对Event接口的实现来代表。一个Event传输了一份载荷(字节数字)和一个与之相伴的可选头部(字符串属性)。一个Flume agent就是一个进程(JVM),管理着允许Event从一个外部源流向外部目标的各组件。

九、Kafka消息队列介绍

使用消息队列主要有两点好处,一是通过异步处理提高系统性能(削峰、减少响应所需时间等),二是降低系统耦合性。在不使用消息队列服务器的时候,用户的请求数据直接写入数据库,在高并发的情况下数据库压力剧增,使得响应速度变慢。但是在使用消息队列之后,用户的请求数据发送给消息队列之后立即返回,再由消息队列的消费者进程从消息队列中获取数据,异步写入数据库。由于消息队列服务器处理速度快于数据库(消息队列也比数据库有更好的伸缩性),因此响应速度得到大幅改善。

这里需要提一点,最终一致性的实现思路:主要是用“记录”和“补偿”的方式。本地事务维护业务变化和通知消息,一起落地,然后RPC到达broker,在broker成功落地后,RPC返回成功,本地消息可以删除。否则本地消息一直靠定时任务轮询不断重发,这样就保证了消息可靠落地broker。broker往consumer发送消息的过程类似,一直发送消息,直到consumer发送消费成功确认。我们先不理会重复消息的问题,通过两次消息落地加补偿,下游是一定可以收到消息的。然后依赖状态机版本号等方式做判重,更新自己的业务,就实现了最终一致性。如果出现消费方处理过慢消费不过来,要允许消费方主动ack error,并可以与broker约定下次投递的时间。对于broker投递到consumer的消息,由于不确定丢失是在业务处理过程中还是消息发送丢失的情况下,有必要记录下投递的IP地址。决定重发之前询问这个IP,消息处理成功了吗?如果询问无果,再重发。

以下为不同消息队列对比图:

十、数据漂移

数据漂移通常是由于处理系统的延迟性造成的,例如前一天的数据落到了今天的数据分区里,处理方法也比较多种:

首先是多获取后一天的数据,如果数据是以小时划分的,那么在计算中间表时,多向后获取1小时的数据分区,基本上可以保障拿到前一天的全量数据。

其次是根据日志时间戳字段来获得准确数据,也就是数据根据log_time字段进行判断,然后写入到对应的分区中。

发布了19 篇原创文章 · 获赞 0 · 访问量 901

猜你喜欢

转载自blog.csdn.net/gaixiaoyang123/article/details/103801871