5、Hive 数据仓库技术

一、Hive 概念

Hive 是基于 Hadoop 的数据仓库软件,可以查询和管理 PB 级别的分布式数据。数据仓库已用多种方式定义,很难给出一种严格的定义。宽泛来讲,数据仓库是一种数据库,他与单位的操作数据库分别维护。数据仓库系统允许将各种应用系统集成在一起,为统一的历史数据分析提供坚实的平台,对信息处理提供支持。数据仓库是一个面向主题的、集成的、时变的、非易失的数据集合,支持管理者的决策过程。

面向主题的:数据仓库围绕一些重要主题,如顾客、供应商、产品和销售组织等。数据仓库关注决策者的数据建模与分析,而不是单位的日常操作和事务处理。因此,数据仓库通常排除对于决策无用的数据,提供特定主题的简明视图。

集成的:通常,构造数据仓库是将多个异构数据源,如关系型数据库、一般文件和联机事务处理记录集成在一起。使用数据清理和数据集成技术,确保命名约定、编码结构、属性度量等的一致性。

时变的:数据存储从历史的角度提供信息。数据仓库中的关键结构都隐式或显式的包含时间元素。

非易失的:数据仓库总是物理的分离存放数据,这些数据源于操作环境下的应用数据。由于这种分离,数据仓库不需要事务处理、恢复和并发控制机制。通常,他只需要两种数据访问操作:数据的初始化装入和数据访问。

相比于传统数据库,数据仓库可以提供对于异构多源数据库的支持,他更关注的是哪些数据是挖掘需要的,这些数据都是显隐或带有时间属性的,而且基于 Hadoop 理论,他们都认为硬件是不可靠的

 

Hive 是构建在 Hadoop 上的数据仓库软件框架,支持使用 SQL 来读,写和管理大规模数据集合。Hive 入门非常简单,功能非常强大,所以非常流行.通常来说,Hive 只支持数据查询和加载,但后面的版本也支持了插入,更新和删除以及流式 api。Hive 具有目前 Hadoop 上最丰富最全的 SQL 语法,也拥有最慢最稳定的执行。是目前 Hadoop 上几乎标准的 ETL 和数据仓库工具。Hive 这个特点与其它 AdHoc 查询工具如 Impala,Spark SQL 或者 Presto 有着应用场景的区别,也就是虽然都是即席查询工具,前者适用与稳定作业执行,调度以及 ETL,或者更倾向于交户式。一个典型的场景是分析师使用 Impala 去探测数据,验证想法,并把数据产品部署在 Hive 上执行。在我们讲 Hive 原理和查询优化前,让我们先回顾一下 Hadoop 基本原理。

 

Hadoop 是一个分布式系统,有 HDFS 和 Yarn。HDFS 用于执行存储,Yarn 用于资源调度和计算。MapReduce 是跑在 Yarn 上的一种计算作业,此外还有 Spark 等。 Hive 通常意义上来说,是把一个 SQL 转化成一个分布式作业,如 MapReduce, Spark 或者 Tez。无论 Hive 的底层执行框架是 MapReduce、Spark 还是 Tez,其原理基本都类似。而目前,由于 MapReduce 稳定,容错性好,大量数据情况下使用磁盘,能处理的数据量大,所以目前 Hive 的主流执行框架是 MapReduce,但性能相比 Spark 和 Tez 也就较低,等下讲到 Group By 和 JOIN 原理时会解释这方面的原因。目前的 Hive 除了支持在 MapReduce 上执行,还支持在 Spark 和 Tez 上执行。我们以 MapReduce 为例来说明的 Hive 的原理。先回顾一下 MapReduce 原理。

两个 Mapper 各自输入一块数据,由键值对构成,对它进行加工(加上了个字符n),然后按加工后的数据的键进行分组,相同的键到相同的机器。这样的话,第一台机器分到了键 nk1 和 nk3,第二台机器分到了键 nk2。接下来再在这些 Reducers 上执行聚合操作(这里执行的是是 count),输出就是 nk1 出现了 2 次,nk3 出现了 1 次,nk2 出现了 3 次。从全局上来看,MapReduce 就是一个分布式的 GroupBy 的过程。从上图可以看到,Global Shuffle 左边,两台机器执行的是 Map。Global Shuffle 右边,两台机器执行的是 Reduce。所以 Hive,实际上就是一个编译器,一个翻译机。把 SQL 翻译成 MapReduce 之类的作业。

它提供了如下功能:

(1)灵活方便的 ETL(extract/transform/load)

我们可以将数据仓库理解成为是一个多数据库数据的集合体,本身来说,数据库是面向于业务的,数据仓库就像上面所说,是面向于主题的,比如今天作为作为一个数据分析员,他关注的就不再是业务人员关注的问题了,而是属性维度对于整体的影响。关于这些问题,我们已经在 Hbase 中详细赘述了,这里就不在多说。数据仓库其实我们可以将其认为是一个大型的数据库,只是这个数据库不是给业 务人员用的,是给分析师使用的。作为分析师,我们更关注的是数据的完整度和 全面性,另外关注的就是这个数据是否是干净的,所谓干净就是指这个数据是不 是存在一些干扰或者是问题的。就好比我们去买菜,回家之后也肯定不会直接就 炒菜了,需要经过洗菜切菜的步骤。这就和数据仓库的工作很类似,数据仓库中 的数据是直接供给做数据分析使用的,所以数据仓库需要将数据收集集成到本地, 并且对数据进行预处理操作,排除掉数据中的一些分析无关的数据以及一些会分 析准确度产生影响的数据。那么为了实现数据的集成,我们就需要从各个位置收 集并且存储数据,并且对原始数据进行预处理。关于数据的预处理操作的步骤详 见第一章大数据基本概念那么我们实现了数据的加载和转换,其实这些相关的操作都依托于,我们要有足够多类型的相关接口,由于数据仓库中的数据并非是自己产生的,就像菜市场的菜不是在菜市场种出来的一样,我们需要从各种类型的数据库中将数据下载到本地。这个时候,我们就需要针对不同类型的数据库提供连接支持,所以接口作为一个很重要的部分也被加入到了数据仓库中。数据仓库有了接口和多数据类型的支持之后,下一个需要解决的问题就是如何保证数据成功导入,针对于大量数据的导入也是一个问题,如何让大量数据尽快导入数据仓库目前有两种方式解决,第一个数据仓库本身需要能够承载海量数据的导入压力,另外一个就是外部程序实现,比如 GDS 等。

(2)多种文件格式的元数据服务数据仓库集成了文件之后,另外一个问题就是如何对这些文件进行读取,我们之前也说过目前的数据类型非常多,结构化、非结构化、半结构化数据类型广泛,那么这些文件被数据仓库集成之后,如何能够正常的被读取,这就需要数据仓库支持相关的元数据,对各种类型的数据都能够支持访问。

(3)直接访问 HDFS 文件以及 Hbase 数据在进行集成的时候,由于 HIVE 是搭载在 Hadoop 上的,本身各个组件之间就可以进行交流,如果还需要通过其他组件做转换还会导致整体进程延迟过高,所以 Hive 支持直接读取 HDFS 和 Hbase 中的文件,降低整体数据集成延迟。

(4)支持 MapReduce,Tez,Spark 等多种计算引擎数据仓库的出现并不是为了数据的存储,而是为了更好的进行分析计算,而且我们对于不同类型的数据也有对应类型的计算引擎去做相关的分析操作,所以 Hive 对于计算引擎的支持度也应该足够大,才能满足业务的需求。

二、Hive 优缺点

优点:

(1) Hive 具有高可靠性和高容错性,采用集群模式保障可靠性,元数据节点同时也采用主备保障,并且在连接超时之后提供重试机制。

(2) 通过类 SQL 语法,易于维护。

(3) 通过自定义的存储格式和函数,可以提供高拓展性。

(4) 对外提供多接口,可以使用户通过多种模式调用。

缺点:

(1) 由于 Hive 默认使用 MapReduce 作为计算引擎,作为离线计算工具,MapReduce 的延迟较高。

(2) 虽然 Hive 提供了视图的概念,但是还是不支持在视图上进行操作。不支持列级别的增删改操作(3) 当前版本还不能支持存储过程,只能通过 UDF 来实现一些逻辑处理

三、Hive 和传统数据仓库比较

四、Hive 架构

Hive 分为三个角色 HiveServer、MetaStore、WebHcat。

(1) HiveServer 将用户提交的 HQL 语句进行编译,解析成对应的 Yarn 任务、Spark 任务或者 HDFS 操作,从而完成数据的提取、转换、分析。

(2) MetaStore 提供元数据服务。

(3) WebHcat 对外提供基于 https 协议的元数据访问、DDL 查询等服务。

Hive 的服务端组件

  1. Driver 组件:该组件包括:Compiler、Optimizer、Executor,它可以将 Hive的编译、解析、优化转化为  MapReduce  任务提交给  Hadoop1  中的JobTracker 或者是 Hadoop2 中的 SourceManager 来进行实际的执行相应的任务。
  2. MetaStore 组件:存储着 hive 的元数据信息,将自己的元数据存储到了关系型数据库当中,支持的数据库主要有:Mysql、Derby、支持把 metastore 独立出来放在远程的集群上面,使得 hive 更加健壮。元数据主要包括了表的名称、表的列、分区和属性、表的属性(是不是外部表等等)、表的数据所在的目录。
  3. 用户接口:CLI(Command Line Interface)(常用的接口:命令行模式)、
  4. Client:Hive 的客户端用户连接至 Hive Server ,在启动 Client 的时候,需要制定 Hive Server 所在的节点,并且在该节点上启动 Hive Server、WUI:通过浏览器的方式访问 Hive。

 

 WebHCat 提供 Rest 接口,使用户能够通过安全的 HTTPS 协议执行以下操作:执行 Hive DDL 操作;运行 Hive HQL 任务; 运行 MapReduce 任务;注:当前版本暂不提供 Pig 接口。

五、Hive 数据存储模型

数据库:创建表时如果不指定数据库,则默认为 default 数据库表:物理概念,实际对应 HDFS 上的一个目录分区:对应所在表所在目录下的一个子目录

桶:对应表或分区所在路径的一个文件倾斜数据:数据集中于个别字段值的场景,比如按照城市分区时,80%的数据都来自某个大城市正常数据:不存在倾斜的数据分区和分桶

分区:数据表可以按照某个字段的值划分分区,每个分区是一个目录,分区数量不固定,分区下可再有分区或者桶,分区可以很明显的提高查询效率桶:数据可以根据桶的方式将不同数据放入不同的桶中,每个桶是一个文件,建表时指定桶个数,桶内可排序,数据按照某个字段的值 Hash 后放入某个桶中,对于数据抽样、特定 join 的优化很有意义托管表和外部表Hive 默认创建托管表,由 Hive 来管理数据,意味着 Hive 会将数据移动到数据仓库目录。另外一种选择是创建外部表,这时 Hive 会到仓库目录以外的位置访问数据。

 

六、增强特性

(1)Colocation 同分布

 

Colocation (同分布):将存在关联关系的数据或可能要进行关联操作的数据存储在相同的存储节点上。文件级同分布实现文件的快速访问,避免了因数据搬迁带来的大量网络开销。

比如有两份数据,一份为学生表(ID, name, sex),另一份数据为成绩表(ID, subject, score),此时要查询男女生平均成绩分别为多少。这时必须对这两份数据进行关联操作(join),我们认为这两份数据具有关联关系。此时采用同分布特性可以减少数据移动等网络开销,直接在本地进行关联操作即可。

(2)HBase 记录批量删除

在 Hive on HBase 功能中,FusionInsight HD Hive 提供了对 HBase 表的单条数据的删除功能,通过特定的语法,Hive 可以将 HBase 表中符合条件的一条或者多条数据清除。如果要删除某张 HBase 表中的某些数据,可以执行 HQL 语句: remove table hbase_table where expression;其中 expression 规定要删除数据的筛选条件。(3)流控特性通过流控特性,可以实现:当前已经建立的总连接数阈值控制; 每个用户已经建立的连接数阈值控制; 单位时间内所建立的连接数阈值控制;

 

七、Hive 的作业编译

Hive 作业的执行过程实际上是 SQL 翻译成作业的过程?那么,它是怎么翻译的?

一条 SQL,进入的 Hive。经过上述的过程,其实也是一个比较典型的编译过程变成了一个作业。

(1)首先,Driver 会输入一个字符串 SQL,然后经过 Parser 变成 AST,这个变成 AST 的过程是通过 Antlr 来完成的,也就是 Anltr 根据语法文件来将 SQL 变成AST。

(2)AST 进入 SemanticAnalyzer(核心)变成 QB,也就是所谓的 QueryBlock。一个最简的查询块,通常来讲,一个 From 子句会生成一个 QB。生成 QB 是一个递归过程,生成的QB经过 GenLogicalPlan 过程,变成了一个 Operator 图,也是一个有向无环图。

(3)OPDAG 经过逻辑优化器,对这个图上的边或者结点进行调整,顺序修订,变成了一个优化后的有向无环图。这些优化过程可能包括谓词下推(PredicatePushDown),分区剪裁(PartitionPrunner),关联排序(JoinReorder)等等

(4)经过了逻辑优化,这个有向无环图还要能够执行。所以有了生成物理执行计划的过程。GenTasks。Hive 的作法通常是碰到需要分发的地方,切上一刀,生成一道 MapReduce 作业。如 GroupBy 切一刀,Join 切一刀,DistributeBy 切一刀,Distinct 切一刀。这么很多刀砍下去之后,刚才那个逻辑执行计划,也就是那个逻辑有向无环图,就被切成了很多个子图,每个子图构成一个结点。这些结点又连成了一个执行计划图,也就是 TaskTree.把这些个 TaskTree 还可以有一些优化,比如基于输入选择执行路径,增加备份作业等。进行调整。这个优化就是由 PhysicalOptimizer 来完成的。经过PhysicalOptimizer,这每一个结点就是一个 MapReduce 作业或者本地作业,就可以执行了。这就是一个 SQL 如何变成 MapReduce 作业的过程。

八、Hive 的 GroupBy 和 Join 操作实现原理

Hive 最重要的部分是 Group By 和 Join。下面分别讲解一下:首先是 Group By例如我们有一条 SQL 语句:INSERT INTO TABLE pageid_age_sum SELECT pageid, age, count(1) FROM pv_usersGROUP BY pageid, age;把每个网页的阅读数按年龄进行分组统计。由于前面介绍了,MapReduce 就是一个 Group By 的过程,这个 SQL 翻译成 MapReduce 就是相对简单的。

Hive 实现成 MapReduce 的原理如下:

 也就是说 Map 分发到 Reduce 的时候,会使用 pageid 和 userid 作为联合分发键,再去聚合(Count),输出结果。

介绍了这么多原理,重点还是为了使用,为了适应场景和业务,为了优化。从原理上可以看出,当遇到 GroupBy 的查询时,会按 GroupBy 键进行分发?如果键很多,撑爆了机器会怎么样?

对于 Spark,为了快,key 在内存中,爆是经常的。爆了就失败了。对于 Hive, Key 在硬盘,本身就比 Impala,Spark 的处理能力大上几万倍。但……不幸的是,硬盘也有可能爆。

当然,硬盘速度也比内存慢上不少,这也是 Hive 总是被吐槽的原因,场景不同,要明白自己使用的场景。当 GroupByKey 大到连硬盘都能撑爆时……这个时候可能就需要优化了。GroupBy 优化通常有 Map 端数据聚合和倾斜数据分发两种方式。也就是执行 SQL前先执行 sethive.map.aggr=true;它的原理是 Map 端在发到 Reduce 端之前先部分聚合一下。来减少数据量。因为我们刚才已经知道,聚合操作是在 Reduce 端完成的,只要能有效的减少 Reduce 端收到的数据量,就能有效的优化聚合速度,避免爆机,快速拿到结果。

另外一种方式则是针对倾斜的 key 做两道作业的聚合。什么是倾斜的数据?比如某猫双 11 交易,华为卖了 1 亿台,苹果卖了 10 万台。华为就是典型的倾斜数据了。如果要统计华为和苹果,会用两个 Reduce 作 GroupBy,一个处理 1 亿台,一个处理 10 万台,那个 1 亿台的就是倾余。由于按 key 分发,遇到倾斜数据怎么办?

 

 

可以使用 hive.groupby.skewindata 选项,通过两道 MapReduce 作业来处理。当选项设定为 true,生成的查询计划会有两个 MRJob。第一个 MRJob 中,Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 GroupByKey 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;第二个 MRJob 再根据预处理的数据结果按照 GroupByKey 分布到 Reduce 中(这个过程可以保证相同的 GroupByKey 被分布到同一个 Reduce 中),最后完成最终的聚合操作。第一道作业:Map 随机分发,按 gbykey 部分聚合第二道作业:第一道作业结果 Map 倾斜的 key 分发,按 gbkkey 进行最终聚合无论你使用 Map 端,或者两道作业。其原理都是通过部分聚合来来减少数据量。能不能部分聚合,部分聚合能不能有效减少数据量,通常与 UDAF,也就是聚合函数有关。也就是只对代数聚合函数有效,对整体聚合函数无效。所谓代数聚合函数,就是由部分结果可以汇总出整体结果的函数,如 count,sum。所谓整体聚合函数,就是无法由部分结果汇总出整体结果的函数,如 avg,mean。比如,sum,count,知道部分结果可以加和得到最终结果。而对于,mean,avg,知道部分数据的中位数或者平均数,是求不出整体数据的中位数和平均数的。在遇到复杂逻辑的时候,还是要具体问题具体分析,根据系统的原理,优化逻辑。刚才说了,Hive 最重要的是 GroupBy 和 Join,所以下面我们讲 Join.

例如这样一个查询:

INSERT INTO TABLE pv_users SELECT pv.pageid ,u.age

FROM page_viewpv JOIN user u ON (pv.userid=u.userid);

把访问和用户表进行关联,生成访问用户表。Hive 的 Join 也是通过 MapReduce 来完成的。

 就上面的查询,在MapReduce 的 Join 的实现过程如下:

 

Map 端会分别读入各个表的一部分数据,把这部分数据进行打标,例如 pv 表标

1,user 表标 2。

Map 读取是分布式进行的。标完完后分发到 Reduce 端,Reduce 端根据 JoinKey,也就是关联键进行分组。然后按打的标进行排序,也就是图上的 ShuffleSort。在每一个 Reduce 分组中,Key 为 111 的在一起,也就是一台机器上。同时,pv表的数据在这台机器的上端,user 表的数据在这台机器的下端。

这时候,Reduce 把 pv 表的数据读入到内存里,然后逐条与硬盘上 user 表的数据做 Join 就可以了。从这个实现可以看出,我们在写 HiveJoin 的时候,应该尽可能把小表(分布均匀的表)写在左边,大表(或倾斜表)写在右边。这样可以有效利用内存和硬盘的关系,增强 Hive 的处理能力。同时由于使用 JoinKey 进行分发,Hive 也只支持等值 Join,不支持非等值 Join。由于 Join 和 GroupBy 一样存在分发,所以也同样存在着倾斜的问题。所以 Join 也要对抗倾斜数据,提升查询执行性能。

Hive 从 0.14 开始支持 ACID。也就是支持了 UpdateInsertDelete 及一些流式的API。也就是这个原因,Hive 把 0.14.1BugFixes 版本改成了 Hive1.0,也就是认为功能基本稳定和健全了。由于 HDFS 是不支持本地文件更改的,同时在写的时候也不支持读。表或者分区内的数据作为基础数据。事务产生的新数据如 Insert/Update/Flume/Storm 等会存储在增量文件(DeltaFiles)中。读取这个文件的时候,通常是 TableScan 阶段,会合并更改,使读出的数据一致。HiveMetastore 上面增加若干个线程,会周期性地合并并合并删除这些增量文件。 Hive 适合做什么?由于多年积累,Hive 比较稳定,几乎是 Hadoop 上事实的 SQL 标准。Hive 适合离线 ETL,适合大数据离线 Ad-Hoc 查询。适合特大规模数据集合需要精确结果的查询。对于交互式 Ad-Hoc 查询,通常还会有别的解决方案,比如 Impala, Presto 等等。特大规模的离线数据处理,尤其是大表关联,特大规模数据聚集,很适合使用Hive。讲了这么多原理,最重要的还是应用,还是创造价值。对 Hive 来说,数据量再大,都不怕。数据倾斜,是大难题。但有很多优化方法和业务改进方法可以避过。Hive 执行稳定,函数多,扩展性强,数据吞吐量大,了解原理,有助于用好和选型。

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值