细讲ods数据仓库


ODS数据仓库全称是Operational Data Store,译为操作数据存储。

ODS VS DB VS EDW

ODS是一组支持企业日常全局应用的数据集合,其数据具有面向主题、集成的、可变的以及数据是当前的或是接近当前的特点。同样也可以看出ODS是介于DB和DW之间的过渡存储。

由于ODS是将业务系统源数据存储在数据仓库中,因此从数据粒度、数据结构、数据关系等各个方面都与业务系统的数据源保持一致。然而,也不能把ODS层简单视作业务系统数据源的一个备份,ODS数据仓库和业务系统数据源的区别主要是因为这两层的面向业务需求不同,业务系统是面向多并发读写同时有需要满足数据的一致性,而ODS数据仓库通常是面向数据报表等批量数据查询需求。

ODS层的设计思路

ODS层数据同步

我们已经知道ODS的数据来源于业务系统,且ODS落地的系统也经常有别于业务系统,比如常见的将数据落到Hive中。所以,首先我们就需要将业务系统的数据抽取到ODS表中。一般来说,数据同步的方式大概可以分为三大类:文件抽取、数据库表的抽取和原始日志的抽取。

文件抽取

通常情况下,ODS层表的存储位置与业务系统表的存储位置是不一样的,比如业务表存在MySQL中,而ODS层存储在Hive中。另外,有的时候,ODS层需要对接多个不同类型的业务系统库,比如DB2、Oracle、Mysql等等,一种比较简单实用的做法是和各个业务系统约定好数据接口,并让业务系统按照数据接口格式生成数据文件和完结标示文件给到ODS。

这种方式有两个明显的优势:一方面可以降低ODS处理多种类型数据库系统能力需求,另一方面也减少了对业务系统的性能影响。但是这种方式也存在一些不足:数据的抽取过程和加载过程是分开的,由业务系统和ODS数据仓库分别负责,同时接口新增和变更比较麻烦,需要较大的沟通维护成本,另外,数据落地到文件增加了额外的上传下载工作,会造成效率比较低。

在实际的生产过程中,这种方式的数据同步也很少被使用。

直连同步

直连同步是指通过定义好的规范接口API和基于动态链接库的方式直接连接业务库,比如ODBC/JDBC等规定了统一的标准接口,不同的数据库基于这套标准提供规范的驱动,从而支持完全相同的函数调用和SQL实现。比如经常使用的Sqoop就是采取这种方式进行批量数据同步的。

直连同步的方式配置十分简单,很容易上手操作,比较适合操作型业务系统的数据同步,但是会存在以下问题:

数据同步时间:随着业务规模的增长,数据同步花费的时间会越来越长,无法满足下游数仓生产的时间要求。

性能瓶颈:直连数据库查询数据,对数据库影响非常大,容易造成慢查询,如果业务库没有采取主备策略,则会影响业务线上的正常服务,如果采取了主备策略,虽然可以避免对业务系统的性能影响,但当数据量较大时,性能依然会很差。

抽取增量数据需要依靠修改业务系统,新增时间戳字段,并且按时间戳增量抽取的数据准确性不能得到保障,业务系统做数据补丁不更新时间戳字段将会导致漏数;

实时性差,只能在某个时刻抽取数据,不能满足准实时数据需求;

在实际的生产过程中,这种方式的数据同步经常被使用,值得注意的是:数据库直连抽取比较适用于小批量表的数据抽取,对于大批量的数据而言,性能会比较差。

日志解析

据库日志抽取是指通过分析数据库日志,将业务系统的DDL和DML语句在一个镜像系统还原,并通过数据流的方式对外提供实时数据服务。

所谓日志解析,即解析数据库的变更日志,比如MySQL的Binlog日志,Oracle的归档日志文件。通过读取这些日志信息,收集变化的数据并将其解析到目标存储中即可完成数据的实时同步。这种读操作是在操作系统层面完成的,不需要通过数据库,因此不会给源数据库带来性能上的瓶颈。

由于是数据库日志抽取是获取所有的变更记录,落地到ODS表的时候我们需要根据主键去重按照日志时间倒排序获取最后状态的变化情况。通常使FULL OUTER JOIN全外连接的方式进行Merge数据。

数据库日志解析的同步方式可以实现实时与准实时的同步,延迟可以控制在毫秒级别的,其最大的优势就是性能好、效率高,不会对源数据库造成影响,目前,从业务系统到数据仓库中的实时增量同步,广泛采取这种方式。

当然,任何方式都不是完美的,使用日志解析的方式进行数据同步也会存在一些已知的问题:比如在业务系统做批量补数时会造成数据更新量超过处理的能力,从而导致数据延迟。另外,这种方式需要额外补数一个实时抽取的系统,从而也增加了投入和处理的复杂性。

该如何选择同步方式

在实际的生产环境中,直连同步和日志解析是非常普遍的两种数据同步方式,随着实时技术的发展,使得实时数据同步的方式变得越来越方便,越来越多的企业开始尝试使用日志解析的方式进行数据同步。这里需要注意的是,每种方式都有其优缺点及适用的场景,找到合适的方式就是最好的方式,切不可一味的追求狂拽酷炫的同步技术,这也是很多技术人员经常犯的错误,应用和钻研新技术是技术人的追求,但是过犹不及,在解决具体问题的时候,要多方面权衡。

另外,数仓的建设是为业务服务的,应该把时间和精力放在如何支持业务、如何发挥数仓的价值、如何用数据为业务提供支持决策上来。笔者认为,数仓的建设不是一堆大数据技术的简单堆砌,深入理解业务和数据才是数仓建设的第一要义。

ODS层数据清洗

关于ODS层是否做数据清洗一直是存在争议的,但有一点是可以确定的,对于比较重的清洗工作是要留到后面数仓的ETL过程中进行处理。

但是,有这么一种情况:我们在长期的生产实际过程中,发现部分已知的数据问题的处理可以通过自动化的方式来处理,这种方式通常在数据入库之前,做额外的加工处理后再做入库操作。

数据清洗的主要工作是处理那些不符合要求的数据,从而提升数据质量,比如一些常见的问题:错误的数据、重复的数据。

错误的数据

这种错误通常是业务系统处理不够健全造成的,比如字符串数据后面有回车空格、日期格式不正确、日期越界等等,这些问题如果不在ODS层做处理,后续的解析处理过程中也是要留意处理的

重复的数据

例如,一些前端系统迁移过后的新老表融合可能会存在大量的重复历史数据,这也可以在数据清洗这一步骤中完成消除重复数据的操作。需要注意的是,在数据清洗后还需要对ODS的数据做稽核,还需要对脏数据做稽核校验,脏数据的校验主要集中在数据量上,如果数据量波动特别大则需要人工介入处理。

其实,在大多数的情况下,是不需要做数据清洗处理的,可以把这个清洗环节放到后面的明细层ETL中进行处理。

ODS层表设计

通常而言,ODS层表跟业务系统保持一致,但又不完全等同于业务系统。在设计ODS物理表时,在表命名、数据存储等方面都需要遵循一定的准则。

命名

比如:不管是表命名还是字段命名尽量和业务系统保持一致,但是需要通过额外的标识来区分增量和全量表,”_delta”来标识该表为增量表。

存储

另外,为了满足历史数据分析需求,我们需要在ODS表中加一个时间维度,这个维度通常在ODS表中作为分区字段。如果是增量存储,则可以按天为单位使用业务日期作为分区,每个分区存放日增量的业务数据。如果是全量存储,只可以按天为单位使用业务日期作为分区,每个分区存储截止到当前业务时间的全量快照数据。