大数据查询利器 Hive 03:Hadoop 及 Hive 环境介绍

Posted by YEY on August 7, 2021

本节中我们将介绍 Hadoop 及 Hive 环境。首先,在 Hadoop 环境中,我们将主要介绍:

  1. 分布式文件系统 (HDFS):它解决的是传统数据库所面临的海量数据存储问题,其采用分布式文件存储,即将文件切分为多份并备份存储在 Hadoop 集群中的不同机器上;
  2. 分布式计算 (MapReduce):它解决的是传统数据库所面临的海量数据时计算处理能力不足的问题。实际上,Hadoop 中有两种分布式计算:MapReduce 和 Spark,而我们所要学习的 Hive 是基于 MapReduce 的;
  3. 数据仓库工具 (Hive):它能够使我们更简便地访问 HDFS 中的文件;
  4. 数据仓库分层:与其他主流数据仓库一样,Hive 采用分层设计。

然后,我们将介绍 Hue 环境,包括 Hue 能做什么,它是如何建数据库、建表以及上传文件等。

1. Hadoop 知识图谱

接下来我们来看一下 Hadoop 介绍的知识图谱:

1.1 分布式存储(HDFS)

首先,我们来看一下 HDFS 的作用:

  • 文件切分 为固定大小,这里我们使用的是 Hadoop 2.0 以上版本并且一般参数采用默认值,切分的单个文件块(Block)大小为 128MB。例如,我们有一个文件 a.txt,其大小为 129MB,HDFS 会将其切分为大小为 128MB 和 1MB 的两个块。
  • 然后,HDFS 会将切分后的块 备份存储 到集群中的多台服务器上,按照默认值设置每个块将存储 3 份,而其副本存放策略会将相同文件块的多个备份分别存放在不同的机架上(每台机架上有多台服务器,如果只有一台机架则会分散存储在该机架的不同服务器上)。而这里的备份存储实际上就是一种安全模式,即当某台服务器宕机时不会影响文件的读取。
  • 另外,HDFS 还对外提供 统一接口 进行文件操作,也就是说虽然内部存在多个分块备份,但是外部用户能看到的就是 a.txt 这一个文件。

那么,HDFS 的这种分布式存储功能是如何实现的呢?

这是因为 HDFS 具有相应的基本组件:

  • NameNode 用于进行元数据管理,包括文件大小、属性、权限等;
  • DataNode 存储数据块,它具有心跳机制,即每几分钟就将自己的生存状态发送给 NameNode,如果其存在数据获取需求就可以到处于存活状态的 DataNode 上进行数据读取;
  • SecondaryNameNode 作为 NameNode 的备份,两者之间会相差一段时间间隔,如果 NameNode 损坏它可以帮助快速恢复数据(尽管可能会损失一部分数据)。

另外,HDFS 中还具有四大机制来支撑分布式存储的实现:

  • 心跳机制:即上面提到的 DataNode 会告知 NameNode 其生存状态;
  • 安全模式:无论是 NameNode 还是 DateNode 都需要进行备份,分别对应 SecondaryNameNode 和文件分块备份;
  • 副本存放策略:为了安全,相同的文件块不会存储在同一个机架或者服务器上;
  • 负载均衡:将所有数据块分散存放在多台服务器上,保证各服务器的容量和负载保持一致。

1.2 分布式计算(MapReduce)

Hadoop 中有两种分布式计算:MapReduce 和 Spark,而我们所要学习的 Hive 是基于 MapReduce 的。

回到我们刚才的 a.txt 文件的例子,HDFS 将其切分为了两个数据块,大小分别为 128MB 和 1MB,假设现在我们需要统计 a.txt 文件中各单词的数量,由于两个文件块分布在不同的 DataNode 上,因此两个块上的查找统计过程是并行的,之后再通过另外一台机器对两者的结果进行整合,这就是所谓的 分治策略

MapReduce 遵循 计算向数据靠拢的理念。对于 Windows 这类操作系统,通常是将数据文件读取到内存中进行操作,然后通过 Python 等程序对数据进行操作处理,这种数据向计算靠拢的做法弊端在于内存容量通常是非常有限的,对于海量数据文件的处理比较困难。MapReduce 采用的是计算向数据靠拢,无需将数据拿过来,只需要把统计单词数量的程序分发给不同数据块所在的 DataNode 即可。

另外,MapReduce 是基于 主从机制,它需要每台 DataNode 服务器在处理数据的过程当中要和分发任务的作业控制器进行基于心跳机制的沟通,告知其当前处理状态和进度。这样才能实现数据回收和监控任务进度,如果再来一个新任务要求对 b.txt 文件进行单词数量统计,而之前的 a.txt 统计任务还在进行中,则会安排给其他服务器进行统计计算。因此,通过这种任务调度机制,MapReduce 也在一定程度上实现了负载均衡。

1.3 数据仓库工具(Hive)

接下来我们看一下数据仓库工具 Hive。注意 Hive 在这里只是数仓工具而非数据仓库本身,类似 Navicat 连接 MySQL,真正工作的是 MySQL,Navicat 只是提供了一个工作界面。

首先,Hive 本身并不存储数据,而是依赖于 HDFS 存储的数据。然后,Hive 本身也不处理数据,而是依赖 MapReduce 处理数据,Hive 会将相应的类 SQL 语句(HQL)翻译给 MapReduce 执行。Hive 中唯一存储的是元数据,而这些元数据实际上存储了 Hive 中的表与 HDFS 中的文件之间的映射关系。这些元数据又可以分为 Derby 和 MySQL 两个版本,通常企业中使用的多为 MySQL 版本。

Hive 中的数据模型主要有 4 种:

  • 表 - 分区
  • 表 - 分区 - 分桶
  • 表 - 分桶

1.4 Hue 介绍

最后,我们将介绍如何通过 Hue 连接 Hive 服务器,以及如何使用 Hue 创建数据库、数据表、编写 HQL 查询语句。

2. Hadoop 集群环境

本节中我们将介绍 分布式文件系统(HDFS)分布式计算(MapReduce)

2.1 分布式文件系统(HDFS)

现在企业环境中,单机容量无法存储大量数据,需要跨机器(集群)存储,而统一管理分布在集群上的文件系统称之为 分布式文件系统

HDFS(Hadoop Distributed File System)是 Hadoop 项目的子项目,使用多台计算机存储文件,并且提供 统一的访问接口(NameNode),用户可以像访问一个普通文件系统一样使用分布式文件系统。NameNode 中存储元数据,当 HDFS Client 发出一个请求之后,NameNode 会映射到相应的 DataNode 上进行文件块的存取,默认单个文件块大小为 128MB,每块备份 3 份。

HDFS 基本组件:

  • HDFS Client : 提供命令管理
  • HDFS NameNode:管理整个文件系统的元数据 ,工作职责:管理元数据、维护目录结构、响应客户端请求
  • DataNode:复制管理用户的文件数据块,工作职责:管理用户提交的数据、心跳机制、块报告
  • SecondaryNameNode:NameNode 的助理,帮助加载元数据,紧急情况下(例如 NameNode 宕机)可以帮助恢复数据

HDFS四大机制:

  • 心跳机制

    • Master/Slave 结构,Master 是 NameNode,Slave 是 DataNode

    • 默认 DataNode 向 NameNode 发送请求的时间间隔为 3s

    • 默认 NameNode 向 DataNode 发送请求的时间间隔为 5min

    • NameNoder 如果长时间没有接收到 DataNode 的心跳,也会每隔一段时间(5min)向 DataNode 发送请求,一共会发两次。

  • 安全模式
    • HDFS 集群正常冷启动时,NameNode 也会在 safemode 状态下维持相当长一段时间,等待它自动退出安全模式即可。
  • 副本存放策略
    • 将每个文件的数据进行分块存储,每一个数据块有保存有多个副本,这些数据块副本分布在不同的机器节点上。
  • 负载均衡
    • 机器容量最高的那个值和最低的那个值差距不能超过 10%

2.2 分布式计算(MapReduce)

分布式计算(MapReduce):

  • MapReduce 是一种分布式并行编程框架
  • MapReduce 策略:分而治之
  • MapReduce 理念:计算向数据靠拢而不是数据向计算靠拢

2.2.1 例子:单词计数

这里我们以统计单词数量为例来看一下 MapReduce 的处理过程:

假设输入数据中的每一行都是一个文件块,比如这里有 3 个文件块,大小分别为 128MB、128MB、80MB。然后,MapReduce 会对每一个文件块分别进行单词计数处理。在处理过程中,有时可能存在内存容量不足的情况,所以当处理数据达到一定量的时候就写出到磁盘中,这被称为 溢写。之后,就按照单词将计数结果放到一起,再进行 Reduce 汇总统计,统计完成后再放到一起输出最终结果。

2.2.2 MapReduce 体系架构

MapReduce 采用 主从(Master/Slave)架构

  • Client
    • 通过 Client(客户端)可以提交用户编写的应用程序
    • 用户通过它将应用程序提交到 JobTracker 端
    • 用户也可以通过 Client 提供的一些接口去查看当前提交作业的运行状态
  • JobTracker
    • 负责资源的监控和作业的调度
    • 监控底层的其他的 TaskTracker 以及当前运行的 Job 的健康状况
    • 一旦探测到失败的情况就把这个任务转移到其它节点继续执行跟踪任务执行进度和资源使用量
  • TaskTracker
    • 执行具体的相关任务,一般接受 Job Tracker 发送过来的命令(如启动新任务、杀死任务等)
    • 把一些自己的资源使用情况以及任务运行进度通过心跳(Heartbeat)方式发送给 JobTracker
  • Task
    • 分为 MapTask 和 Reduce Task 两种,均由 TaskTracker 启动
    • HDFS 以固定大小的 Block 为基本单位存储数据,而 MapReduce 以 Split 为基本单位处理数据。Split 的划分方法完全由用户自己决定
    • 注意,Split 的多少决定了 MapTask 的数目,因为 每一个 Split 只会交给一个 MapTask 处理

Split 与 Block 的关系图如下:

可以看到,HDFS 将文件分成了 5 个 Block,并且分别备份存储在 5 台 DataNode 服务器上。如果我们想查找该文件,可以按照负载均衡策略分别从这些 DataNode 中获取(例如图中红色虚线所示)。我们可以直接按照 Block 的切分方式进行处理,也可以按照需求重新切分 Split 进行处理,这样就我们完成了 Map 的部分。

2.2.3 MapReduce 工作流程

接下来我们来看一下 MapReduce 的工作流程:

切分后的每个 Split 发送给一个 Map 任务,然后这里我们设置了两个 Reduce 任务对 Map 结果进行整合,得到两个输出文件。当然,我们也可以只设置一个 Reduce 输出。

2.3 数据仓库工具(Hive)

2.3.1 Hive 简介

Hive 是 Facebook 为了解决海量日志数据的统计分析而开发的一个基于 Hadoop 的 数据仓库工具(后来开源给了 Apache 软件基金会),它可以将 结构化 的数据文件映射为一张数据库表,并提供类 SQL 查询功能的 HQL。

Hive 特点:

  • Hive 本身并不支持数据存储和处理,只是一个面向用户的编程接口
  • Hive 依赖分布式文件系统 HDFS 存储数据

  • Hive 依赖分布式并行计算模型 MapReduce 处理数据
  • 借鉴 SQL 语言设计了新的查询语言 HiveQL

2.3.2 HQL 转换为 MapReduce 的原理

假如我们有两张表:

(1) 直接抽取

语句 1:

1
SELECT uid, gender FROM User;

语句 2:

1
2
3
SELECT uid, gender
FROM User 
WHERE gender = '1';

(2) GROUP BY

语句 3:

1
2
3
SELECT COUNT(uid) AS uv, item_id
FROM Order
GROUP BY item_id;

语句 4:

1
2
3
SELECT COUNT(DISTINCT uid) AS uv, item_id
FROM Order
GROUP BY item_id;

(3) JOIN

语句 5:

1
2
3
SELECT SUM(price) AS u_price, gender
FROM User a JOIN Order b ON a.uid = b.uid 
GROUP BY gender;

我们之后会学习 HQL 语句的优化。通常来说,使用 JOIN 时我们将较小的表放在左侧,它会加载到内存当中,速度会提高。另外,Hive 中的表模型是可以分桶的,如果这里 Uer 表和 Order 表都以 uid 字段进行了分桶(基于哈希值计算原理),就可以直接对分桶进行关联,这样可以大大提升 JOIN 速度,这也是 Hive 中分桶的主要作用。

这里我们没有进行分桶,因此在使用 JOIN 关联时,会将 User 表的每个块(一共 3 个块)与 Order 表的所有块(一共 3 个块)进行匹配(黄色虚线框),得到 3 个关联表(绿色虚线框),然后再对每个关联后的表按 gender 字段进行 GROUP BY 分组,最后 Reduce 整合结果并输出。也就是说,当我们没有进行分桶的时候,我们需要用 Order 表中所有的块与 User 表中的每一个块进行关联,速度方面就相对较慢。

2.4 数据仓库分层

现在我们来看一下数仓分层,它是数据库设计中一个非常重要的环节,一个好的数仓分层设计能够让整个数据体系更容易理解和使用,对于新入职的数据分析和数据开发人员也更加友好。

2.4.1 数仓分层的好处

  • 清晰数据结构:每一个数据分层都有它的作用域和职责,在使用表的时候能更方便地定位和理解。
  • 减少重复开发:规范数据分层,开发一些通用的中间层数据,能够减少极大的重复计算。
  • 统一数据口径:通过数据分层,提供统一的数据出口,统一对外输出的数据口径。
  • 复杂问题简单化:将一个复杂的任务分解成多个步骤来完成,每一层解决特定的问题。

首先是清晰数据结构,每个数据层都有各自的作用域和职责。例如:某层只负责统计每日数据、另外一层只负责统计每周数据(由于周实际上是对日的统计,因此该层在之前那层的上面)、可视化层则只负责最终指标展示等。通过数据分层,对于入职不同部门的员工,只需要向其开放相应数据层的权限即可。

另外一点就是可以减少重复性开发,数据仓库实际上是用空间换时间。也就是说,我们有很多集群,并且目前的硬件设备价格非常便宜,如果想存储更多数据,只需要购买更多的服务器来构建一个更大的集群即可,主要目的还是节省时间,所以可能会存在很多中间层。例如,为了各种应用而设计的很多中间层(即大宽表),我们可以制作不同的大宽表分别给到不同的应用使用(日报、周报、可视化等)。当我们在这些宽表中存好数据后,就不用每次进行可视化或者制作日报时都重新进行表关联和中间层运算,从而减少了重复性开发。

然后是统一数据口径,其实我们在中间层上进行汇总时,整个汇总计算是为了输出一些指标,如果我们将这些都已经组织好了并放在某个层上,那以后需要时就可以直接使用,因为它会在固定的时间点计算这些指标。因此,这些数据口径并不是每个人都有权限更改的,对于应用层的人员只负责从数据仓库中提取数据。注意,这里的数仓不是指底层数仓,而是某个已经架到高层的数仓,即底层原始数据存储和中间层的开发等都已经完成了,只剩下应用,并且各项应用指标都已经计算好了,所以这种情况下可以有效保证输出数据口径统一。

最后,分层可以将复杂问题简单化。也就是说,一个复杂问题在通过分步拆解的过程中已经完成了很大一部分工作。例如,我们在学习 MySQL 的时候写过很多子查询,如果进行数仓分层后,我们就不需要子查询了,而是可以第一层就对应最内层查询、第二层对应外面一层查询、第三层对应更外面一层查询……这样到应用层可能直接使用 SELECT * FROM 某个表名 就可以了,因为这些数据层实际上已经完成了前面那些子查询步骤。这就将复杂问题简单化了,即每一层都解决了一些特定的问题,到最后一层直接使用即可。因此,有些同学入职某些部门的数据分析岗位后,可能只需要使用一些的针对该部门的特定数据,而如果公司内部数仓分层架构已经搭建好了,这种情况下可能会发现平时工作使用的 SQL 语句都相对比较简单,这就是数仓分层的好处。

2.4.2 通用的数据分层设计

一般可以将数据仓库分为 4 层:

  1. 数据运营层 (ODS):存储的原始业务数据例,便于回溯。例如,将 MySQL/Oracle/SQL Server 中存储的原始业务数据表直接拷贝一份到 ODS 层,这样做的目的是当某天发现问题时或者需要开展新的事务/分析专题的时候,可能需要基于原始数据重新搭建一些东西,因此我们需要保留原始数据。这也对应了我们前面提到的数据仓库的原则:利用空间置换时间,即使再备份一个 ODS 也没关系,因为目前硬件价格比较低廉。

  2. 数据仓库层 (DW):按照分析主题或者部门进行划分,可以细分为明细层(DWD)和服务层(DWS)。

    • 数据明细层 (DWD):DWD 层对维度进行了退化, 即当前分析主题下不会用到的一些列(例如注释等)可以移除。另外一点就是将字段由编码还原到内容,例如订单表中的 “地区” 字段存储的是每个地区的 ID,而在地区表中这些 ID 都有对应的城市名,因此在 DWD 中就会将这些城市名还原到订单表中,这样就不需要地区表这张字典表了。这里同样体现了 “空间换时间” 的原则。
    • 数据服务层 (DWS):在 DWD 层完成维度退化后,DWS 层会按照业务将数据进行汇总计算,整合成宽表。例如,汇总统计每人每天访问多少次、 每人每天完成了多少订单等,然后在此基础上我们还可以统计每人每周、每人每月、每人每季度、每人每年的情况,这样一层层向外扩展,实现对数据的一个轻度汇总。
  3. 数据应用层 (APP):针对汇总好的数据,可能再进行部分简单计算后就能够投入业务中使用了。

  4. 维表层 (DIM):维表层主要包含两部分数据:

    • 高基数维度数据:一般是用户资料表、商品资料表类似的资料表。数据量可能是千万级或者上亿级别。
    • 低基数维度数据:一般是配置表,比如枚举值的中文含义(即字典表),或者日期维表。数据量可能是个位数或者几千几万。

    维表层可以单独构建一层,也可以在一开始存放在 ODS 层,然后在 DWD 中进行维度退化时移除掉即可。为了便于数据回溯,一般我们将维表层直接放在 ODS 层的原始数据里。通常,低基数维表的数据量并不是很大,不会影响速度。

2.4.3 例子:电商网站数仓分层设计

我们来看一个数仓分层的例子,看一下电商网站是如何设计数据分层体系的。这里我们暂且只关注用户访问行为及用户信息、商品信息等部分数据。

首先,看一下最底部的 ODS 层,它是直接将原始数据拿过来存储,例如:PC 网页/APP 的访问日志、一些高维表(商品信息表、用户信息表等)、订单表(包含下单用户 ID、订单金额、快递方式等信息)、订单明细表(包含订单中的各商品详情、是否打折等信息)。

将原始数据都存入 ODS 层之后,我们就进入 DWD 层,它主要完成两件事:1. 维度退化(减少低维表);2. 针对分析主题进行轻度数据汇总。具体来说,对于用户访问日志表:1. 去掉无用信息(例如网址等);2. 包含各种数据源的数据(例如其他业务的数据信息);3. 对部分枚举类型的值进行翻译(维度退化)。

之后是 DWS 层,该层针对分析主题进行轻度汇总。例如提供基于时间维度(日、周、月、年等)的汇总。或者,我们可以计算更多的指标,正如之前提到的数据分层可以减少重复开发、统一数据口径,这里我们可以统计一些汇总指标(例如登录次数、购买次数等)。

在完成汇总统计后,我们就可以在 APP 层对这些汇总数据进行应用,例如商品品类销售日报、周报等。 或者针对不同渠道的转化、留存分析(需要在 DWS 层按渠道进行汇总)。

以上就是针对电商网站的一个比较抽象的数仓分层设计。下面我们来看一下更加具体的用户行为日志代码分层:

通常,事务数据库对这类日志是不入库的,也就是说,我们不会将其存储进 MySQL/Oreacle 等数据库中,而是写入一个文本文件(例如 JSON 格式)。首先,ODS 层存储该日志的原始 JSON 文件。然后,DWD 层会将原始 JSON 文件按字段解析成日志表形式(例如设备 id、区域、用户 id、APP 版本等)。然后,DWS 层就可以统计用户的日活跃明细(例如登录次数、浏览商品数、搜索次数、搜索关键字等),做一个轻度汇总。然后在用户日汇总的基础上,我们还可以进行周汇总、月汇总等。 最后,在应用层我们就可以统计每日活跃用户数等指标。如果我们还想统计新增用户、沉默用户等指标,就需要在 DWS 层再添加一些相关的汇总项。这里,由于这里 ODS 层只取了日志,所以如果想统计新增用户指标,还需要存储用户表、注册表等,或者日志本身已经存储了相关信息。总之,我们需要根据存储的数据进行汇总,然后再对这些汇总数据进行应用。以上就是针对用户行为的数据分层。

3. Hue 环境介绍

3.1 Apache Hue 介绍

3.1.1 Hue是什么

HUE(Hadoop User Experience)是一个开源的 Apache Hadoop UI 系统,由 Cloudera Desktop 演化而来,最后 Cloudera 公司将其贡献给 Apache 基金会的 Hadoop 社区,它是基于 Python Web 框架 Django 实现的。

类似于 MySQL,如果没有 Hue 环境,我们也能在终端/命令行中运行 HQL 语句:

1
2
mysql> SHOW DATABASES;
hive> SHOW DATABASES;

但是,这种方式不太直观,而且 Hadoop 环境是部署在 Linux 上的,我们还需要掌握一些常用的 Linux 命令。

如果我们不希望在终端/命令行环境下编写 HQL 语句,可以使用 Hue,它可以让我们 在浏览器端的 Web 控制台上与 Hadoop 集群进行交互,来分析处理数据,例如操作 HDFS 上的数据、运行 MapReduce Job、执行 Hive 的 HQL 语句、浏览 HBase 数据库等等

3.1.2 Hue 能做什么

  • 访问 HDFS 和文件浏览

  • 通过 Web 调试和开发 Hive 以及数据结果展示

  • 通过 Web 调试和开发 Impala 交互式 SQL Query
  • Spark 调试和开发
  • Pig 开发和调试
  • HBase 数据查询和修改,数据展示
  • Hive 的元数据(metastore)查询
  • MapReduce 任务进度查看,日志追踪
  • 创建和提交 MapReduce、Streaming、Java job 任务
  • Sqoop2 的开发和调试
  • Zookeeper 的浏览和编辑
  • 数据库(MySQL、PostGres、SQlite、Oracle)的查询和展示

3.2 Apache Hue 界面应用

输入配置的 Hue 网址:http://113.31.147.119:8888/

输入用户名密码后进入 Hue 主界面,点击 Query 下拉按钮,选择 Editor 下的 Hive 选项,进入 Hive。

切换数据库:可以使用 USE 数据库名,也可以点击左侧数据库图标旁的 < 箭头在数据库列表中选择,或者在 HQL 语句编辑区域左上方的 Database 下拉列表中选择。

上传文件进行数据装载:点击左侧文件 Files 图标进入文件管理界面。

注意:文件一旦被 load 到数据库的表中,文件将被移动到相应表的目录下。

点击任意文件,可以对当前文件进行查看或下载。

4. 知识总结

  1. Hadoop 核心分布式存储 + 分布式计算:
    • 分布式存储(HDFS):Hadoop.2X 默认块大小 128MB,备份数 3
    • 分布式计算 MapReduce(分而治之,分而后和)
  2. Hive 数仓工具的特点:
    • 基于 HDFS 存储数据
    • 基于 MapReduce 处理数据
    • 类 SQL 语句 HQL
    • 只负责管理 Hive 元数据(Hive 表与 HDFS 文件的映射关系,元数据的存储是借助于 MySQL)
  3. 数据分层存储作用:
    • 区域化管理
    • 数据体系结构清晰
    • 指标口径统一
    • 避免重复计算
    • 复杂问题简单化
  4. 通过 Hue 访问操作数据库:
    • 数据库菜单
    • 文件菜单
知识共享许可协议本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 欢迎转载,并请注明来自:YEY 的博客 同时保持文章内容的完整和以上声明信息!