数据仓库简介

参考《Hadoop构建数据仓库实践》

快速导航

主题域
RDS
TDS
ODS

1. 什么是数据仓库

1.1 数据仓库的定义

数据仓库之父Bill Inmon将数据仓库描述 为一个面向主题的、集成的、随时间变化的、非易失的数据集合,用于支持管理者的决策过程。

  • 面向主题

数据仓库被设计成辅助人们分析数据。例如,一个公司要分析销售数据,就可以建立一个专注于销售的数据仓库,使用这个数据仓库,就可以回答类似于”去年谁是我们这款产品的最佳用户“这样的问题。主题域是对某个主题进行分析后确定的主题的边界,如客户、销售、产品都是主题域的例子。

  • 集成

还用销售的例子,假设公司有多条产品线和多种产品销售渠道,而每个产品线都有自己独立的销售数据库。此时要想从公司层面整体分析销售数据,必须将多个分散的数据源统一成一致的、无歧义的数据格式后,再放置到数据仓库中。因此数据仓库必须能解决诸如产品命名冲突、计量单位不一致等问题。当完成了这些数据整合工作后,该数据仓库可称为是集成的。

  • 随时间变化

为了发现业务变化的趋势、存在的问题,或者新的机会,需要分析大量的历史数据。这与联机事务处理(OLTP)系统形成鲜明的对比。OLTP反应的是当前时间点的数据情况,要求高性能、高并发和极短的响应时间。而数据仓库关注的是数据随时间变化的情况,并且能反映在过去某个时间点的数据是怎样的。

  • 非易失

一旦进入到数据仓库中,数据就不应该再有改变。在数据仓库环境中,一般不进行数据更新。数据仓库中的数据基本是静态的。数据仓库的目的就是根据曾经发生的事件进行分析,如果数据是可修改的,将使历史分析变得没有意义。

除了以上四个特性以外,数据仓库还有一个重要的概念是粒度。数据仓库中的粒度是指数据的细节或汇总程度,细节程度越高,粒度级别越低。例如,单个事务是低粒度级别,而全部一个月事务的汇总就是高粒度级别。粒度级别越低,数据量越大,查询的细节程度越高,查询范围越广泛。

1.2 数据仓库里的数据从哪里来

通常数据仓库的数据来自各个业务应用系统。

  • Oracle、MySQL、SQL Server等关系数据库里的结构化数据;
  • 文本、CSV等平面文件或Word、Excel文档中的非结构化数据;
  • HTML、XML等自描述的半结构化数据。

这些业务数据经过一系列的数据抽取、转换、清洗,最终以一种统一的格式装载进数据仓库。数据仓库里的数据作为分析用的数据源,提供给后面的即席(ad hoc)查询、分析系统、数据集市、报表系统、数据挖掘系统等。

1.3 建立数据仓库的原因,数据仓库的好处

为什么不直接操作业务系统中的数据用于分析,而要使用数据仓库呢?很多因素导致直接访问业务系统无法进行全局数据分析的工作:

  • 某些业务数据由于安全或其他因素不能直接访问。
  • 业务系统的版本变更很频繁,每次变更都需要重写分析系统并重新测试。
  • 很难建立和维护汇总数据来源于多个业务系统版本的报表。
  • 业务系统的数据格式,如日期、数字的格式不统一。
  • 业务系统的表结构为事务处理性能而优化,有时并不适合查询与分析。
  • ...

使用数据仓库的好处:

  • 将多个数据源集成到单一数据存储,因此可以使用单一数据查询引擎展示数据。
  • 缓解在事务处理数据库上因执行大查询而产生的资源竞争问题。
  • 维护历史数据
  • 通过提供一致的编码和描述,减少或修正坏数据问题,提高数据质量。
  • 重构数据,使数据对业务用户更有意义。
  • 向复杂分析查询交付优秀的查询性能,同时不影响操作型系统。
  • ...

2. 操作型系统与分析型系统

2.1 操作型系统

操作型系统是一类专门用于管理面向事务的应用的信息系统。事务在这里指计算机或数据库的术语。

2.1.1 操作型系统的数据库操作

常用操作:增、改、查。通常是插入与更新密集型的,同时会对数据库进行大量并发查询,而删除操作相对较少。

2.1.2 操作型系统的数据库设计

操作型系统的特征是大量短的事务,并强调快速处理查询。每秒事务数是操作型系统的一个有效度量指标。

在数据库逻辑设计上,操作型系统的应用数据库大都使用规范化设计方法,通常要满足第三范式。这是因为规范化设计能最大限度地减少数据冗余,提供更快更高效的方式执行数据库写操作。

关于数据库的三大范式的介绍可见: https://blog.csdn.net/ddzzz_/article/details/119277573

在数据库物理设计上,以Oracle数据库为例,简要说明在设计操作型系统数据库时应考虑的问题:

  • 合理使用聚簇。聚簇是一种数据库模式,其中包含有共用一列或多列的多个表。数据库中的聚簇表用于提高连接操作的性能。
  • 适当调整数据块大小。数据块大小应该是操作系统块大小的倍数,并且设置上限以避免不必要的I/O。
  • 动态分配表空间。
  • 合理划分数据库分区。分区最大的作用是能在可用性和安全性维护期间保持事务处理的性能。
  • SQL优化。有效利用数据库管理系统的优化器,使用最佳的数据访问路径。
  • 避免过度使用索引。大量的数据修改会给索引维护带来压力,从而对整个系统的性能产生负面影响。

以上所讲的操作型系统都是以数据库系统为核心,而数据库系统为了保持ACID特性,本质上是单一集中式系统。在当今这个信息爆炸的时代,集中式数据库往往已无法支撑业务的需要。分布式事务、去中心化、CAP与最终一致性等一些列新的理论和技术为解决系统扩展问题应运而生。这里不做展开。

2.2 分析型系统

分析型系统是一种快速回答多维分析查询的实现方式。

2.2.1 分析型系统的数据库操作

在数据库层面,分析型系统操作被定义为少量的事务,复杂的查询,处理归档和历史数据。这些数据很少被修改,从数据库抽取数据是最多的操作。分析型数据库基本上都是读操作

2.2.2 分析型系统的数据库设计

分析型系统的特征是相对少量的事务,但查询通常非常复杂且会包含聚合计算。吞吐量是一个有效的性能度量指标。

在数据库逻辑设计上,分析型数据库使用多维数据模型,通常是设计成星型模式雪花模式

在数据库物理设计上,依然以Oracle数据库为例,简要说明在设计分析型系统数据库时应该考虑的一些问题。

  • 表分区。可以独立定义表分区的物理存储属性,将不同分区的数据存放到多个物理文件上,这样做一方面可以分散I/O;另一方面,当数据量非常大时,方便数据维护;再有就是利用分区消除查询数据时,不用扫描整张表,从而提高查询性能。
  • 位图索引。当查询条件中包含低基数(不同值很少,例如性别)的列,尤其是包含有这些列上的or、and或not这样的逻辑运算时,或者从有大量行的表中返回大量的行时,应考虑位图索引。
  • 物化视图。物化视图物理存储查询所定义的数据,能够自动增量刷新数据,并且可以利用查询重写特性极大地提高查询速度。
  • 并行化操作。可以在查询大量数据时执行并行化操作,这样会使多个服务器进程为同一个查询语句工作,使得该查询可以快速完成,但会耗费更多的资源。

分析型系统更加注重数据分析和报表,而操作型系统的目标是一个伴有大量数据改变的事务优化系统。

3. 数据仓库架构

3.1 基本架构

img

整个数据仓库环境包括操作型系统和数据仓库系统两大部分。操作型系统的数据由各种形式的业务数据组成(数据可能是结构化、半结构化、非结构化的)。这些数据经过抽取、转换和装载(ETL)过程进入数据仓库系统。

这里把ETL过程分成了抽取和转换装载两个部分。抽取过程负责从操作型系统获取数据,该过程一般不做数据聚合和汇总,但是会按照主题进行集成,物理上是将操作型系统的数据全量或增量复制到数据仓库系统的RDS中。

抽取过程指的是把数据从操作型数据源抽取到RDS的过程,这个过程可能会有一些数据集成的操作,但不会做数据转换、清洗、格式化等工作。 Hadoop生态圈中的主要数据源抽取工具是 SqoopFlume。Sqoop被设计成支持在关系数据库和 Hadoop 之间传输数据,而 Flume 被设计成基于流的数据捕获,主要是从日志文件中获取数据。使用这两个工具可以完成数据仓库的抽取。 如果数据源是普通的文本和CSV文件,抽取过程将更加简单,只需用操作系统的scpftp命令将文件拉取到Hadoop集群的任一节点,然后使用HDFS的put命令将已在本地的文件上传到HDFS,或者使用Hive的load data将文件装载进表里就可以了。

转换装载过程将数据进行清洗、过滤、汇总、统一格式化等一系列转换操作后,使数据转换为适合查询的格式,然后装载进数据仓库系统的TDS中。

转换与装载过程是将数据从RDS迁移到TDS的过程,期间会对数据进行一系列的转换和处理。经过了数据抽取步骤,此时数据已经在Hive表中了,因此Hive可以用于转换和装载。 Hive实际上是在MapReduce之上封装了一层SQL解释器,这样可以用类SQL语言书写复杂的MapReduce作业。Hive不但提供了丰富的数据查询功能和分析函数,还可以在某些限制下进行数据的更新,因此支持SCD1(渐变维的一种处理类型)。

(关于ETL的更详细内容见 4. 抽取-转换-装载(ETL)

RDS (RAW DATA STORES) 是原始数据存储的意思。将原始数据保存到数据仓库是个不错的想法。ETL过程的bug或系统中的其他错误是不可避免的,保留原始数据使得追踪并修改这些错误成为可能。有时数据仓库的用户会有查询细节数据的需求,这些细节数据的粒度与操作型系统的相同。有了RDS,这种需求很容易实现,用户可以查询RDS里的数据而不必影响业务系统的正常运行。这里的RDS实际上是起到了操作型数据存储(ODS)的作用。

RDS 是原始数据存储,其数据是从操作型系统抽取而来。它有两个作用,一是充当操作型系统和数据仓库之间的过渡区,二是作为细节数据查询的数据源。

TDS (TRANSFORMED DATA STORES) 意为转换后的数据存储。这是真正的数据仓库中的数据。大量的用户会在经过转换的数据集上处理他们的日常查询。这些数据将被以保证最重要的和最频繁的查询能够快速执行的方式构建。

TDS 是转换后的数据存储,也就是数据仓库,用于后续的多维分析或即席查询。

自动化调度组件的作用是自动定期重复执行ETL过程。

ETL过程自动化是数据仓库成功的重要衡量标准,也是系统易用性的关键。 Hadoop生态圈中的主要管理工具是 Falcon。Falcon把自己看作是数据治理工具,能让用户建立定义好的ETL流水线。还有一个叫做 Oozie 的工具,它是一个Hadoop的工作流程调度系统,可以使用它将ETL过程封装进工作流自动执行。

数据目录有时也被称为元数据存储,它存储的是数据仓库的元数据,可以提供一份数据仓库中数据的清单,主要是描述数据属性的信息,用来支持如指示存储位置、历史数据、资源查找、文件记录等功能。用户通过它应该可以快速解决这些问题:什么类型的数据被存储在哪里,数据集的构建有何区别,数据最后的访问或更新时间等。

Hadoop 生态圈中主要的数据目录工具是 HCatalog。HCatalog 是 Hadoop 上的一个表和存储管理层。使用不同的数据处理工具(如 Pig、MapReduce)的用户,通过 HCatalog 可以更加容易地读写集群中的数据。HCatalog 引入”表“的抽象,把文件看作数据集。它展现给用户的是一个 HDFS 上数据的关系视图,这样用户不必关心数据存放在哪里或者数据格式是什么等问题,就可以轻松知道系统中有哪些表,表中都包含什么。 HCatalog 默认支持多种文件格式的读写,如 RCFile、SequenceFile、ORC files、text files、CSV、JSON等。

查询引擎组件负责实际执行用户查询。

由于最终用户经常需要进行交互式的即席查询,并随时动态改变和组合他们的查询条件,因此要求查询引擎具有很高的查询性能和较短的响应时间。
Hadoop生态圈中的主要SQL查询引擎有基于 MapReduce 的 Hive、基于 RDD 的 SparkSQL 和 Cloudera 公司的 Impala
Hive可以在四种主流计算框架的三种,分别是 Tez、MapReduce 和 Spark(还有一种是Storm)上执行类SQL查询。(关于三种计算框架的介绍见:hive的引擎mapreduce、tez和spark三者比较 - 简书)
SparkSQL是Hadoop中另一个著名的SQL引擎,它实际上是一个Scala程序语言的子集。正如SparkSQL这个名字所暗示的,它以 Spark 作为底层的计算框架。
Impala 是 Cloudera 公司的查询系统,它提供 SQL 语言,最大的特点是速度快,主要用于 OLAP。

用户界面指的是最终用户所使用的接口程序。可能是一个GUI软件,如BI套件中的客户端软件,也可能是一个浏览器。

数据分析的结果最终要以业务语言和形象化的方式展现给用户。数据仓库的最终用户界面通常是一个BI仪表盘或类似的一个数据可视化工具提供的浏览器页面。 Hadoop 生态圈中比较知名的数据可视化工具是 HueZeppelin。 Hue 是一个开源的 Hadoop UI 系统,最早是由 Cloudera Desktop 演化而来,它是基于 Python Web 框架 Django 实现的。通过使用 Hue 我们可以在浏览器端的 Web 控制台上与 Hadoop 集群进行交互来分析处理数据,还可以用图形化的方式定义工作流。Hue 默认支持的数据源有 Hive 和 Impala。 Zeppelin 提供了 Web 版的 notebook,用于做数据分析和可视化。Zeppelin 默认只支持 SparkSQL。

可以看到,普通数据仓库的8个组成部分都有相对应的 Hadoop 组件作为支撑。Hadoop 生态圈中众多工具提供的功能,完全可以满足创建传统数据仓库的需要。使用 Hadoop 建立数据仓库不仅是必要,而且是充分的。

3.2 操作数据存储(ODS)

操作数据存储又称为ODS (Operational Data Sore),定义:一个面向主题的、集成的、可变的、当前的细节数据集合,用于支持企业对于即时性的、操作性的、集成的全体信息的需求。ODS在某些方面具有类似于数据仓库的特点,在另一些方面又显著不同。

  • 像数据仓库一样,是面向主题的
  • 像数据仓库一样,其数据是完全集成的
  • 数据是当前的,这与数据仓库存储历史数据的性质明显不同。ODS具有最少的历史数据(一般是30天到60天),而尽可能接近实时地展示数据的状态。
  • 数据是可更新的,ODS就如同一个事务处理系统,当新的数据流进ODS时,受其影响的字段被新信息覆盖。
  • 数据几乎完全是细节数据,仅具有少量的动态聚集或汇总数据。通常将ODS设计成包含事务级的数据,即包含该主题域中最低粒度级别的数据。
  • 在数据仓库中,几乎没有针对其本身的报表,报表均放到数据集市中完成;在ODS中,业务用户频繁地直接访问ODS。

在一个数据仓库环境中,ODS具有如下几个作用:

  • 充当业务系统与数据仓库之间的过渡区。ODS中存放的数据从数据结构、数据粒度、数据之间的逻辑关系上都与业务系统基本保持一致,因此抽取过程只需简单的数据复制而基本不再需要做数据转换,大大降低了复杂性,同时最小化对业务系统的侵入。
  • 转移部分业务系统细节查询的功能。某些原来由业务系统产生的报表、细节数据的查询能够在ODS中进行,从而降低业务系统的查询压力。
  • 完成数据仓库中不能完成的一些功能。用户有时会要求数据仓库查询最低粒度级别的细节数据,而数据仓库中存储的一般是聚合或汇总过的数据,并不存储每笔交易产生的细节数据,这时就需要转移到ODS来完成,而且ODS的数据模型是按照面向主题的方式组织的,可以方便地支持多维分析。

4. 抽取-转换-装载(ETL)

ETL(Extract、Transform、Load)是建立数据仓库最重要的处理过程。

  • 抽取:从操作型数据源获取数据。
  • 转换:转换数据,使之转变为适用于查询和分析的形式和结构。
  • 装载:将转换后的数据导入到最终的目标数据仓库。

建立一个数据仓库就是要把来自于多个异构的源系统的数据集成在一起,放置于一个集中的位置用于数据分析。ETL系统的工作就是把异构的数据转换成同构的。

4.1 数据抽取

设计和建立数据抽取过程,在ETL处理乃至整个数据仓库处理过程中,一般是较为耗时的任务。需要决定抽取哪些数据。通常数据都不是只抽取一次,而是需要以一定的时间间隔反复抽取。对抽取方法的选择高度依赖于源系统和目标数据仓库环境的业务需要。一般情况下,不可能因为需要提升数据抽取的性能,而在源系统中添加额外的逻辑,也不能增加这些源系统的工作负载。

4.1.1 逻辑抽取

两种逻辑抽取类型:全量抽取增量抽取

(1)全量抽取

源系统的数据全部被抽取。因为这种抽取类型影响源系统上当前所有有效的数据,所以不需要跟踪自上次成功抽取以来的数据变化。源系统只需要原样提供现有的数据而不需要为附加的逻辑信息(比如时间戳等)。一个全表导出的数据文件或者一个查询源表所有数据的SQL语句,都是全量抽取的例子。

(2)增量抽取

只抽取某个事件发生的特定时间点之后的数据。通过该事件发生的时间顺序能够反映数据的历史变化,它可能是最后一次成功抽取,也可能是一个复杂的业务事件,如最后一次财务结算等。必须能够标识出特定时间点之后所有的数据变化。这些发生变化的数据可以由源系统自身来提供,例如能够反映数据最后发生变化的时间戳列,或者是一个原始事务处理之外的,只用于跟踪数据变化的变更日志表。大多数情况下,使用后者意味着需要在源系统上增加抽取逻辑。

在许多数据仓库中,抽取过程不含任何变化数据捕获技术。取而代之的是,把源系统中的整个表抽取到数据仓厍过渡区,然后用这个表的数据和上次从源系统抽取得到的表数据作比对,从而找出发生变化的数据。虽然这种方法不会对源系统造成很大的影响,但显然需要考虑给数据仓库处理增加的负担,尤其是当数据量很大的时候。

4.1.2 物理抽取

依赖于选择的逻辑抽取方法和能够对源系统所做的操作和所受的限制,存在两种物理数据抽取机制:直接从源系统联机抽取或者间接从一个脱机结构抽取数据。这个脱机结构有可能已经存在,也可能需要由抽取程序生成。

(1)联机抽取

数据直接从源系统抽取。抽取进程或者直连源系统数据库,访问它们的数据表,或者连接到一个存储快照日志或变更记录表的中间层系统。注意这个中间层系统并不需要必须和源系统物理分离。

(2)脱机抽取

数据不从源系统直接抽取,而是从一个源系统以外的过渡区抽取。过渡区可能己经存在(例如数据库备份文件、关系数据库系统的重做日志、归档日志等),或者抽取程序自己建立。

4.1.3 变化数据捕获

抽取处理需要重点考虑增量抽取,也被称为变化数据捕获,简称CDC。假设一个数据仓库系统,在每天夜里的业务低峰时间从操作型源系统抽取数据,那么增量抽取只需要过去24小时内发生变化的数据。变化数据捕获也是建立准实时数据仓库的关键技术。

常用的变化数据捕获方法有时间戳、快照、触发器和日志四种。时间戳方法需要源系统有相应的数据列表示最后的数据变化。快照方法可以使用数据库系统自带的机制实现,如Oracle的物化视图技术,也可以自己实现相关逻辑,但会比较复杂。触发器是关系数据库系统具有的特性,源表上建立的触发器会在对该表执行insert、update、delete等语句时被触发,触发器中的逻辑用于捕获数据的变化。日志可以使用应用日志或系统日志,这种方式对源系统不具有侵入性,但需要额外的日志解析工作。

4.2 数据转换

转换操作:如统一数据类型、处理拼写错误、消除数据歧义、解析为标准格式等。数据转换一个最重要的功能是清洗数据,只有”合规“的数据才能进入目标数据仓库。

  • 只装载特定的数据列。例如,某列为空的数据不装载。
  • 统一数据编码。例如,性别字段,有些系统使用的是1和0,有些是'M,和'F',有些是'男',和'女',统一成'M'和'F'
  • 自由值编码。例如,将'Male'改成'M'
  • 预计算。例如,产品单价*购买数量=金额。
  • 基于某些规则重新排序以提高查询性能。
  • 合并多个数据源的数据并去重。
  • 预聚合。例如,汇总销售数据。
  • 行列转置
  • 将一列转为多列。例如,某列存储的数据是以逗号作为分隔符的字符串,将其分割成多列的单个值
  • 合并重复列
  • 预连接。例如,查询多个关联表的数据。
  • 数据验证。针对验证的结果采取不同的处理,通过验证的数据交给装载步骤,验证失败的数据或直接丢弄,或记录下来做进一步检查。

4.3 数据装载

把转换后的数据装载进目标数据仓库。需要考虑的两个问题:

  • 数据装载的效率问题
  • 一旦装载过程中途失败了,如何再次重复执行装载过程

即使经过了转换、过滤和清洗,去掉了部分噪声数据,但需要装载的数据量还是很大的。执行一次数据装载可能需要几个小时的时间,同时需要占用大量的系统资源,要提高装载的效率,加快装载速度,可以从以下几方面入手。

  • 首先保证足够的系统资源。数据仓厍存储的都是海量数据,所以要配置高性能的服务器,并且要独占资源,不要与别的系统共用。
  • 在进行数据装载时,要禁用数据库约束(唯一性、非空性,检查约束等)和索引,当装载过程完全结束后,再启用这些约束,重建索引,这种方法会很大的提高装载速度。在数据仓库环境中,一般不使用数据库来保证数据的参考完整性,即不使用数据库的外键约束,它应该由ETL工具或程序来维护。

数据装载过程可能由于多种原因而失败,比如装载过程中某些源表和目标表的结构不一致而导致失败,而这时己经有部分表装载成功了。在数据量很大的情况下,如何能在重新执行装载过程时只装载失败的部分是一个不小的挑战。对于这种情况,实现可重复装载的关键是要记录下失败点,并在装载程序中处理相关的逻辑。还有一种情况,就是装载成功,数据又发生了改变(比如有些滞后的数据在ETL执行完才进入系统,就会带来数据的更新或新增),这时需要重新再执行一遍装载过程,己经正确装载的数据可以被覆盖,但相同数据不能重复新增。简单的实现方式是先删除再插入,或者用replace into、merge into等类似功能的操作。

装载到数据仓库里的数据,经过汇总、聚合等处理后交付给多维立方体或数据可视化、仪表盘等报表工具、Bl工具做进一步的数据分析。