3.5 Hadoop与数据仓库

传统数据仓库一般建立在Oracle、MySQL这样的关系数据库系统之上。关系数据库主要的问题是不好扩展,或者说扩展的成本非常高,因此面对当前4Vs的大数据问题时显得能力不足,而这时就显示出Hadoop的威力。Hadoop生态圈最大的吸引力是它有能力处理非常大的数据量。在大多数情况下,Hadoop生态圈的工具能够比关系数据库处理更多的数据,因为数据和计算都是分布式的。

还用介绍MapReduce时的那个例子进行说明:在一个10TB的Web日志文件中,找出单词‘ERROR’的个数。解决这个问题最直接的方法就是查找日志文件中的每个单词,并对单词‘ERROR’的出现进行计数。做这样的计算会将整个数据集读入内存。作为讨论的基础,我们假设现代系统从磁盘到内存的数据传输速率为每秒100MB,这意味着在单一计算机上要将10TB数据读入内存需要27.7个小时。如果我们把数据分散到10台计算机上,每台计算机只需要处理1TB的数据。它们彼此独立,可以对自己的数据分片中出现的‘ERROR’计数,最后再将每台计算机的计数相加。在此场景下,每台计算机需要2.7个小时读取1TB数据。因为所有计算机并行工作,所以总的时间也近似是2.7个小时。这种方式即为线性扩展——可以通过简单地增加所使用的计算机数量来减少处理数据花费的时间。以此类推,如果我们使用100台计算机,做这个任务只需0.27个小时。Hadoop背后的核心观点是:如果一个计算可以被分成小的部分,每一部分工作在独立的数据子集上,并且计算的全局结果是独立部分结果的联合,那么此计算就可以分布在多台计算机中并行执行。

分布式计算可以用来解决大数据问题,那么关系数据库能否采用分布式呢?答案是无论实际中还是理论上,关系数据库都难以在大规模集群的很多台机器上并行执行。在本节,先看一下关系数据库可扩展性的不足,然后了解相关理论,最后说明使用Hadoop创建传统数据仓库的可行性,及其生态圈中与数据仓库相关的工具组件。

3.5.1 关系数据库的可扩展性瓶颈

关系数据库的可扩展性一直是数据库厂商和用户最关注的问题。从较高的层次看,可扩展性就是能够通过增加资源来提升容量,并保持系统性能的能力。可扩展性可分为向上扩展(Scale up)和向外扩展(Scale out)。

向上扩展有时也称为垂直扩展,它意味着采用性能更强劲的硬件设备,比如通过增加CPU、内存、磁盘等方式提高处理能力,或者购买小型机或高端存储来保证数据库系统的性能和可用性。无论怎样,向上扩展还是一种集中式的架构。也就是说,数据库系统运行在一台硬件设备上,要做的就是不断提高这台设备的配置以加强性能。

向上扩展最大的好处就是实现简单,降低开发人员和维护人员的技能门槛。很明显单台服务器比多台服务器更容易开发,因为无须关心多台机器间的数据一致性或者谁主谁从等问题,能显著节省开发成本。同时单机上的数据备份与恢复等维护工作相对简单,也不用考虑数据复制等问题,减轻了系统维护的工作。但向上扩展存在不可逾越的障碍,当应用变得非常庞大,向上扩展策略就无能为力了。首先是成本问题,特殊配置的硬件往往非常昂贵。再有向上扩展不是无限制的,即使最强大的单台计算机,其处理能力也有限制。当应用到达一定程度,向上扩展不再可行,此时就需要向外扩展。

向外扩展有时也称为横向扩展或水平扩展,由多台廉价的通用服务器实现分布式计算,分担某一应用的负载。关系数据库的向外扩展主要有Shared Disk和Shared Nothing两种实现方式。Shared Disk的各个处理单元使用自己的私有CPU和内存,共享磁盘系统,典型的代表是OracleRAC。Shared Nothing的各个处理单元都有自己私有的CPU、内存和硬盘,不存在共享资源,各处理单元之间通过协议通信,并行处理和扩展能力更好,MySQL Fabric采用的就是Shared Nothing架构。

1. Oracle RAC

Oracle RAC是Oracle的集群解决方案。其架构的最大特点是共享存储架构(Shareddisk),整个RAC集群建立在一个共享的存储设备之上,节点之间采用高速网络互连。Oracle RAC提供了较好的高可用特性,比如负载均衡和透明应用切换。其最大优势在于对应用完全透明,应用无须修改便可以从单机数据库切换到RAC集群。

但是,RAC的扩展能力有限,32个节点的RAC已算非常庞大了。随着节点数的不断增加,节点间通信的成本也会随之增加,当到达某个限度时,增加节点不会再带来性能上的提高,甚至可能造成性能下降。这个问题的主要原因是Oracle RAC对应用透明,应用可以连接集群中的任意节点进行处理,当不同节点上的应用争用资源时,RAC节点间的通信开销会严重影响集群的处理能力。

RAC的另外一个问题是,整个集群都依赖于底层的共享存储,因此共享存储的I/O能力和可用性决定了整个集群可以提供的能力。

2. MySQL Fabric

MySQL Fabric架构为MySQL提供了高可用和横向扩展的特性。在实际部署中,可以单独使用高可用或横向扩展,也可以同时启用这两个特性。

MySQL Fabric在MySQL复制上增加了一个管理和监控层,它和一组MySQLFabric-aware连接器一起,把写和一致性读操作路由到当前的主服务器。MySQL Fabric有一个HA组的概念。HA组是由两个或两个以上的MySQL服务器组成的服务器池。在任一时间点,HA组中有一个主服务器,其他的都是从服务器。HA组的作用是确保该组中的数据总是可访问的。MySQL通过把数据复制多份提供数据安全性。

当单个MySQL服务器(或HA组)的写性能达到极限时,可以使用Fabric把数据分布到多个MySQL服务器组。注意这里说的组可以是单一服务器,也可以是HA组。管理员通过建立一个分片映射,定义数据如何在多个服务中分片。一个分片映射作用于一个或多个表,由管理员指定每个表上的哪些列作为分片键,MySQL Fabric使用分片键计算一个表的特定行应该存在于哪个分片上。当多个表使用相同的映射和分片键时,这些表上包含相同列值(用于分片的列)的数据行将存在于同一个分片。单一事务可以访问一个分片中的所有数据。目前Fabric提供两种用分片键计算分片号的方法:HASH和RANGE。

HASH:在分片键上执行一个哈希函数生成分片号。如果作为分片键的列只有很少的重复值,那么哈希函数的结果会平均分布在多个分片上。

RANGE:管理员显式定义分片键的取值范围和分片之间的映射关系。这可以尽可能让用户控制数据分片,并确定哪一行被分配到哪一个分片。

应用程序访问分片的数据库时,需要设置一个连接属性指定分片键。Fabric连接器会应用正确的范围或哈希映射,并将事务路由到正确的分片。当需要更多的分片时,MySQL Fabric可以把现有的一个分片分成两个,同时修改状态存储和连接器中缓存的路由数据。类似地,一个分片可以从一个HA组迁移到另一个。

注意单一的事务或查询只能访问一个分片,所以基于对数据的理解和应用的访问模式选择一个分片键是非常重要的,并不是对所有表分片都有意义。对于当前不能交叉分片查询的限制,将某些小表的全部数据存储到每一个组中可能会更好。这些全局表被写入到‘全局组’,表中数据的任何改变都会自动复制到所有其他非全局组中。全局组中模式(结构)的改变也会复制到其他非全局组中以保证一致性。

图3-13所示的是一个具有高可用和数据分片特性的MySQL Fabric架构,图中共有10个MySQL实例,其中一个运行连接器,另外九个是工作节点。每行的三个实例是一个HA组,每列的三个实例是一个数据分片。

图3-13 具有高可用和数据分片特性的MySQL Fabric架构

3.5.2 CAP理论

我们已经看到,关系数据库的可扩展性存在很大的局限。虽然这种情况随着分布式数据库技术的出现而有所缓解,但还是无法像Hadoop一样轻松在上千个节点上进行分布式计算。究其原因,就不得不提到CAP理论。

CAP理论指的是任何一个分布式计算系统都不能同时保证如下三点:

● Consistency(一致性):所有节点上的数据时刻保持同步。

● Availability(可用性):每个请求都能接收到一个响应,无论响应成功或失败。

● Partition tolerance(分区容错性):系统应该能持续提供服务,无论网络中的任何分区失效。

换句话说,CAP理论意味着在一个分布式环境下,一致性和可用性只能取其一。这个观点是计算机科学家Eric Brewer在1998年最先提出的,2002年Lynch与其他人证明了Brewer的推测,从而把CAP上升为一个定理。

高可用、数据一致是很多系统设计的目标,但是分区又是不可避免的。

● CA without P:如果不要求P(不允许分区),则C(强一致性)和A(可用性)是可以保证的。但其实分区不是想不想的问题,而是终会存在。因此CA的系统更多的是允许分区后各子系统依然保持CA。传统关系型数据库大都是这种模式。

● CP without A:如果不要求A(可用),相当于每个请求都需要在节点之间强一致,而P(分区)会导致同步时间无限延长,如此CP也是可以保证的。很多传统的数据库分布式事务都属于这种模式。

● AP wihtout C:要高可用并允许分区,则需放弃一致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。现在众多的NoSQL都属于此类。

对于CAP理论也有一些不同的声音,有一种观点认为应该构建不可变模型避免CAP的复杂性。CAP的困境在于允许数据变更,每次变更就得数据同步,保持一致性,这样系统就变得很复杂。然而对于数据仓库这样的应用来说,数据就是客观存在的,不可变,只能增加和查询。传统的CURD(创建、更新、读取、删除)变为CR。这个概念与数据仓库的非易失性非常吻合,任何的变更都是增加记录。通过对所有记录的操作进行合并,从而得到最终记录。因此,任何的数据模型都应该抽象为:Query=Function(all data),任何的数据处理都是查询,查询是对全体数据施加了某个函数的结果。这个定义清晰简单,完全抛弃了CAP那些烦琐而又模糊的语义。因为每次操作都是对所有数据进行全局计算,也就没有了一致性问题。

Hadoop正是这样的系统!Hadoop的HDFS只支持数据增加,其数据复制策略解决了数据可用性问题,而Mapeduce进行全局计算,完美地符合了对数据处理的期望。实际上,在Hadoop的Hive上已经可以进行行级别的增删改操作(本书第6章建立数据仓库示例模型中将会详细介绍),甚至在Hadoop中出现了满足事务处理的数据库产品,如Trafodion。

除Hadoop和一些类似的分布式计算框架外,有没有可能实现一套分布式数据库集群,既保证可用性和一致性,又可以提供很好的扩展能力呢?目前,已经有很多分布式数据库产品,但大部分是面向决策支持类型的应用,因为相比较事务处理应用,决策支持应用更容易做到分布式扩展,比如基于PostgreSQL发展的Greenplum,就很好地解决了可用性和扩展性的问题,并且提供了强大的并行计算能力,现在该产品已经成为Apache HAWQ孵化项目。

2012年,Lynch在证明CAP理论十年后重写了论文,缩小CAP适用的定义,消除质疑的场景,展示了CAP广阔的研究成果,并顺便暗示CAP定理依旧正确。CAP理论从出现到被证明,再到饱受质疑和重新定义,我们应该如何看待它呢?首先肯定的是,CAP理论并不是神话,它并不适合再作为一个适应任何场景的定理,它的正确性更加适合基于原子读写的NoSQL场景。其次,无论如何C、A、P这三个概念始终存在于任何分布式系统,只是不同的模型会对其有不同的呈现,可能某些场景对三者之间的关系敏感,而另一些不敏感。最后,作为开发者,一方面不要将精力浪费在如何设计能满足三者的完美分布式系统,而是应该进行取舍。另一方面,分布式系统还有很多特性,如优雅降级、流量控制等,都是需要考虑的问题,而不仅是CAP三者。

3.5.3 Hadoop数据仓库工具

通过前面的描述可知,当数据仓库应用的规模和数据量大到一定程度,关系数据库已经不再适用,此时Hadoop是开发数据仓库项目的可选方案之一。然而Hadoop及其生态圈工具所提供的功能,能否满足我们方便、高效地开发数据仓库的要求呢?回忆一下图1-1所示的数据仓库架构,一个常规数据仓库由两类存储和6个主要功能模块组成。下面我们就介绍与这8个部分对应的Hadoop相关组件或产品。

1. RDS和TDS

RDS是原始数据存储,其数据是从操作型系统抽取而来。它有两个作用,一是充当操作型系统和数据仓库之间的过渡区,二是作为细节数据查询的数据源。TDS是转换后的数据存储,也就是数据仓库,用于后续的多维分析或即席查询。

这两类数据逻辑上分开,物理上可以通过在Hive上建立两个不同的数据库来实现,最终所有数据都被分布存储到HDFS上。

2.抽取过程

这里的抽取过程指的是把数据从操作型数据源抽取到RDS的过程,这个过程可能会有一些数据集成的操作,但不会做数据转换、清洗、格式化等工作。

Hadoop生态圈中的主要数据摄取工具是Sqoop和Flume。Sqoop被设计成支持在关系数据库和Hadoop之间传输数据,而Flume被设计成基于流的数据捕获,主要是从日志文件中获取数据。使用这两个工具可以完成数据仓库的抽取。在第7章中将详细介绍使用Sqoop抽取数据的实现过程。

如果数据源是普通的文本和CSV文件,抽取过程将更加简单,只需用操作系统的scp或ftp命令将文件拉取到Hadoop集群的任一节点,然后使用HDFS的put命令将已在本地的文件上传到HDFS,或者使用Hive的load data将文件装载进表里就可以了。

3.转换与装载过程

转换与装载过程是将数据从RDS迁移到TDS的过程,期间会对数据进行一系列的转换和处理。经过了数据抽取步骤,此时数据已经在Hive表中了,因此Hive可以用于转换和装载。

Hive实际上是在MapReduce之上封装了一层SQL解释器,这样可以用类SQL语言书写复杂的MapReduce作业。Hive不但提供了丰富的数据查询功能和分析函数,还可以在某些限制下进行数据的行级更新,因此支持SCD1(渐变维的一种处理类型)。在第8章中将详细介绍如何使用Hive进行数据的转换与装载。

4.过程管理和自动化调度

ETL过程自动化是数据仓库成功的重要衡量标准,也是系统易用性的关键。

Hadoop生态圈中的主要管理工具是Falcon。Falcon把自己看作是数据治理工具,能让用户建立定义好的ETL流水线。除Falcon外,还有一个叫做Oozie的工具,它是一个Hadoop的工作流调度系统,可以使用它将ETL过程封装进工作流自动执行。在第9章中将详细介绍如何使用Oozie实现定期自动执行ETL作业。

5.数据目录

数据目录存储的是数据仓库的元数据,主要是描述数据属性的信息,用来支持如指示存储位置、历史数据、资源查找、文件记录等功能。

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

HCatalog默认支持多种文件格式的读写,如RCFile、SequenceFiles、ORC files、text files、CSV、JSON等。

6.查询引擎和SQL层

查询引擎和SQL层主要的职责是查询和分析数据仓库里的数据。由于最终用户经常需要进行交互式的即席查询,并随时动态改变和组合他们的查询条件,因此要求查询引擎具有很高的查询性能和较短的响应时间。

Hadoop生态圈中的主要SQL查询引擎有基于MapReduce的Hive、基于RDD的SparkSQL和Cloudera公司的Impala。Hive可以在四种主流计算框架的三种,分别是Tez、MapReduce和Spark(还有一种是Storm)上执行类SQL查询。SparkSQL是Hadoop中另一个著名的SQL引擎,它实际上是一个Scala程序语言的子集。正如SparkSQL这个名字所暗示的,它以Spark作为底层计算框架。Impala是Cloudera公司的查询系统,它提供SQL语义,最大特点是速度快,主要用于OLAP。在第12章中将详细介绍用这几种SQL引擎进行数据分析,并对比它们的性能差异。除此之外,第12章中还会简单描述一款名为Kylin的OLAP系统,它是首个中国团队开发的Apache顶级项目,其查询性能表现优异。

7.用户界面

数据分析的结果最终要以业务语言和形象化的方式展现给用户,只有这样才能取得用户对数据仓库的认可和信任。因此具有良好体验的用户界面是必不可少的。数据仓库的最终用户界面通常是一个BI仪表盘或类似的一个数据可视化工具提供的浏览器页面。

Hadoop生态圈中比较知名的数据可视化工具是Hue和Zeppelin。Hue是一个开源的Hadoop UI系统,最早是由Cloudera Desktop演化而来,它是基于Python Web框架Django实现的。通过使用Hue我们可以在浏览器端的Web控制台上与Hadoop集群进行交互来分析处理数据,还可以用图形化的方式定义工作流。Hue默认支持的数据源有Hive和Impala。Zeppelin提供了Web版的notebook,用于做数据分析和可视化。Zeppelin默认只支持SparkSQL。

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