添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
docurl=/cn/Service/Document_Software/Document_Center/Big_Data/Catalog/H3C_DataEngine/H3C_DataEngine/Configure/User_Manual/Component_Manual/H3C_DataEngine_UM_E5201-1204/202301/1755419_30005_0.htm

07-Hive

1 组件简介

1.1 组件概述

1.2 组件架构

1.3 应用场景

2 快速入门

2.1 组件安装

2.1.1 查看组件的日志信息

2.2 运行状态监控

2.2.1 查看组件详情

2.2.2 组件检查

2.3 快速使用指导

2.3.1 非Kerberos环境

2.3.2 Kerberos环境

2.4 快速链接

2.4.1 配置组件快速链接

2.4.2 访问Hive快速链接

3 使用指南

3.1 Client下载/安装/使用/卸载

3.1.1 Web界面进行集群外节点上的组件Client管理

3.1.2 后台进行集群外节点上的Client管理

3.2 添加/删除进程

3.2.1 添加进程

3.2.2 删除进程

3.3 权限访问控制

3.3.1 权限说明

3.3.2 权限使用操作示例

3.4 租户管理

3.4.1 Hive租户的资源共享策略

3.4.2 新增租户

3.4.3 租户使用操作示例

3.5 备份恢复

3.5.1 新建Hive同步任务

3.5.2 Web界面配置源集群和目的集群互信

3.5.3 后台配置源集群和目的集群互信

3.5.4 Hive同步任务相关配置修改

3.5.5 HDFS加密区数据同步

3.5.6 Hive备份恢复示例

3.6 LDAP认证

3.7 事务性操作

3.7.1 ACID的含义和使用

3.7.2 开启事务

3.7.3 事务表操作

3.8 HiveServer2 高可用功能

3.9 Hive分区表生命周期管理

3.9.1 总体要求

3.9.2 使用限制

3.9.3 使用说明

3.10 HQL操作

3.10.1 创建表

3.10.2 数据加载

3.10.3 数据查询

3.10.4 视图操作

3.10.5 函数介绍

3.11 JDBC方式连接HiveServer2

4 最佳实践

4.1 Hive操作HBase表

4.1.1 概述

4.1.2 操作示例

4.2 Hive on Spark

4.2.1 概述

4.2.2 操作示例

5 常见问题解答

5.1 调优类

5.2 运维类问题

1 组件简介

1.1  组件概述

Hive是建立在Hadoop上的数据仓库框架,提供一种类SQL的语言HQL(Hive Query Language),对结构化和半结构化数据进行批量分析,完成数据计算。

HQL具有对海量数据处理的能力,将执行的HQL语句转换为分布式计算任务,从而完成海量数据的查询和分析工作。同时,为了满足不同场景的需求,HQL能通过实现用户自定义函数(UDF)、用户自定义聚合函数(UDAF)以及用户自定义表函数(UDTF)对其进行扩展。

Hive具有以下特点:

· 易于进行数据的抽取、转换和加载(ETL)

· 支持多种数据存储格式

· 能直接访问存储在HDFS或其他数据存储系统上的文件

· 支持多种使用方式(如JDBC、WebUI等)

1.2  组件架构

图1-1 Hive 整体架构

表1-1 模块说明

· 一个集群内可部署多个HiveServer2

· 对外提供Hive数据库服务,将用户提交的HQL语句进行编译,解析成对应的Map/Reduce任务或者HDFS操作,从而完成数据的提取、转换和分析

· 提供JDBC/ODBC接口

MetaStore

· 一个集群内可部署多个MetaStore

· 提供Hive的元数据服务,负责Hive表结构和属性信息的读、写、维护和修改

· 提供Thrift接口,供HiveServer2、Spark和WebHCat等MetaStore客户端来访问,操作元数据

Map/Reduce

· Hive将SQL语句拆分成Map和Reduce任务,然后通过计算引擎MapReduce(或TEZ、Spark)执行

· Hive(version: 2.1.1-cdh6.2.0)使用MapReduce、Tez和Spark计算引擎

1.3  应用场景

Hive常用于以下场景:

· 数据离线分析:可以统计一个网址在某段时间内的页面访问量等。

· 数据挖掘:Hive与Spark结合可以完成数据挖掘工作,如用户行为分析、热点推荐等。

· 低成本数据分析:不需要编写MapReduce程序,可以使用SQL语句替代。

2.2  运行状态监控

2.2.1  查看组件详情

进入Hive组件详情页面,如 图2-1 所示。组件详情页面主要展示基本信息、部署拓扑、配置详情和配置修改历史等相关信息,同时可对组件或组件进程执行相关管理操作,可查看或修改组件的各配置项信息,也可查看组件的配置修改历史及当前使用配置版本。

主要功能如下:

· 基本信息:展示组件的基本配置信息,比如:进程部署的个数、启动状态等,以便于快速了解组件。

· 部署拓扑:在组件详情的[部署拓扑]页签,可查看组件进程的安装详情以及运行状态详情,并可对组件执行停止、重启、删除等相关操作。

【说明】:进程名:同一个进程可分别安装在多个主机节点上,所以进程列表中某一进程名可能重复出现,但同一进程名对应的主机名和主机IP不同。

· 配置:在组件详情的[配置]页签,可查看或修改组件各配置项的信息。

· 配置修改历史:在组件详情的[配置修改历史]页签,可查询组件的配置历史版本以及当前使用版本。

· 组件操作:在组件详情页面右上角,可对组件执行相关管理操作。比如:重启组件、添加进程、下载Client、访问快速链接、查看操作记录等。

图2-1 组件详情

2.2.2  组件检查

执行Hive组件检查时,会检查HiveServer是否可以正常连接。

集群在使用过程中,根据实际需要,可对Hive组件执行组件检查的操作。

(1)     组件检查的方式有以下三种,任选其一即可:

¡ 在[集群管理/集群列表]页面,单击某集群名称可跳转至对应的集群详情页面。

- 在集群详情页面选择[组件]页签,单击业务组件列表中Hive组件对应的<组件检查>按钮。

- 在集群详情页面选择[组件]页签,单击业务组件列表中Hive组件名称进入组件详情页面,在右上角组件操作的下拉框中选择<组件检查>按钮。

¡ 在组件管理的组件详情页面右上角组件操作的下拉框中选择<组件检查>按钮。

(2)     然后在弹窗中进行确定后,即可对该组件进行检查。

(3)     组件检查结束后,检查窗中会显示组件检查成功或失败的状态,如 图2-2 所示,表示该组件检查成功,可正常使用。

图2-2 组件检查

(4)     组件检查结束后,在组件详情页面单击<操作记录>按钮,进入操作记录窗口。可查看“Hive Service Check”组件操作执行的详细信息以及操作日志详情,根据操作日志可判断组件检查的具体情况。

图2-3 组件检查日志详情

2.3  快速使用指导

Hive既可以通过集群用户访问,又可以通过组件超级用户访问。其中:

· 集群用户:指在大数据集群的[集群权限/用户管理]页面可查看到的用户,包括集群超级用户和集群普通用户。其中:

¡ 集群超级用户:仅Hadoop集群拥有集群超级用户。新建Hadoop集群成功后,集群超级用户会自动同步到[集群权限/用户管理]页面,且对应描述为“集群超级用户”。

¡ 集群普通用户:指在[集群权限/用户管理]页面新建的用户。开启权限管理后,普通用户绑定角色即可拥有该角色所具有的权限;不开启权限管理时,普通用户缺省仅拥有各组件原生的用户权限。

· 组件超级用户:指组件内部的最高权限用户,如Hive组件的hive用户。大数据集群中安装组件时均会缺省创建组件内置超级用户,也是集群用户的一种。

2.3.1  非Kerberos 环境

Hive安装完成后,连接集群内的节点(该节点要求安装了Hive Client)即可操作Hive。在非Kerberos环境下通过控制台执行创建表、查询表等相关操作。操作步骤如下:

(1)     连接HiveServer2

在集群中包含Hive Client的某台机器中,使用以下任意方式连接:

¡ 方式一:默认参数连接

直接输入beeline,将会使用当前会话框用户自动连接集群的HiveServer。

¡ 方式二:指定参数连

beeline -u "jdbc:hive2://<HiveServer2地址>:10000/" -n hive -p

其中:<HiveServer2地址>为HiveServer2所在的机器IP地址或主机名(在Client节点上通过主机名连接HiveServer2时,该节点的/etc/hosts文件中必须包含对应集群的/etc/hosts文件的节点信息);10000为HiveServer2的默认端口号。

· -u:指定连接HiveServer2的地址和端口号。

· -n:指定连接所需用户名。

· -p:指定连接所需密码(使用LDAP认证时,需正确填写用户对应的密码。其他情况可为空值,开启LDAP认证的具体操作请参见 3.6 LDAP认证 章节)。

(2)     创建表

create table a(i int,s string);

(3)     插入数据

insert into table a values(1, 'a');

(4)     查看数据

select * from a;

+------+------+--+

| a.i  | a.s  |

+------+------+--+

| 1    | a    |

+------+------+--+

2.3.2  Kerberos 环境

· Kerberos环境下,用户需要做身份认证才可直接对Hive执行操作,认证方式请参见 2.3.2  1. Kerberos环境下的用户身份认证

· 本章节操作需要切换至具有操作Hive文件系统权限的用户。

1. Kerberos 环境下的用户身份认证

Kerberos环境下进行用户身份认证的方式(本章节示例用户为user1),认证有以下两种方式(根据实际情况任选其一即可):

· 集群用户身份认证

· 组件超级用户身份认证

(一)集群用户身份认证

· 集群用户指在大数据集群的[集群权限/用户管理]页面可查看到的用户,包括集群超级用户和集群普通用户。

· 集群用户的认证文件可在[集群权限/用户管理]页面,单击用户列表中用户对应的<下载认证文件>按钮进行下载。

Hive还可以通过集群用户访问。在开启Kerberos的大数据集群中进行集群用户(以user1用户示例)身份认证的方式,包括以下两种(根据实际情况任选其一即可):

· 方式一(此方式不要求知道用户密码,直接使用 keytab 文件进行认证)

a.     将用户user1的认证文件(即keytab配置包)解压后,上传至访问节点的/etc/security/keytabs/目录下,然后将keytab文件的所有者修改为user1,命令如下:

chown user1 /etc/security/keytabs/user1.keytab

b.     使用 klist 命令查看user1.keytab的principal名称,命令如下:

klist -k user1.keytab

【说明】如 图2-4 所示,红框内容即为user1.keytab的principal名称。

图2-4 认证文件的principal 名称

c.     切换至用户user1,并执行身份验证的命令如下:

su user1

kinit -kt user1.keytab [email protected]

【说明】其中:user1.keytab为用户user1的keytab文件,[email protected]为user1.keytab的principal名称。

d.     输入 klist 命令可查看认证结果。

· 方式二(此方式要求用户密码已知,通过密码直接进行认证)

a.     输入以下命令:kinit user1

b.     根据提示输入密码Password for [email protected]:<密码>

c.     输入 klis t命令可查看认证结果。

图2-5 查看认证结果

(二)组件超级用户身份认证

Hive可以通过组件超级用户访问,比如hive用户。在开启Kerberos的大数据集群中进行组件超级用户(以hive用户示例)认证的步骤如下:

(1)     在集群内节点的/etc/security/keytabs/目录下,查找hive的认证文件“hive.service.keytab”。

【说明】在Hive Client节点上,需要将hive的认证文件“hive.service.keytab”上传节点的任意目录下,将keytab文件的所有者修改为hive,然后切换至hive用户下进行认证,其中修改所有者命令为:

chown hive hive.service.keytab

(2)     使用 klist 命令查看hive.service.keytab的principal名称,命令如下:

klist -k hive.service.keytab

【说明】如 图2-6 所示,红框内容即为hive.service.keytab的principal名称。

图2-6 认证文件的principal 名称

(3)     切换至用户hive,并执行身份验证的命令如下:

su hive

kinit -kt hive.service.keytab hive/[email protected]

【说明】其中:hive.service.keytab为hive的认证文件,hive/[email protected]为hive.service.keytab的principal名称。

(4)     输入 klist 命令可查看认证结果。

2. Hive操作说明

Hive安装完成后,连接集群内的节点(该节点要求安装了Hive Client)即可操作Hive。当用户身份认证成功后,在Kerberos环境下通过控制台执行创建表、查询表等相关操作。操作步骤如下:

(1)     Hive的Principal配置值获取

登录集群HiveServer2所在节点(示例:node2.hde.com),运行以下命令获取principal:

klist -kt /etc/security/keytabs/hive.service.keytab

Keytab name: FILE:/etc/security/keytabs/hive.service.keytab

KVNO Timestamp           Principal

---- ------------------- ------------------------------------------------------

1 04/15/2020 21:35:56 hive/[email protected]

1 04/15/2020 21:35:56 hive/[email protected]

1 04/15/2020 21:35:56 hive/[email protected]

1 04/15/2020 21:35:56 hive/[email protected]

(2)     连接HiveServer2

在集群中包含Hive Client的某台机器(示例:node2.hde.com)中,使用以下任意方式连接:

¡ 方式一:默认参数连接

直接输入beeline,将会使用当前会话框用户自动连接集群的HiveServer。

¡ 方式二:指定参数连接

beeline -u " jdbc:hive2://node2:10000/;principal=hive/[email protected] " -n hive -p ""

- -u用于指定连接HiveServer2的地址和端口号。HiveServer2的端口号默认为10000,principal名称为hive/[email protected]

- -n用于指定连接所需的用户名(可为空值)。

- -p用于指定连接所需的密码(使用LDAP认证时,需正确填写用户对应的密码;其他情况可为空值)。

(3)     创建表

create table a(i int,s string);

(4)     插入数据

insert into table a values(1, 'a');

(5)     查看数据

select * from a;

+------+------+--+

| a.i  | a.s  |

+------+------+--+

| 1    | a    |

+------+------+--+

2.4  快速链接

2.4.1  配置组件快速链接

大数据集群部署完成后,需要修改本地hosts文件,用以确保组件的快速链接页面通过域名访问能够顺利跳转。

修改本地hosts文件的方法如下:

(1)     登录大数据集群中任意一节点,查看当前集群的hosts文件(Linux环境下位置为/etc/hosts)。

(2)     将集群的hosts文件信息添加到本地hosts文件中。若本地电脑是Windows环境,则hosts文件位于C:\Windows\System32\drivers\etc\hosts,修改该hosts文件并保存。

(3)     在本地hosts文件中配置主机域名信息完成后,此时即可访问组件的快速链接。

2.4.2  访问Hive 快速链接

Hive提供了Hive监控页面(即HiveServer UI),可以直观的看到当前链接的会话、历史日志、配置参数以及度量信息。

(1)     如 图2-7 所示,在Hive组件详情页面的右上角[快速链接]的下拉框中,可以获取访问入口信息。

【说明】当集群开启高可用时,Hive同步开启HA,此时有两个访问入口,任选其一即可。

图2-7 Hive 快速链接

(2)     HiveServer页面默认主页显示的是当前链接的会话,包括IP、用户名、当前执行的查询数量、链接总时长、空闲时长;如果有会话执行查询,页面中的Queries模块会显示查询的语句、执行耗时等。

图2-8 HiveServer UI页面

3 使用指南

3.1  Client 下载/安装/使用/卸载

用户可下载Hive Client,在客户端节点上安装Hive的Client后,即可直接连接集群中的Hive,进行组件维护、任务管理等操作。组件Client管理(Client下载/安装/使用/卸载)有两种方式:

· Web界面进行集群外节点上的组件Client管理

· 后台进行集群外节点上的Client管理

3.1.1  Web 界面进行集群外节点上的组件Client管理

在[运维管理/客户端管理]页面进行Client管理时,涉及手动和自动两种类别,不同类别支持的操作不同:

· 自动:适用于当前机器未安装组件客户端,配置完成后,可自动安装所属集群中所有支持下载Client的组件客户端,安装完成后可直接使用客户端。

· 手动:适用于当前机器已安装有组件客户端,仅支持将通过后台方式安装的Client客户端添加进客户端管理页面进行展示,不支持任何管理操作。对于手动类别的客户端,客户端的配置文件更新、卸载等操作,仍需在客户端节点后台手动进行操作,详情请参见 3.1.2 后台进行集群外节点上的Client管理

本章节仅介绍当前机器未安装组件客户端的情况下,如何在集群外未安装Client的机器上自动批量安装组件Client(集群中新增组件或组件配置变更时,可自动适配)、安装后如何使用客户端、如何卸载客户端。对于当前机器已通过后台方式安装组件客户端,如何手动将其添加到客户端管理页面进行展示,可参考产品联机帮助,此处不再进行说明。

1. 下载并安装Client

(1)     在[运维管理/客户端管理]页面,单击<新增客户端>按钮,弹出新增客户端窗口,如 图3-1 所示。

图3-1 新增客户端

(2)     在新增客户端窗口,选择“自动”类别,并根据提示配置参数项的值,参数说明如下:

¡ 选择集群:在下拉框选择客户端节点要访问的集群。

¡ 客户端IP:输入安装client的客户端节点所对应的主机IP地址,IP会自动进行测试连通性校验,并且也可以通过单击<测试连通性>按钮进行校验。

¡ 用户名:即客户端节点对应的主机用户名,必须为root用户。

¡ 用户密码:输入客户端节点对应的root用户密码。

(3)     配置完成后,单击<确定>按钮,可自动下载并安装所属集群中所有支持下载Client的组件客户端。

安装完成后,若配置状态为已是最新,则表示客户端配置与集群配置信息保持一致,可直接访问组件;若配置状态为手动刷新,表示客户端配置落后集群配置,此时需用户单击<手动刷新>按钮,主动将客户端配置与集群同步,待刷新完成后,客户端配置状态会显示为“已是最新”。

2. 访问组件

在客户端节点上,成功安装组件的Client之后,即可直接连接大数据集群中的该组件,执行相关管理、维护等操作。

· 根据大数据集群是否开启安全管理(即Kerberos认证),在集群外的客户端节点上访问组件的方式不同:

¡ 若集群未开启Kerberos,则在Client节点上,不需要对用户进行校验即可直接访问组件并执行相关操作。

¡ 若集群开启了Kerberos,则在Client节点上,必须对用户进行身份认证之后,才可访问组件并执行相关操作。关于Kerberos环境下,进行用户认证的操作方式请参见 2.3.2  1. Kerberos环境下的用户身份认证

3. 使用Hive Client

操作方式与 3.1.2  4. 非Kerberos环境下使用Hive Client 章节和 3.1.2  5. Kerberos环境下使用 Hive Client 章节完全相同。

4. 卸载Client客户端

删除自动安装的客户端节点,会自动在客户端节点卸载Client客户端,不仅在客户端管理页面的客户端列表中对应信息会被清除,而且无法通过该客户端向集群中提交任务,客户端上正在运行的程序也会被终止。

对于自动安装的客户端,可通过在客户端管理页面执行删除客户端的操作来卸载Client客户端。

(1)     在[运维管理/客户端管理]页面,单击某客户端节点对应的<删除>按钮,并在弹出的窗口中单击<确定>按钮,即可删除客户端节点,如 图3-2 所示。

图3-2 删除客户端

3.1.2  后台进行集群外节点上的Client 管理

1. 下载Client安装包

· 组件Client下载方式较多(比如:集群支持批量下载Client操作),下载要求也存在差异,但关于安装、使用、卸载等操作均类似,更多详情请参见产品在线联机帮助,本章节不做单独说明。

· 本章节仅以下载集群中单个组件Client为例进行操作指导。

· 组件Client下载成功后,将在服务器指定路径下或本地获得Client压缩包。

· Client安装完成后,通过客户端可直接登录其对应的组件,在运维场景或业务场景中直接使用shell命令,或在应用程序开发场景中使用客户端中的样例工程。

· 租户中的Hive组件也支持下载Client,下载Client按钮在租户详情页面。本文以下载集群中组件Client为例进行操作,租户中的Client下载操作类似。

下载Client安装包的步骤如下:

(1)     在集群管理页面的集群列表中,单击集群名称进入集群详情页面,在集群已安装的组件列表中单击Hive组件的<下载Client>按钮,弹出下载Client窗口,如 图3-3 所示。

图3-3 下载客户端

(2)     根据规划,选择下载的客户端类型,包括“完整客户端”和“仅配置文件”两种。其中:

¡ 完整客户端,表示下载客户端的完整文件,适用于首次安装完整客户端的场景。

¡ 仅配置文件,表示仅下载客户端的配置文件,适用于已下载并安装过完整客户端,但集群中的组件配置信息或主机相关信息后来被更改的场景下,此时需要更新客户端节点上的配置文件。

(3)     根据实际使用需要,可选择下载的Client压缩包仅保存在服务器指定目录下或同步下载到本地。

¡ 保存到服务器上时,缺省保存在服务器的/var/lib/ambari-server/data/tmp/目录下(下载成功后,会有下载地址的详细提示信息),该路径不支持修改。

¡ 若勾选同步下载到本地时,则下载的客户端文件会保存到用户本地下载目录下。

(4)     完成选择后,单击<确定>按钮,即可下载Client安装包。根据选择下载路径的不同或选择下载客户端类型的不同,得到的Client压缩包名称均不相同,详情请以实际为准。

2. 安装Client客户端

· 安装Client的节点必须能与大数据集群中的所有节点均网络互通。

· 安装Client的节点的操作系统必须与大数据集群中各节点的操作系统相同,否则会导致Client不完整无法正常使用。

· 下载的组件Client禁止安装在大数据平台管理节点上或者大数据集群的各个节点上,否则可能会导致已安装的服务或组件异常。

· 安装Client的节点必须启用NTP服务,且必须与大数据集群时间保持一致。

· 建议安装Client之前,关闭该节点的防火墙,否则可能会导致部分组件使用异常。

· 执行安装 Client客户端的用户可以为root用户和所有被赋予权限的非root用户(比如权限为755)。

与下载Client时可选择的客户端类型对应,安装Client也分为两种情况:

· 安装完整客户端。

· Client配置文件更新。

(一)安装完整客户端

(1)     登录待安装Client的目标节点,将已下载的Client压缩包上传到任意路径下,进行解压。

(2)     配置网络连接,仅非root用户需要执行此操作,root用户可跳过此步骤。

在解压得到的Client安装包文件夹中,查看hosts文件获得集群所有节点主机名和IP地址的映射关系,将集群各主机名和IP地址按照严格的映射关系,拷贝至该节点的“/etc/hosts”文件中。

(3)     启动安装

在解压得到的Client安装包文件夹下,启动安装脚本。命令如下:

./install.sh <安装路径> -o

· 安装Client时,可自定义指定安装路径,若不指定则使用缺省安装路径。若安装目录不存在,则会自动创建;若安装目录已存在,则要求必须为空。当前版本中,Client缺省安装目录为/usr/hdp/3.0.1.0-187/。

· 安装Client时,还可以通过在末尾添加“-o”参数,限制安装后的组件Client仅能被执行安装的该用户使用;若不添加则表示任意用户均可使用此组件Client。

(二)仅更新配置文件

(1)     登录待更新Client配置文件的目标节点,将已下载的Client压缩包上传到任意路径下。

(2)     在Client安装路径下,执行更新Client配置文件的命令。命令如下:

./refreshConfig.sh <Client 安装路径> <Client配置文件包存放路径>/<Client配置文件包>

3. 访问组件

在集群外节点上,成功安装组件的Client之后,即可直接连接大数据集群中的该组件,执行相关管理、维护等操作。需要注意:

· Client安装完成后,进入安装目录,配置客户端环境变量(仅针对session有效,建议每次使用Client客户端时均配置一遍环境变量),命令如下:

source bigdata_env

· 根据大数据集群是否开启安全管理(即Kerberos认证),在集群外的客户端节点上访问组件的方式不同:

¡ 若集群未开启Kerberos,则在Client节点上,不需要对用户进行身份认证即可直接访问组件并执行相关操作。

¡ 若集群开启了Kerberos,则在Client节点上,必须对用户进行身份认证之后,才可访问组件并执行相关操作。关于Kerberos环境下,进行用户认证的操作方式请参见 2.3.2  1. Kerberos环境下的用户身份认证

使用beeline命令连接HiveServer2,操作步骤如下:

(1)     Hive启动beeline

¡ 方式一:以当前用户beeline连接HiveServer2

beeline

¡ 方式二:自定义用户beeline连接HiveServer2

beeline -u url -n username -p password

在beeline中连接Hiveserver2,分为两种模式:

- 非HA模式下连接,执行如下命令:

url: jdbc:hive2://<HiveServer2地址>:10000

其中:<HiveServer2地址>为HiveServer2所在的机器IP地址或主机名(在集群外通过主机名连接HiveServer2时必须配置本地hosts文件);10000为HiveServer2的默认端口号。

需要根据实际环境输入用户名(示例用户为hive)和密码,密码为空,连接示例命令如下:

beeline -u “jdbc:hive2://node2:10000/” -n hive -p ""

- HA模式下连接,执行如下命令:

url: jdbc:hive2:// <zk_url>/:serviceDiscoveryMode=zookeeper; zooKeeperNamespace=hiveserver2;

其中,<zk_url>是ZooKeeper集群地址,例如“node1:2181,node2:2181,node3:2181”。zooKeeperNamespace默认HiveServer2对应配置文件中hive.server2.zookeeper.namespace的值

需要根据实际环境输入用户名(示例用户为hive)和密码,密码为空,连接示例命令如下:

beeline -u "jdbc:hive2://node1:2181,node2:2181,nod3e:2181/;serviceDiscoveryMode=zookeeper;zookeeperNamespace=hiveserver2" -n hive -p ""

(二)HQL示例

通过beeline连接Hive进行建表,操作步骤如下:

(1)     在本地目录下创建teacher_li.txt文件,内容如下:

John          19

Marry        18

Poli            19

(2)     将文件上传到HDFS的tmp目录下,执行如下命令:

hdfs dfs -put teacher_li.txt /tmp

(3)     使用beeline连接Hive组件:

beeline –u “!connect jdbc:hive2://node2:10000” –n hdfs –p “”

说明:此处输入示例用户名hdfs,输入密码为空

(4)     创建表,执行如下语句:

CREATE TABLE student1_info( name STRING, age INT)

PARTITIONED BY (teacher STRING)

ROW FORMAT DELIMITED

FIELDS TERMINATED BY  '\t'

LINES TERMINATED BY '\n'

STORED AS TEXTFILE;

(5)     向表中加载数据,执行如下语句:

load data inpath '/tmp/teacher_li.txt' into table student_info partition( teacher='Mr.li' );

(6)     查询数据结果,执行如下语句:

select * from student_info;

图3-4 查询数据结果

5. Kerberos 环境下使用 Hive Client

(一)Kerberos认证

Kerberos环境下使用Hive Client需要先进行用户身份认证,用户身份认证详情请参见 2.3.2  1. Kerberos环境下的用户身份认证

(二)Hive Client使用beeline

Hive Client使用beeline操作步骤如下:

(1)     Hive启动beeline

¡ 方式一:以当前用户beeline连接HiveServer2

beeline

¡ 方式二:自定义用户beeline连接HiveServer2

在beeline中连接Hiveserver2,分为两种模式:

- 非HA模式下连接,执行如下命令:

beeline  !connect jdbc:hive2://node:10000/;principal=hive/[email protected]

其中:node为HiveServer2服务所在机器IP地址或主机名(在集群外通过主机名连接HiveServer2时必须配置本地hosts文件);hive/[email protected]为HiveServer2的principal的名称。

- HA模式下连接,执行如下命令:

beeline -u "jdbc:hive2://node1:2181,node2:2181,nod3e:2181/;serviceDiscoveryMode=zookeeper;zookeeperNamespace=hiveserver2" -n hive -p ""

其中:node1:2181,node2:2181,node3:2181是ZooKeeper集群地址;zooKeeperNamespace默认HiveServer2对应配置文件中hive.server2.zookeeper.namespace的值。

(2)     需要根据实际环境选择输入用户名和密码,密码为空。

(三)HQL示例

通过beeline连接Hive组件进行建表,操作步骤如下:

(1)     在本地目录下创建teacher_li.txt文件,内容格式如下:

John          19

Marry         18

Poli            19

(2)     将文件上传到HDFS的tmp目录下,步骤如下:

hdfs dfs -put teacher_li.txt /tmp

a.     使用beeline连接Hive组件,执行如下语句:

!connect jdbc:hive2://node2:10000/;principal=hive/[email protected]

说明:此处输入示例用户名hive,输入密码为空。

b.     创建表,执行如下语句:

CREATE TABLE student_info( name STRING, age INT)

PARTITIONED BY (teacher STRING)

ROW FORMAT DELIMITED

FIELDS TERMINATED BY  '\t'

LINES TERMINATED BY '\n'

STORED AS TEXTFILE;

c.     向表中加载数据,执行如下语句:

load data inpath '/tmp/teacher_li.txt' into table student_info partition( teacher='Mr.li' );

d.     查询数据结果,执行如下语句:

select * from student_info;

图3-5 查询数据结果

6. 卸载Client 客户端

集群重装之后,之前安装的Client客户端将不可用。此时需要卸载Client。执行卸载Client的用户可以为root用户或所有被赋予权限的非root用户。

(1)     登录安装Client的节点,在Client安装目录下执行以下命令:

./uninstall.sh

(2)     卸载脚本执行结束后,安装目录将自动删除,此时Client卸载成功。

3.2  添加/ 删除进程

3.2.1  添加进程

Hive 支持添加 HiveServer2、Hive Metastore进程 在并发查询任务较多的情况下,可以考虑增加HiveServer2和Hive Metastore进程,分摊查询负载,提高并发数。

1. 操作示例

· 本章节仅以添加HiveServer2进程为例进行说明,其它进程操作类似不再进行说明。

· 若集群中所有节点均已安装Hive Server2,添加Hive Server2进程前则需要先在集群中添加主机,然后再执行添加Hive Server2进程的操作。如果集群中有添加进程所需要的主机,则可直接执行添加Hive Server2进程的操作。

添加 HiveServer2进程的操作步骤如下:

(1)     在Hive组件详情页面,在右上角组件操作的下拉框中选择<添加进程>按钮。

(2)     弹出添加进程窗口,如 图3-6 所示。

a.     选择进程及主机

在选择进程项的下拉列表中选择可添加的组件进程,在选择主机项的主机列表中勾选进程安装在哪一个主机上(支持多选)。

b.     部署进程

选择结束后单击下一步部署进程,直至部署进度条结束(不支持中止)。

c.     启动进程

部署进程结束后单击下一步启动进程,直至启动进度条结束(不支持中止)。

图3-6 添加 进程

(3)     查看进程变化

HiveServer2扩容完成后,在组件详情页面[部署拓扑]页签中可以查看HiveServer2安装数量变化以及状态。

(4)     重启组件(根据实际情况选择)

进入集群详情页面,选择[组件]页签,需根据页面提示重新启动相关组件。

3.2.2  删除进程

Hive支持删除HiveServer2或Hive Metastore进程。

· 在并发任务较少的情况下,可以考虑减少Hive Metastore和HiveServer2进程,节省集群资源。

· 删除进程后,Hive Metastore、HiveServer2分别对应进程的个数均不能少于1个。

1. 操作示例

· 删除进程操作不仅可以在组件详情页面的[部署拓扑]页签下执行,也可以在[集群管理/主机管理/主机监控]下的主机详情页面执行。本章节仅以“在组件详情页面的[部署拓扑]页签下执行删除HiveServer2进程操作”为例进行说明,其它进程操作类似不再进行说明。

· 执行删除HiveServer2进程操作前,请确认HiveServer2是否有运行的任务,如果有运行的任务时,删除进程会影响任务执行。

删除HiveServer2进程的操作步骤如下:

(1)     在Hive组件详情页面[部署拓扑]页签下,选择需要删除HiveServer2进程的主机,然后单击该进程右侧操作中的<停止>按钮,停止HiveServer2。

(2)     删除 HiveServer 2

待HiveServer2停止成功后,如所示,单击操作列的<删除>按钮,即可完成删除HiveServer2。

图3-7 删除进程

(3)     查看进程变化

HiveServer2删除完成之后,在组件详情页面[部署拓扑]页签中可以查看HiveServer2进程的数量变化情况以及状态。

(4)     重启组件(根据实际情况选择)

进入集群详情页面,选择[组件]页签,需根据页面提示重新启动相关组件。

3.3  权限访问控制

集群新建用户的组件权限会因为集群是否开启权限管理功能而有所不同:

· 未开启权限管理时,用户可进行库表的创建、修改、插入、删除等操作。

· 开启权限管理后,组件权限需通过[集群权限/角色管理]中的角色分配给用户,用户通过绑定角色进行赋权后,才能对组件执行操作。

权限管理是安全管理的重要组成部分,在开启权限管理的集群中,权限基于角色进行统一管理,角色是权限的集合。

为用户赋予权限的整体流程如下:

(1)     新建角色,并为角色配置权限。

(2)     新建用户,并将角色分配用户,用户即拥有角色所具有的权限。

3.3.1  权限说明

Hive支持对数据库表和数据库UDF配置权限,并且提供数据脱敏和行级过滤功能。

· 数据库的配置权限:数据库表可对数据库、数据表、列配置权限,权限包括:select、update、create、drop、alter、index、use,其中all表示配置所有权限。注意:Hive的权限同样也适用于Impala(Impala只支持查询操作的列权限)、Spark组件,即Impala、Spark SQL也支持对库表的权限访问控制。

· 数据库UDF的配置权限:数据库UDF可对数据库、UDF配置权限,权限包括create、drop。

· 数据脱敏:是指按照某种规则对指定列进行脱敏,保证数据安全性,Hive数据脱敏策略如 3-2 所示。

· 行级过滤:是指对表配置行级过滤策略,仅展示满足过滤策略的数据(若过滤策略配置为空则不过滤)。行级过滤类似where子句,示例:配置策略id>1时,查询表时会自动获取id大于1的数据。

Hive操作所需权限对应关系如 表3-1 所示,Hive数据脱敏策略如 表3-2 所示。

表3-1 Hive 权限说明

以授予create权限为例,对数据库hivetest授予create权限 (其它权限的授予方式与 create方式操作类似),操作步骤如下:

(1)     新建用户hiveuser01,授权前执行创建库操作。如 图3-8 所示,表示hiveuser01用户没有hivetest数据库的create权限。

图3-8 执行结果

(2)     角色授权

在[集群权限/角色管理]页面,新建角色hive01,本示例授予hive01角色hivetest数据库的create权限。

图3-9 为hive01角色授予权限

(3)     用户绑定角色

在[集群权限/用户管理]页面,在hiveuser01用户的操作列,单击<修改用户授权>按钮,选择角色hive01。

图3-10 用户绑定角色

(4)     重新执行创建hivetest数据库操作。如 图3-11 所示,表示数据库hivetest成功创建。

图3-11 执行结果

2. 表权限控制

表3-4 授权配置

以授予update权限为例,对数据库hivetest数据表hivetab1授予update权限,操作步骤如下:

(1)     新建用户hiveuser21,授权前,执行插入表hivetest.hivetab1操作如 图3-12 所示,表示hiveuser21用户没有hivetest.hivetab1数据表的update权限。

图3-12 无权限

(2)     角色授权

[集群权限/角色管理]页面,新建角色hive21,本示例授予hive21角色hivetest.hivetab1数据表的update权限。

图3-13 为hive21角色授予权限

(3)     用户绑定角色

在[集群权限/用户管理]页面,在hiveuser21用户的操作列,单击<修改用户授权>按钮,选择角色hive21。

图3-14 用户绑定角色

(4)     重新执行插入表hivetest.hivetab1操作

图3-15 所示,红框内信息表明hiveuser21没有提交到yarn default队列的权限。

图3-15 无权限

(5)     角色授权

[集群权限/角色管理]页面,单击hive21角色操作列的<编辑>按钮,修改角色组件权限设置。本示例授予hive21角色队列default的submit-app权限。

图3-16 为hive21角色授予权限

(6)     重新执行插入表hivetest.hivetab1操作。如 图3-17 所示,表明hivetest.hivetab1数据表成功插入数据

图3-17 插入成功

以授予select权限为例,对数据库hivetest数据表hivetab1授予select权限,操作步骤如下:

(1)     执行查询表hivetest.hivetab1操作。如 图3-18 所示,截图中表示hiveuser21用户没有hivetest.hivetab1数据表的select权限。

图3-18 无权限

(2)     角色授权

[集群权限/角色管理]页面,单击hive21角色操作列的<编辑>按钮,修改角色组件权限设置。本示例授予hive21角色hivetest.hivetab1数据表的select权限。

图3-19 授予权限

(3)     重新执行查询表hivetest.hivetab1操作。如 图3-20 所示,信息表明可以查询hivetest.hivetab1数据表数据。

图3-20 查询成功

3. 列级别权限控制

表3-5 授权配置

以授予select 权限为例,对数据库hivetest数据表hivetab1的name列授予select权限,操作步骤如下:

(1)     新建用户hiveuser02,授权前进行查询操作。如 图3-21 所示,提示当前用户没有表hivetab1的查询权限。

图3-21 执行结果

(2)     角色授权

在[集群权限/角色管理]页面,授权hivetest库下hivetab1表的列name查询权限。

图3-22 授予权限

(3)     用户绑定角色

在[集群权限/用户管理]页面,hiveuser02用户修改用户授权选择hive02角色,进行用户绑定角色。

图3-23 绑定角色

(4)     重新执行查询操作,select操作执行成功。

图3-24 执行结果

以授予update权限为例,对数据库hivetest数据表hivetab1的name列授予update权限,操作步骤如下:

(1)     执行插入表hivetest.hivetab1列name的操作,提示当前没有update权限。

图3-25 无权限

(2)     角色授权

在[集群权限/角色管理]页面,单击hive02角色操作列的<编辑>按钮,修改角色组件权限设置。本示例授予hive02角色hivetest.hivetab1中name列的update权限,及YARN队列default的submit-app权限。

图3-26 授予权限

(3)     重新执行插入操作,insert操作执行成功。

图3-27 执行成功

图3-28 查询插入结果

4. UDF权限控制

表3-6 授权配置

public final class LowerFunc extends UDF{

public Text evaluate(final Text s){

if(s == null){return null;}

return new Text(s.toString().toLowerCase());

其中pom.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>com.test</groupId>

<artifactId>hiveUdfTest</artifactId>

<version>1.0-SNAPSHOT</version>

<dependencies>

<dependency>

<groupId>org.apache.hive</groupId>

<artifactId>hive-exec</artifactId>

<version>2.1.1-cdh6.2.0</version>

</dependency>

</dependencies>

<build>

<plugins>

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-shade-plugin</artifactId>

<version>2.4.3</version>

</plugin>

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-compiler-plugin</artifactId>

<version>3.0</version>

<configuration>

<source>1.7</source>

<target>1.7</target>

</configuration>

</plugin>

</plugins>

</build>

</project>

(2)     编译打包后上传到测试集群,示例中打包为hiveUdfTest-1.0-SNAPSHOT.jar。

(3)     新建用户udfuser03,将udf测试jar包上传到hdfs,授权前进行create操作。如 图3-29 所示,提示当前用户没有库hivetest下udf mylowerperm1的create权限。

图3-29 无权限

(4)     修改/tmp/udflib目录权限为777目的是其他用户调用该函数时拥有该jar包的访问权限。

(5)     角色授权

在[集群权限/角色管理]页面,新建角色udf03,授权hivetest库下udf mylowerperm1的create权限。

图3-30 授予权限

(6)     绑定角色

在[集群权限/用户管理]页面,udfuser03用户修改用户授权选择udf03角色,进行用户绑定角色。

图3-31 绑定角色

(7)     重新执行操作,create操作执行成功。

图3-32 执行成功

图3-33 查看创建的内容

· 在新Session中执行show functions命令或show functions like '*函数名*'命令可能查看不到新建函数,因为之前创建function时连接的HiveServer2和当前连接是不同的,执行reload functions命令或重启当前连接的HiveServer2,即可重新读取数据库的函数加载到缓存,此时重新执行命令即可查看到新建函数。

· 在创建或删除临时函数(如:create temporary function ...或drop temporary function ...)时,由于临时函数属于会话session级别,不属于某个数据库,使用时也不需要追加库名前缀。因此授权时,选择数据库需要配置对所有库都有权限,即数据库配置为*。

5. 数据脱敏配置

数据脱敏是指按照某种规则对指定列进行脱敏,保证数据安全性。配置数据脱敏规则需先配置数据库表的select权限,然后进行数据脱敏配置。下面简单介绍数据脱敏配置的整体流程。

【示例一】

以配置脱敏规则为MASK为例,对数据库mask01数据表t01的name列进行数据脱敏,操作步骤如下:

(1)     配置数据库表mask01.t01的select权限,即对数据库mask01数据表t01授予select权限。新建用户hivemask01和角色hivemask01,为角色授予select权限后,将该用户绑定到hivemask01角色,并执行查询表操作。详细过程请参考 3.3.2  2. 章节,查询结果如 图3-34 所示。

图3-34 mask01.t01 原始数据

(2)     配置脱敏规则MASK

在[集群权限/角色管理]页面,单击角色列表中hivemask01角色名进入角色详情页面,在页面右上角单击<编辑>按钮,配置mask01库下t01表的列name的脱敏规则为MASK,即通过规则“x替代小写字母,X替代大写字母,n替代数字”来实现对列name的数据脱敏。

图3-35 配置脱敏规则MASK

(3)     执行查询表mask01.t01操作。如 图3-36 所示,信息表明对mask01库下t01表的列name脱敏成功。

图3-36 MASK 脱敏成功

【示例二】

以配置脱敏规则为MASK_SHOW_LAST_4为例,对数据库mask01数据表t01的name列进行数据脱敏,操作步骤如下:

(1)     配置脱敏规则MASK_SHOW_LAST_4

在[集群权限/角色管理]页面,单击角色列表中hivemask01角色名进入角色详情页面,在页面右上角单击<编辑>按钮,配置mask01库下t01表的列name的脱敏规则的脱敏规则为MASK_SHOW_LAST_4,即通过规则“仅显示后四位,其他用x代替”来实现对列name的数据脱敏。

图3-37 配置脱敏规则MASK_SHOW_LAST_4

(2)     执行查询表mask01.t01操作。如 图3-38 所示,信息表明对mask01库下t01表的列name脱敏成功。

图3-38 MASK_SHOW_LAST_4 脱敏成功

【示例三】

以配置脱敏规则为MASK_SHOW_FIRST_4为例,对数据库mask01数据表t01的name列进行数据脱敏,操作步骤如下:

(1)     配置脱敏规则MASK_SHOW_FIRST_4

在[集群权限/角色管理]页面,单击角色列表中hivemask01角色名进入角色详情页面,在页面右上角单击<编辑>按钮,配置mask01库下t01表的列name的脱敏规则的脱敏规则为MASK_SHOW_FIRST_4,即通过规则“仅显示前四位,其他用x代替”来实现对列name的数据脱敏。

图3-39 配置脱敏规则MASK_SHOW_FIRST_4

(2)     执行查询表mask01.t01操作。如 图3-40 所示,信息表明对mask01库下t01表的列name脱敏成功。

图3-40 MASK_SHOW_FIRST_4 脱敏成功

【示例四】

以配置脱敏规则为MASK_HASH为例,对数据库mask01数据表t01的name列进行数据脱敏,操作步骤如下:

(1)     配置脱敏规则MASK_HASH

在[集群权限/角色管理]页面,单击角色列表中hivemask01角色名进入角色详情页面,在页面右上角单击<编辑>按钮,配置mask01库下t01表的列name的脱敏规则的脱敏规则为MASK_HASH,即通过规则“Hash值替代原值”来实现对列name的数据脱敏。

图3-41 配置脱敏规则MASK_HASH

(2)     执行查询表mask01.t01操作。如 图3-42 所示,信息表明对mask01库下t01表的列name脱敏成功。

图3-42 MASK_HASH 脱敏成功

【示例五】

以配置脱敏规则为MASK_NULL为例,对数据库mask01数据表t01的name列进行数据脱敏,操作步骤如下:

(1)     配置脱敏规则MASK_NULL

在[集群权限/角色管理]页面,单击角色列表中hivemask01角色名进入角色详情页面,在页面右上角单击<编辑>按钮,配置mask01库下t01表的列name的脱敏规则的脱敏规则为MASK_NULL,通过规则“NULL值替代原值”来实现对列name的数据脱敏。

图3-43 配置脱敏规则MASK_NULL

(2)     执行查询表mask01.t01操作。如 图3-44 所示,信息表明对mask01库下t01表的列name脱敏成功。

图3-44 MASK_NULL 脱敏成功

【示例六】

以配置脱敏规则为MASK_NONE为例,对数据库mask01数据表t01的name列进行数据脱敏,操作步骤如下:

(1)     配置脱敏规则MASK_NONE

在[集群权限/角色管理]页面,单击角色列表中hivemask01角色名进入角色详情页面,在页面右上角单击<编辑>按钮,配置mask01库下t01表的列name的脱敏规则的脱敏规则为MASK_NONE,即“显示原值”。

图3-45 配置脱敏规则MASK_NONE

(2)     执行查询表mask01.t01操作。如 图3-46 所示,数据显示原值。

图3-46 MASK_NONE 脱敏成功。

【示例七】

以配置脱敏规则为MASK_DATE_SHOW_YEAR为例,对数据库mask01数据表t03的birth列进行数据脱敏,操作步骤如下:

(1)     配置数据库表mask01.t03的select权限,即对数据库mask01数据表t03授予select权限,执行查询表操作。详细过程请参考 3.3.2  2. 章节,查询结果如 图3-47 所示。

图3-47 mask01.t03 原始数据

(2)     配置脱敏规则MASK_DATE_SHOW_YEAR

在[集群权限/角色管理]页面,单击角色列表中hivemask01角色名进入角色详情页面,在页面右上角单击<编辑>按钮,配置mask01库下t01表的列birth的脱敏规则的脱敏规则为MASK_DATE_SHOW_YEAR。

图3-48 配置脱敏规则MASK_DATE_SHOW_YEAR

(3)     执行查询表mask01. t03操作。如 图3-49 所示,若birth列为date类型,通过规则“显示日期年份,月份和日期均用01代替”来实现对列birth的数据脱敏。

图3-49 MASK_DATE_SHOW_YEAR 脱敏成功

注意 :若birth列为string类型,配置脱敏规则MASK_DATE_SHOW_YEAR时,年月日均用x替换来实现脱敏。

6. 行级过滤配置

配置行级过滤规则需先配置数据库表的select权限,然后配置行级过滤权限。对数据库mask01数据表t01配置行级过滤策略,操作步骤如下:

(1)     配置数据库表mask01.t01的select权限,即对数据库mask01数据表t03授予select权限,执行查询表操作。详细过程请参考 3.3.2  2. 章节(本章仍以hivemask01用户和hivemask01角色为例进行说明),当前若已完成该配置,则跳过此步。

(2)     配置行级过滤规则

在[集群权限/角色管理]页面,单击角色列表中hivemask01角色名进入角色详情页面,在页面右上角单击<编辑>按钮,配置mask01库下t01表的的过滤规则为“id>123 and name like '%mask%'”(若配置为空则不过滤)。

图3-50 配置行级过滤规则

(3)     执行查询表mask01. t01操作。如 图3-51 所示,即为“id>123 and name like '%mask%'”过滤后的结果。

图3-51 行级过滤结果

3.4  租户管理

租户主要用于资源控制、业务隔离的场景。通过租户将大数据集群的资源隔离成一个个资源集合(一个资源集合是一个租户)。 多个租户之间共享一套集群,共享网络和集群资源,并且不同租户之间保证资源隔离。在使用租户管理功能时,不同类型的用户执行租户相关操作的流程不同,如下:

· 新增租户

¡ 普通用户在自己创建的租户集群中申请租户时,无需审批,会直接触发新增租户的操作。

¡ 普通用户在其他用户创建的租户集群中申请租户时,则需要走流程审批,待审批人审批通过后才能触发新增租户的操作。

¡ 管理员用户新增租户时,无需审批,会直接触发新增租户的操作。

· 租户管理操作

¡ 普通用户在自己创建的租户集群中执行租户续期、资源扩缩容操作时,无需审批,会直接触发相关操作。

¡ 普通用户在其他用户创建的租户集群中执行租户续期、资源扩缩容操作时,则需要走流程审批,待审批人审批通过后才能触发相关操作。

¡ 管理员用户执行租户续期、资源扩缩容操作时,无需审批,会直接触发相关操作。

3.4.1  Hive 租户的资源共享策略

租户申请的Hive资源对应一个或多个database,每个database具有独立的存储和计算资源,用户可根据实际需要申请Hive组件资源。

租户申请Hive资源时,Hive依赖YARN,即申请Hive资源必须同时申请YARN资源。

· Hive的计算资源由YARN进行分配和调度。

· Hive的存储资源对应HDFS资源。

3.4.2  新增租户

(1)     在[集群权限/租户管理]页面,单击<新增租户>按钮,跳转至新增租户页面,如 图3-52 所示。在租户集群sharecluster01中新增租户hiveshare1,主用户usershare1,并为该租户配置Hive组件资源(数据库名hiveshare1、数据库容量10GB)、YARN组件资源(内存8GB、CPU核数4)。使用Hive资源需要依赖YARN资源。

图3-52 新增 租户

(2)     新增租户成功后,用户可在租户列表查看到已创建的租户,同时可以看到其所属集群、申请人、用户名列表、创建时间、失效时间等相关信息,如 图3-53 所示。

图3-53 查看租户

(3)     单击租户名称,可查看租户详情,如 图3-54 所示,可以看到对应的Hive数据库名和容量、YARN队列和容量等信息。用户usershare1拥有该租户资源的所有权限,若资源不够/过多时,可编辑租户对其执行扩容/缩容操作。

图3-54 查看租户详情

(4)     确认租户

租户创建成功后,其中的用户usershare1、队列hiveshare1、数据库hiveshare1均创建成功。

¡ Hive:数据库hiveshare1创建成功,大小为10G。

图3-55 查看Hive资源

¡ YARN:资源队列由原来的root下只有default队列变为default和hiveshare1队列,且hiveshare1的队列大小为8G 4core,可通过ResourceManager UI页面Scheduler查看。

图3-56 查看YARN资源

3.4.3  租户使用操作示例

· 租户模式的集群缺省开启Kerberos认证,在使用租户时需要通过该租户的用户对应的认证文件,对租户的用户进行身份认证。租户的用户认证文件的下载在租户列表页面或租户详情页面执行,关于对租户资源的用户进行认证的方式与集群中用户的身份认证方式相同,详情请参见 2.3.2  1. Kerberos环境下的用户身份认证

· Hive资源的租户包括客户端(即组件Client),系统提供了下载Hive客户端的功能。在客户端节点上安装Hive的Client后,即可连接租户中的此组件,执行组件维护、任务管理等操作。租户资源组件Client的下载在租户列表页面执行,关于租户资源组件Client的安装方式与集群组件Client相同,详情请参见 3.1 Client下载/安装/使用/卸载

在hiveshare1数据库中执行创建表并插入、查询数据等操作。

图3-57 执行创建表并插入、查询数据等操作

3.5  备份恢复

备份恢复可以提供DataEngine跨集群之间的数据同步功能,当前版本支持对Hive组件中的指定数据进行同步备份,以保证数据内容不丢失。

备份恢复功能主要是通过创建同步任务实现集群间的数据同步能力。使用同步任务功能,可以为集群中的数据提供同步能力,以满足日常数据备份的需求,保证系统或机器故障时的数据不丢失。

3.5.1  新建 Hive同步任务

· 源集群为同步任务的数据输出集群(一般指新建同步任务的本集群);目的集群为同步任务的数据输入集群。

· 新建同步任务时,要求源集群与目的集群的安全管理策略相同,即同时开启Kerberos认证或同时都没有开启Kerberos认证。

· 新建同步任务时,要求源集群与目的集群的集群类型、集群模式均相同。

· 新建同步任务时,要求源集群与目的集群的集群名称、集群中节点主机名均不相同,否则配置跨集群互信时可能出错。

· Hive同步任务不支持事务表的同步,不支持多个主集群备份到同一个备集群。

· Hive同步任务为周期性调度任务。Hive同步任务周期性执行时,默认首次执行是全量数据备份,后续执行是增量数据备份,备份周期间隔时间内的数据不会实时同步到目的集群。

· 使用Hive同步任务备份HDFS加密区的数据时,需要根据集群的配置情况进行相关配置修改,详情请参见 3.5.5 HDFS加密区数据同步

集群在使用过程中,根据实际需要,可新建Hive同步任务,将源集群中的Hive某些库或表中的数据周期性拷贝到目的集群中。

1. 前提条件

· Web界面配置源集群和目的集群互信:运行Hive同步任务前,可在大数据平台管理系统的Web界面完成互信配置。即在大数据平台管理系统的[运维管理/互信管理]页面配置源集群和目的集群互信,详情请参见 3.5.2 Web界面配置源集群和目的集群互信

· 后台配置源集群和目的集群互信:运行Hive同步任务前,也可在后台完成互信配置。即需要根据集群的配置情况进行相关配置修改,配置方法详情请参见 3.5.3 后台配置源集群和目的集群互信 3.5.4 Hive同步任务相关配置修改

2. 新建Hive同步任务

新建Hive同步任务的前提条件准备完成后,即可开始创建Hive同步任务。步骤如下:

(1)     在[集群管理/备份恢复]页面,选择[同步任务]页签,单击<新建同步任务>按钮,进入新建同步任务页面。

(2)     选择Hive组件,如 图3-58 所示,根据提示配置对应参数项的值,关于各参数项配置详情请参见产品在线联机帮助。

(3)     相关信息配置完成后,单击<新建>按钮即可成功新建Hive同步任务,此时任务到达调度时间后即可被执行。

图3-58 新建Hive 同步任务

3.5.2  Web 界面配置源集群和目的集群互信

· 新建互信操作必须以root用户执行(即源集群和目的集群的root权限均处于启用状态)。

· 对于要配置互信的集群,不同集群间的主机名称不能重复。

· 对于已配置互信的源集群和目的集群,若当前集群互信无法满足用户需要,对应源集群还需与其他目的集群互信。此时可通过执行添加互信操作,在原有的集群互信基础上,添加对应源集群与其他目的集群的互信。关于添加互信的操作,本章节不再进行说明,详情请参考产品在线联机帮助。

在[运维管理/互信管理]页面,可通过执行新增互信的操作,配置源集群与目的集群(包括同平台集群和自定义集群)互信。

(1)     在运维管理的左侧导航树中选择[互信管理],进入互信管理页面。

(2)     在互信管理页面,单击左上角的<新建>按钮,弹出新建窗口,如 图3-59 所示。

(3)     在新建窗口,根据提示配置对应参数项的值,如下:

¡ 源集群:在下拉框选择当前所在大数据平台管理系统中待执行互信操作的集群。

¡ 同平台集群:在下拉框选择当前所在大数据平台管理系统中的其他集群,支持同时配置多个集群。同平台集群的下拉框选项显示的集群与源集群kerberos安全认证开启状态一致。

¡ 自定义集群:仅可配置为DataEngine大数据管理平台中的集群,即当前所在大数据平台管理系统中的其他集群或其他不同的DataEngine大数据平台中的集群,支持同时配置多个集群。其中:

- 集群名称:输入自定义集群的集群名称。

- 集群IP:输入自定义集群的集群IP,集群IP即集群主节点的IP地址。

- root密码:输入自定义集群root用户密码。

- kerberos安全认证:自定义集群的kerberos安全认证开启状态必须与源集群保持一致。若自定义集群开启了kerberos认证,需勾选;若没有开启,则不进行勾选。

(4)     配置完成后,单击<确定>按钮即可完成源集群与目的集群互信。

图3-59 Web 界面新建源集群目的集群互信

3.5.3  后台配置源集群和目的集群互信

¡ 开启Kerberos认证集群clusterA,kerberos realm为CLUSTERA.COM。

· 目的集群

¡ 开启Kerberos认证集群clusterB,kerberos realm为CLUSTERB.COM。

1. 开启kerberos认证的环境

若源集群和目的集群都开启了Kerberos认证,则集群互信的配置步骤如下:

(1)     检查并修改源集群和目的集群的时区、时间均同步。

(2)     修改源集群和目的集群中所有节点的/etc/hosts文件,要求所有节点的/etc/hosts文件均同时包含源集群和目的集群的所有节点信息(互相拷贝即可)。

(3)     修改源集群和目的集群中所有节点的/etc/krb5.conf文件,要求:

¡ 修改realms,要求同时包含源集群和目的集群的realms内容(互相拷贝即可),如 图3-60 所示。

¡ 修改domain_realm,要求同时包含源集群和目的集群的domain_realm内容。

- 当源集群与目的集群的主机名后缀相同时,需要将domain_realm内容修改为“集群中各节点主机名=对应的realms名”。示例:源集群和备集群的主机名后缀均为.hde.com,则配置如 图3-61 所示。

- 当源集群与目的集群的主机名后缀不同时,则可直接将两个集群的domain_realm中内容合并(不需要修改,直接互相拷贝即可)。示例:源集群的主机名后缀为.hde.com,目的集群的主机名后缀为.hadoop.com,则配置如 图3-62 所示。

图3-60 realms 修改后示例

图3-61 domain_realm 修改后示例(源集群和目的集群主机名后缀相同)

图3-62 domain_realm 修改后示例(源集群和目的集群主机名后缀不同)

在源集群和目的集群的Master节点上,执行添加principal操作。

a.     在源集群Master节点上,分别执行以下两条命令,以添加principal(命令执行后,需要分别输入密码):

kadmin.local -q ' addprinc -e "aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96" krbtgt/[email protected] '

kadmin.local -q ' addprinc -e "aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96" krbtgt/[email protected] '

b.     在目的集群Master节点上,分别执行以下两条命令,以添加principal(命令执行后,需要分别输入密码):

kadmin.local -q ' addprinc -e "aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96" krbtgt/[email protected] '

kadmin.local -q ' addprinc -e "aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96" krbtgt/[email protected] '

注意】

¡ CLUSTERA.COM和CLUSTERB.COM分别为源集群和目的集群的域名,请根据实际情况进行修改。添加principal时需确保两个集群输入的密码相同(即上述四条命令运行后输入的密码均相同),且密码要求至少8位,否则会提示密码太短导致设置无效。

¡ 若添加principal时输入的密码不同,可在源集群和目的集群上进行删除,然后重新执行第4步添加principal的操作。删除命令如下:

kadmin.local -q ' delprinc krbtgt/[email protected]'

kadmin.local -q ' delprinc krbtgt/[email protected]'

(5)     源集群与目的集群互信配置完成后,可登录目的集群进行校验。校验方式示例:在目的集群后台切换至集群超级用户,执行命令hdfs dfs -ls hdfs://<源集群Active NameNode IP地址>:8020/,查看源集群的HDFS是否可正常访问,若能正常访问则表示源集群与目的集群的互信配置成功。

2. 不开kerberos认证的环境

若源集群和目的集群都未开启Kerberos认证,则集群互信的配置步骤如下:

(1)     检查并修改源集群和目的集群的时区、时间均同步。

(2)     修改源集群和目的集群中所有节点的/etc/hosts文件,要求所有节点的/etc/hosts文件均同时包含源集群和目的集群的所有节点信息(互相拷贝即可)。

3.5.4  Hive同步任务相关配置修改

· 开启Kerberos认证的环境

若源集群和目的集群都开启了Kerberos认证,创建Hive同步任务之前,需进行以下配置修改:

¡ 对源集群进行配置修改,说明如下:

在源集群的[集群列表/集群详情/业务组件/HDFS组件详情]页面,修改HDFS配置项hadoop.security.auth_to_local的值。要求在末尾DEFAULT之前增加内容“ RULE:[1:$1@$0](.*@CLUSTERB.COM)s/@.*// ”,其中CLUSTERB.COM为目的集群的域名,请根据实际情况进行修改。此配置项修改完成后,需重启HDFS组件。

¡ 对目的集群进行配置修改,说明如下:

在目的集群的[集群列表/集群详情/业务组件/HDFS组件详情]页面,修改HDFS配置项hadoop.security.auth_to_local的值。要求在末尾DEFAULT之前增加内容“ RULE:[1:$1@$0](.*@CLUSTERA.COM)s/@.*// ”,其中CLUSTERA.COM为源集群的域名,请根据实际情况进行修改。此配置项修改完成后,需重启HDFS组件。

· 不开Kerberos认证的环境

若源集群和目的集群都未开启Kerberos认证,则在集群之间运行Hive同步任务时,不需要进行相关配置的修改。

3.5.5  HDFS 加密区数据同步

无论集群是否开启Kerberos,使用Hive同步任务备份HDFS加密区的数据时,需要在新建Hive同步任务时进行高级配置,将配置项distcp.skip.crc的值设置为true,否则会抛出Checksum mismatch错误。

1. 开启Kerberos认证的环境

若源集群和目的集群都开启了Kerberos认证,在集群之间备份HDFS加密区数据时,需提前进行以下配置修改:

· 对源集群进行配置修改,说明如下:

在源集群的[集群列表/集群详情/系统组件/RANGER_KMS组件详情]页面,修改RANGER_KMS配置项hadoop.kms.authentication.kerberos.name.rules的值。要求在末尾DEFAULT之前增加内容“ RULE:[1:$1@$0](.*@CLUSTERB.COM)s/@.*// ”,其中CLUSTERB.COM为目的集群的域名,请根据实际情况进行修改。此配置项修改完成后,需重启RANGER_KMS组件。

· 对目的集群进行配置修改,说明如下:

在目的集群的[集群列表/集群详情/系统组件/RANGER_KMS组件详情]页面,修改RANGER_KMS配置项hadoop.kms.authentication.kerberos.name.rules的值。要求在末尾DEFAULT之前增加内容“RULE:[1:$1@$0](.*@CLUSTERA.COM)s/@.*// ”,其中CLUSTERA.COM为源集群的域名,请根据实际情况进行修改。此配置项修改完成后,需重启RANGER_KMS组件。

2. 不开启Kerberos认证的环境

若源集群和目的集群都未开启Kerberos认证,则在集群之间备份HDFS加密区数据时,不需要进行相关配置的修改。

3.5.6  Hive 备份恢复示例

示例:两个集群在一个系统中,均开启Kerberos和安全管理,按照 3.5.1  1. 前提条件 配置完互信及Hive相关配置后,将源集群中的一个数据库同步到目的集群。

(1)     在目的集群后台切换至hdfs用户,查看源集群的HDFS是否可正常访问,如所示表明可正常访问说明源集群与目的集群互信配置成功:

图3-63 集群互信

(2)     新建同步任务,填写开始时间、同步周期、目的集群地址等信息,默认选择任务执行集群为目的集群(不会影响源集群的业务),具体填写规则请参见联机帮助。单击<校验>按钮可获取任务执行队列,根据进行情况选取即可。

图3-64 新建同步任务

(3)     任务在调度时间会自动执行,也可手动单击<启动>执行即时备份,在<更多/运行记录>中可查看执行记录及日志详情。

图3-65 查看执行结果

图3-66 查看运行记录

(4)     登录到目的集群,可查看数据库表同步的数据正常。

图3-67 同步成功

3.6  LDAP 认证

HiveServer2支持多种认证方式,包括none、ldap、kerberos、pam、custom,通过hive.server2.authentication参数可设置认证方式。

开启LDAP认证,需要修改如 表3-7 所示的高级配置,并在Hive组件的自定义配置hive-site下新增如 表3-8 所示配置。

表3-7 修改配置项

开启LDAP认证后,在连接集群中包含Hive Client的某台机器时,需指定参数进行连接:

beeline -u "jdbc:hive2://<HiveServer2地址>:10000/" -n hive -p "password"

· -u:指定连接HiveServer2的地址和端口号。

· -n:指定连接所需用户名。

· -p:指定连接所需密码(使用LDAP认证时,需正确填写用户对应的密码。其他情况可为空值)。

3.7  事务 性操作

3.7.1  ACID 的含义和使用

数据库事务具有四个特性,即ACID。各特性含义如下:

· 原子性(Atomicity):一个事务是一个不可分割的工作单位,事务中包含的操作要么都执行,要么都不执行。

· 一致性(Consistency):事务必须是使数据库从一个一致性状态变为另一个一致性状态。

· 隔离性(Isolation):一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不会互相干扰。

· 持久性(Durability):指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。后续的其他操作或故障不应该对其有任何影响。

Hive支持事务,能支持行级的ACID,因此,在同一个分区中,一个应用在进行读操作时,另一个应用能进行新增操作,而不会相互影响。

Hive支持事务的特性能用于以下情况:

· 流数据的采集

· 数据的修改,包括INSERT、UPDATE和DELETE

Hive中对事务的支持具有以下限制:

· 不支持BEGIN、COMMIT和ROLLBACK,所有的操作都是自动提交

· 目前只有存储格式为ORC文件的才能支持事务

· 使用事务的表必须是分桶表

· 目前只支持快照级别的隔离

· 事务不能与已有的ZooKeeper和in-memory lock managers兼容

· 对于建表时已经指明了支持ACID属性的数据表,不能使用ALTER TABLE语句修改模式定义

3.7.2  开启事务

Hive中的事务默认关闭,开启事务前需要进行相关参数的设置,参数相关配置如 表3-9 所示。

表3-9 开启事务的相关参数配置

· 为了使数据表支持ACID,建表时必须将表的transactional属性设置为true。

· 建表语句必须带有into buckets子句和stored as orc tblproperties('transactional'='true')子句,但不能带有stored by子句。

· 使用insert命令向表中插入数据示例:

insert into table t1 values(1,"string1");

insert into table t1 values(2,"string2");

insert into table t1 values(3,"string3");

insert into table t1 values(4,"string4");

· 使用update命令修改表中数据示例:

update t1 set name = "string33" where id = 3;

· 使用delete命令删除表中数据示例:

delete from t1 where id = 4;

3.8  HiveServer2 高可用功能

安装Hive时,若集群开启高可用则默认会在两个节点上安装HiveServer2,以提供HA功能。

HiveServer2启动后会向Zookeeper注册临时节点,当用户以JDBC方式连接HiveServer2时,Hive会随机选择一个节点上的HiveServer2与用户建立连接。若当前连接节点上的HiveServer2服务挂掉后,Hive会自动将连接切换到其它节点的HiveServer2上。

使用HA时,JDBC的url是jdbc:hive2://<zk集群地址>/;serviceDiscoveryMode=zooKeeper; zooKeeperNamespace=[hive.server2.zookeeper.namespace参数值]。其中,zk集群地址格式为“zk_node1host:zk_node1port,...”。

1. HiveServer2使用HA示例

(1)     在集群中节点上安装多个HiveServer2并启动。在Zookeeper上可以看到注册的znode信息为:

[root@node1 ~]# zookeeper-client -server node1:2181

[zk: localhost:2181(CONNECTED) 0] ls /hiveserver2

[serverUri=node1.hde.com:10000;version=2.1.1-cdh6.2.0;sequence=0000000007, serverUri=node2.hde.com:10000;version=2.1.1-cdh6.2.0;sequence=0000000006]

(2)     使用beeline连接HiveServer2,示例代码如下:

[root@node1 ~]#beeline –u “jdbc:hive2://node1:2181,node2:2181,node3:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2” –n hive –p “”

2020-02-12 15:51:41,477 INFO  jdbc.Utils (Utils.java:parseURL(443)) - Resolved authority: node1.hde.com:10000

2020-02-12 15:51:41,591 INFO  jdbc.HiveConnection (HiveConnection.java:logZkDiscoveryMessage(799)) - Connected to node1.hde.com:10000

2020-02-12 15:51:41,694 WARN  curator.CuratorZookeeperClient (CuratorZookeeperClient.java:<init>(96)) - session timeout [3000] is less than connection timeout [15000]

Connected to: Apache Hive (version 2.1.1-cdh6.2.0)

Driver: Hive JDBC (version 2.1.1-cdh6.2.0)

Transaction isolation: TRANSACTION_REPEATABLE_READ

1: jdbc:hive2://node1:2181,node2:2181/> create table mltable(id double,label double);

No rows affected (0.796 seconds)

1: jdbc:hive2://node1:2181,node2:2181/> show tables;

+-----------+--+

| tab_name  |

+-----------+--+

| mltable   |

+-----------+--+

1 row selected (0.211 seconds)

(3)     通过Beeline日志信息,可以看到此次连接了node1节点的HiveServer2。用户可以手动将node1节点HiveServer2停掉,在Beeline中再次尝试执行SQL语句:

1: jdbc:hive2://node1:2181,node2:2181/> show tables;

+-----------+--+

| tab_name  |

+-----------+--+

| mltable   |

+-----------+--+

1 row selected (0.211 seconds)

可以看到,用户不需重新连接,JDBC连接仍然有效。

3.9  Hive 分区表生命周期管理

在Hive中支持对分区表的数据生命周期管理,为分区数据设置过期时间,定期释放过期分区存储空间,简化数据回收过程。

3.9.2  使用限制

· 仅支持分区表使用,非分区表进行忽略

· 分区过期检测周期为周期性操作。分区过期检测周期全局有效,不支持对单独的表设置,并且在检测周期时间内数据清理存在延迟

· 生命周期时间只支持天,且只能为整数

· 分区生命周期过期功能属于高风险操作,使用前需要充分了解,确定生命周期之外的分区数据不再使用后再进行配置,避免数据误清理

3.9.3  使用说明

1. 分区生命周期设置语法

创建表时支持指定TBLPROPERTIES属性,不增加Hive语法,指定lifecycle参数,注意设定lifecycle后需要开启hive.partition.expire.on才可生效。

(1)     创建分区表时设置分区生命周期

创建表时通过TBLPROPERTIES指定lifecycle属性:

CREATE TABLE <table_name> (<col_name> <data_type>, <col_name> <data_type>, …) PARTITIONED BY (<col_name> <data_type>) TBLPROPERTIES('lifecycle'='days');

注:lifecycle为表属性,days为天数,只支持整数。

操作示例

a.     创建分区表testlifecycle01,并指定lifecycle属性值为1,如 图3-69 所示。执行命令如下:

create table testlifecycle01(id int,name string) partitioned by (age int,dept string,score int) tblproperties('lifecycle'='1');

图3-69 创建分区表并设置lifecycle

(2)     查询表分区生命周期

针对已经创建好的表或者设置过lifecycle的表,需要查询lifecycle参数:

desc formatted <table_name>;

操作示例

a.     查询testlifecycle01分区表lifecycle参数值,如 图3-70 所示。执行命令如下:

desc formatted testlifecycle01;

图3-70 查询lifecycle

(3)     修改表分区生命周期

针对已经创建好的表或者设置过lifecycle表,需要增加或修改lifecycle参数:

ALTER TBALE <table_name> SET TBLPROPERTIES('lifecycle'='300');

示例操作

a.     修改testlifecycle01分区表lifecycle参数值,如 图3-71 所示。执行命令如下:

alter table testlifecycle01 set tblproperties('lifecycle'='3');

b.     修改lifecycle参数值后,执行查询结果如 图3-72 所示。

图3-71 修改lifecycle

图3-72 修改后查询lifecycle

(4)     删除表分区生命周期

由于Hive中属性一旦设置不可删除,通过设置lifecycle为-1可以忽略过期:

ALTER TBALE <table_name> SET TBLPROPERTIES('lifecycle'='-1');

示例操作

a.     设置testlifecycle01分区表lifecycle为-1,如 图3-73 所示。命令如下:

alter table testlifecycle01 set tblproperties('lifecycle'='-1');

b.     修改lifecycle参数值后,执行查询结果如 图3-74 所示。

图3-73 修改lifecycle

图3-74 查询lifecycle 参数

2. 分区清理规则

分区过期检查线程默认每小时(3600s)会执行一次,查找设置分区lifecycle表,并根据当前时间与分区数据最后一次更新时间进行比对,超过生命周期时间分区会被清理。

示例操作

(1)     创建分区表并设置生命周期,然后查询分区表

a.     创建分区表testlifecycle01,并指定lifecycle属性值为1,命令如下:

create table testlifecycleceshi(id int,name string) partitioned by (age int,dept string,score int) tblproperties('lifecycle'='1');

b.     查询表testlifecycleceshi,如 图3-75 所示,命令如下:

select * from testlifecycleceshi;

图3-75 分区表创建后查询表

(2)     在表中插入数据

a.     对testlifecycle01分区表执行插入数据操作,命令如下:

insert into table testlifecycleceshi partition(age='19',dept='IS',score='85') values ('95002','liyong1');

insert into table testlifecycleceshi partition(age='20',dept='IS',score='86') values ('95002','liyong2');

insert into table testlifecycleceshi partition(age='21',dept='IS',score='87') values ('95002','liyong3');

insert into table testlifecycleceshi partition(age='22',dept='IS',score='88') values ('95002','liyong4');

insert into table testlifecycleceshi partition(age='23',dept='IS',score='89') values ('95002','liyong5');

insert into table testlifecycleceshi partition(age='23',dept='IS',score='90') values ('95002','liyong6');

b.     数据插入成功后,执行查询表操作,如 图3-76 所示。

图3-76 插入数据后查询表

(3)     到生命周期设置的时间后,超过生命周期时间分区会被清理,查询表结果如 图3-77 所示。

图3-77 到生命周期设置时间后查询表

3.10  HQL 操作

语法说明:

CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name

[(col_name data_type [column_constraint_specification] [COMMENT col_comment], ... [constraint_specification])]

[COMMENT table_comment]

[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]

[CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]

[SKEWED BY (col_name, col_name,

ON ((col_value, col_value, ...), (col_value, col_value, ...), ...)

[STORED AS DIRECTORIES]

[ROW FORMAT row_format]

[STORED AS file_format]

| STORED BY 'storage.handler.class.name' [WITH SERDEPROPERTIES (...)]

[LOCATION hdfs_path]

[TBLPROPERTIES (property_name=property_value, ...)]

[AS select_statement];

创建表主要有以下三种方式:

· 自定义表结构,以关键字EXTERNAL来区分创建内部表或外部表。

¡ 内部表:如果对数据的处理都由Hive完成,则应该使用内部表。在删除内部表时,元数据和数据一起被删除。

¡ 外部表:如果数据要被多种工具(如Pig等)共同处理,则应该使用外部表,可避免对该数据的误操作。删除外部表时,只删除掉元数据。

· 根据已有表来创建新表,使用CREATE LIKE句式,可以完全复制原有的表结构,包括表的存储格式。

· 根据查询结果创建新表,使用CREATE AS SELECT句式。

2. Hive数据类型

Hive中的数据类型包括基本数据类型和复杂数据类型。

表3-12 基本数据类型

整数(距离UNIX新纪元时间的秒数)、浮点数(距离UNIX新纪元时间的秒数,精确到纳秒)或字符串(JDBC约定的时间字符串格式:YYYY-­MM-­DD hh:mm:ss:fffffffff)

日期,格式为YYYY-­MM-­DD,DATE类型只能和DATE、TIMESTAMP、STRING相互转换

STRING

字符串,可使用单引号或双引号

VARCHAR

指定长度的字符串

指定长度,长度不够会以空格填充

BOOLEAN

布尔类型,true或false

BINARY

表3-13 复杂数据类型

3. 创建表示例

(1)     内部表创建,执行如下命令:

create table employees(name string, salary float, address string) row format delimited fields terminated by ',' stored as textfile;

¡ "delimited fields terminated by"用于指定列与列之间的分隔符

¡ “stored as textfile”用于指定表的存储格式为textfile

(2)     外部表创建,执行如下命令:

create external table stocks(sysbol string, price_open float, price_colse float ) ;

(3)     使用CREATE Like创建表,执行如下命令:

create table employees_like LIKE employees;

4. 扩展

· 创建分区表

一个表可以拥有一个或者多个分区,每个分区以文件夹的形式单独存在表文件夹的目录下。对分区内数据进行查询,可缩小查询范围,加快数据的检索速度和可对数据按照一定的条件进行管理。

分区可在创建表时用PARTITIONED BY子句进行定义。

CREATE EXTERNAL TABLE IF NOT EXISTS employees_info_extended

id INT,

name STRING,

usd_flag STRING,

salary DOUBLE,

deductions MAP<STRING, DOUBLE>,

address STRING

)  PARTITIONED BY (entrytime STRING)

STORED AS TEXTFILE;

· 更新表的结构

一个表在创建完成后,还可以使用ALTER TABLE执行增/删字段、修改表属性以及添加分区等操作。例如为表employees_info_extended增加tel_phone和email字段。执行如下命令:

ALTER TABLE employees_info_extended ADD COLUMNS (tel_phone STRING, email STRING);

3.10.2  数据加载

1. 概述

使用HQL可以向已有的表中加载数据。数据加载中可以从本地文件系统、HDFS集群中加载数据,以关键字LOCAL来区分数据源是否来自本地。

加载数据语句中有关键字LOCAL,表明从本地加载数据,除要求对相应表的UPDATE权限外,还要求该数据在当前连接的HiveServer节点上。

· LOCAL模式和HDFS模式都需要用户拥有文件的所有者权限。

· 如果加载数据语句中有关键字OVERWRITE,表示加载的数据会覆盖表中原有的数据,否则加载的数据会追加到表中。

语法说明:

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]

【注意】Hive使用LOAD DATA LOCAL INPATH时,要求数据文件必须与所连接的HiveServer2服务在同一个节点。

2. 数据加载示例

数据加载示例操作步骤如下:

(1)     在HDFS上创建文件/hivetest/employee.txt文件

(2)     将/hivetest/employee.txt文件加载至employees表中,执行如下命令:

LOAD DATA INPATH '/hivetest/employee.txt ' OVERWRITE INTO TABLE employees;

(3)     查询employees中的数据,执行如下命令:

Select * from employees;

图3-78 执行结果

3.10.3  数据查询

1. 概述

使用HQL可以对数据进行查询分析。查询分析方法有:

· SELECT查询的常用特性,如JOIN等。

· 加载数据至指定分区。

· 使用Hive自带函数。

· 使用自定义函数。

[WITH CommonTableExpression (, CommonTableExpression)*]

SELECT [ALL | DISTINCT] select_expr, select_expr, ...

FROM table_reference

[WHERE where_condition]

[GROUP BY col_list]

[ORDER BY col_list]

[CLUSTER BY col_list

| [DISTRIBUTE BY col_list] [SORT BY col_list]

[LIMIT [offset,] rows]

2. 数据查询示例

(1)     查询name列的数据,执行如下语句:

SELECT name from employees;

(2)     使用Hive自带函数COUNT(),统计表employees中有多少条记录,执行如下语句:

SELECT COUNT(*) FROM employees_info_extended;

3.10.4  视图操作

Hive View具有以下特点:

· View是逻辑存在。

· View只读,且不支持LOAD/INSERT/ALTER。需要改变View定义时,可以使用Alter View。

· View内可能包含OPDER BY/LIMIT语句,若一个对View的查询包含这些语句,则该语句优先级高。

· Hive支持迭代视图。

· Hive中的视图查询和普通查询类似,查询时把表名更换为视图名即可。

· 语法说明:

CREATE VIEW [IF NOT EXISTS] [db_name.]view_name [(column_name [COMMENT column_comment], ...) ]

[COMMENT view_comment]

[TBLPROPERTIES (property_name = property_value, ...)]

AS SELECT ...;

2. 视图操作示例

(1)     创建视图,执行如下命令:

create view employees_name_info as select name from employees;

(2)     查询视图,执行如下命令:

select * from employees_name_info;

(3)     删除视图,执行如下命令:

drop view employees_name_info;

3.10.5  函数介绍

Hive提供了丰富的函数操作,详情请参考Hive官网 https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF

· 使用 Show functions 命令可以列举出当前Hive会话中所加载的函数名称,包括内置的和用户加载进来的函数。

· 系统函数通常都有其自身的使用文档,使用 describe function 命令可以查看对应函数的简短介绍。

¡ 执行命令:describe function abs;

¡ 执行结果:abs(x) - returns the absolute value of x

· 关于函数更多的详细文档,可以在 describe function 命令中使用 extended 关键字来查看。

¡ 执行命令:describe function extended abs;

¡ 执行结果如 图3-79 所示。

图3-79 abs 函数详细文档

下面介绍Hive内置的部分系统函数。

表3-14 数学函数

conv(BIGINT num, INT from_base, INT to_base), conv(STRING num, INT from_base, INT to_base)

将GIGINT/STRING类型的num从from_base进制转换成to_base进制

DOUBLE

abs(DOUBLE a)

计算a的绝对值

INT or DOUBLE

pmod(INT a, INT b), pmod(DOUBLE a, DOUBLE b)

a对b取模

DOUBLE

sin(DOUBLE a), sin(DECIMAL a)

求a的正弦值

DOUBLE

asin(DOUBLE a), asin(DECIMAL a)

求a的反正弦值

DOUBLE

cos(DOUBLE a), cos(DECIMAL a)

DOUBLE

acos(DOUBLE a), acos(DECIMAL a)

求反余弦值

DOUBLE

tan(DOUBLE a), tan(DECIMAL a)

DOUBLE

atan(DOUBLE a), atan(DECIMAL a)

求反正切值

DOUBLE

degrees(DOUBLE a), degrees(DECIMAL a)

将弧度值转换成角度值

DOUBLE

radians(DOUBLE a), radians(DOUBLE a)

将角度值转换成弧度值

INT or DOUBLE

positive(INT a), positive(DOUBLE a)

INT or DOUBLE

negative(INT a), negative(DOUBLE a)

返回a的相反数

DOUBLE or INT

sign(DOUBLE a), sign(DECIMAL a)

如果a是正数则返回1.0,是负数则返回-1.0,否则返回0.0

DOUBLE

数学常数e

DOUBLE

数学常数pi

BIGINT

factorial(INT a)

求a的阶乘

DOUBLE

cbrt(DOUBLE a)

求a的立方根

INT BIGINT

shiftleft(TINYINT|SMALLINT|INT a, INT b)

shiftleft(BIGINT a, INT b)

BIGINT

shiftright(TINYINT|SMALLINT|INT a, INTb)

shiftright(BIGINT a, INT b)

BIGINT

shiftrightunsigned(TINYINT|SMALLINT|INTa, INT b),

shiftrightunsigned(BIGINT a, INT b)

无符号按位右移

greatest(T v1, T v2, ...)

least(T v1, T v2, ...)

表3-15 集合函数

将时间的秒值转换成format格式(format可为“yyyy-MM-dd hh:mm:ss”,“yyyy-MM-dd hh”,“yyyy-MM-dd hh:mm”等等),如from_unixtime(1250111000,"yyyy-MM-dd") 得到2009-03-12

bigint

unix_timestamp()

获取本地时区下的时间戳

bigint

unix_timestamp(string date)

将格式为yyyy-MM-dd HH:mm:ss的时间字符串转换成时间戳,如unix_timestamp('2009-03-20 11:30:01') = 1237573801

bigint

unix_timestamp(string date, string pattern)

将指定时间字符串格式字符串转换成Unix时间戳,如果格式不对返回0,如:unix_timestamp('2009-03-20', 'yyyy-MM-dd') = 1237532400

string

to_date(string timestamp)

返回时间字符串的日期部分

year(string date)

返回时间字符串的年份部分

quarter(date/timestamp/string)

返回当前时间属于哪个季度,如quarter('2015-04-08') = 2

month(string date)

返回时间字符串的月份部分

day(string date) dayofmonth(date)

返回时间字符串的天

hour(string date)

返回时间字符串的小时

minute(string date)

返回时间字符串的分钟

second(string date)

返回时间字符串的秒

weekofyear(string date)

返回时间字符串位于一年中的第几个周内 如weekofyear("1970-11-01 00:00:00") = 44, weekofyear("1970-11-01") = 44

datediff(string enddate, string startdate)

计算开始时间startdate到结束时间enddate相差的天数

string

date_add(string startdate, int days)

从开始时间startdate加上days

string

date_sub(string startdate, int days)

从开始时间startdate减去days

timestamp

from_utc_timestamp(timestamp, string timezone)

如果给定的时间戳并非UTC,则将其转化成指定的时区下时间戳

timestamp

to_utc_timestamp(timestamp, string timezone)

如果给定的时间戳是指定时区下时间戳,则将其转化成UTC下的时间戳

current_date

返回当前时间日期

timestamp

current_timestamp

返回当前时间戳

string

add_months(string start_date, int num_months)

返回当前时间下再增加num_months个月的日期

string

last_day(string date)

返回这个月的最后一天的日期,忽略时分秒部分(HH:mm:ss)

string

next_day(string start_date, string day_of_week)

返回当前时间的下一个星期X所对应的日期 如:next_day('2015-01-14', 'TU') = 2015-01-20 以2015-01-14为开始时间,其下一个星期二所对应的日期为2015-01-20

string

trunc(string date, string format)

返回时间的最开始年份或月份,如trunc("2016-06-26",“MM”)=2016-06-01  trunc("2016-06-26",“YY”)=2016-01-01,注意所支持的格式为MONTH/MON/MM, YEAR/YYYY/YY

double

months_between(date1, date2)

返回date1与date2之间相差的月份,如date1>date2,则返回正,如果date1<date2,则返回负,否则返回0.0,如:months_between('1997-02-28 10:30:00', '1996-10-30') = 3.94959677 1997-02-28 10:30:00与1996-10-30相差3.94959677个月

string

date_format(date/timestamp/string ts, string fmt)

按指定格式返回时间date 如:date_format("2016-06-22","MM-dd")=06-22

表3-18 条件函数

使用指定的字符集charset将二进制值bin解码成字符串,支持的字符集有:'US-ASCII', 'ISO-8859-1', 'UTF-8', 'UTF-16BE', 'UTF-16LE', 'UTF-16',如果任意输入参数为NULL都将返回NULL

binary

encode(string src, string charset)

使用指定的字符集charset将字符串编码成二进制值,支持的字符集有:'US-ASCII', 'ISO-8859-1', 'UTF-8', 'UTF-16BE', 'UTF-16LE', 'UTF-16',如果任一输入参数为NULL都将返回NULL

find_in_set(string str, string strList)

返回以逗号分隔的字符串中str出现的位置,如果参数str为逗号或查找失败将返回0,如果任一参数为NULL将返回NULL回

string

format_number(number x, int d)

将数值X转换成"#,###,###.##"格式字符串,并保留d位小数,如果d为0,将进行四舍五入且不保留小数

string

get_json_object(string json_string, string path)

从指定路径上的JSON字符串抽取出JSON对象,并返回这个对象的JSON格式,如果输入的JSON是非法的将返回NULL。

注意: 此路径上JSON字符串只能由数字、字母、下划线组成且不能有大写字母和特殊字符,且key不能由数字开头,这是由于Hive对列名的限制

boolean

in_file(string str, string filename)

如果文件名为filename的文件中有一行数据与字符串str匹配成功就返回true

instr(string str, string substr)

查找字符串str中子字符串substr出现的位置,如果查找失败将返回0,如果任一参数为Null将返回null

注意 :位置为从1开始

length(string A)

返回字符串的长度

locate(string substr, string str[, int pos])

查找字符串str中的pos位置后字符串substr第一次出现的位置

string

lower(string A) lcase(string A)

将字符串A的所有字母转换成小写字母

string

lpad(string str, int len, string pad)

从左边开始对字符串str使用字符串pad填充,最终len长度为止,如果字符串str本身长度比len大的话,将去掉多余的部分

string

ltrim(string A)

去掉字符串A前面的空格

array<struct<string,double>>

ngrams(array<array<string>>, int N, int K, int pf)

返回出现次数TOP K的的子序列,n表示子序列的长度

string

parse_url(string urlString, string partToExtract [, string keyToExtract])

返回从URL中抽取指定部分的内容,参数url是URL字符串,而参数partToExtract是要抽取的部分,这个参数包含(HOST, PATH, QUERY, REF, PROTOCOL, AUTHORITY, FILE, and USERINFO,例如:parse_url('http://facebook.com/path1/p.php?k1=v1&k2=v2#Ref1', 'HOST') ='facebook.com',如果参数partToExtract值为QUERY则必须指定第三个参数key 如:parse_url('http://facebook.com/path1/p.php?k1=v1&k2=v2#Ref1', 'QUERY', 'k1') =‘v1’

string

printf(String format, Obj... args)

按照printf风格格式输出字符串

string

regexp_extract(string subject, string pattern, int index)

抽取字符串subject中符合正则表达式pattern的第index个部分的子字符串。

注意预定义字符的使用,如第二个参数如果使用'\s'将被匹配到s,'\\s'才是匹配空格

string

regexp_replace(string INITIAL_STRING, string PATTERN, string REPLACEMENT)

按照正则表达式PATTERN将字符串INTIAL_STRING中符合条件的部分成REPLACEMENT所指定的字符串,如里REPLACEMENT这空的话,抽符合正则的部分将被去掉,如:regexp_replace("foobar", "oo|ar", "") = 'fb.'注意预定义字符的使用,如第二个参数如果使用'\s'将被匹配到s,'\\s'才是匹配空格

string

repeat(string str, int n)

重复输出n次字符串str

string

reverse(string A)

反转字符串

string

rpad(string str, int len, string pad)

从右边开始对字符串str使用字符串pad填充,最终len长度为止,如果字符串str本身长度比len大的话,将去掉多余的部分

string

rtrim(string A)

去掉字符串后面出现的空格

array<array<string>>

sentences(string str, string lang, string locale)

字符串str将被转换成单词数组,如:sentences('Hello there! How are you?') =( ("Hello", "there"), ("How", "are", "you") )

string

space(int n)

返回n个空格

array

split(string str, string pat)

按照正则表达式pat来分割字符串str,并将分割后的数组字符串的形式返回

map<string,string>

str_to_map(text[, delimiter1, delimiter2])

将字符串str按照指定分隔符转换成Map,第一个参数是需要转换字符串,第二个参数是键值对之间的分隔符,默认为逗号;第三个参数是键值之间的分隔符,默认为"="

string

substr(string|binary A, int start) substring(string|binary A, int start)

对于字符串A,从start位置开始截取字符串并返回

string

substr(string|binary A, int start, int len) substring(string|binary A, int start, int len)

对于二进制/字符串A,从start位置开始截取长度为length的字符串并返回

string

substring_index(string A, string delim, int count)

截取第count分隔符之前的字符串,如count为正则从左边开始截取,如果为负则从右边开始截取

string

translate(string|char|varchar input, string|char|varchar from, string|char|varchar to)

将input出现在from中的字符串替换成to中的字符串 如:translate("MOBIN","BIN","M")="MOM"

string

trim(string A)

将字符串A前后出现的空格去掉

binary

unbase64(string str)

将64位的字符串转换二进制值

string

upper(string A) ucase(string A)

将字符串A中的字母转换成大写字母

string

initcap(string A)

将字符串A的每个单词转换为首字母大写的字符串

levenshtein(string A, string B)

计算两个字符串之间的差异大小,如:levenshtein('kitten', 'sitting') = 3

string

soundex(string A)

将普通字符串转换成soundex字符串

表3-20 聚合函数

3.11  JDBC 方式连接HiveServer2

除了使用beeline命令提交HQL语句外,还可以使用JDBC方式连接HiveServer2。

通过JDBC方式连接HiveServer2,并对表进行创建和查询操作。操作步骤如下:

(1)     建立maven工程

Pom.xml文件内容:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>com.test.hive</groupId>

<artifactId>hiveDemo</artifactId>

<version>1.0</version>

<dependencies>

<dependency>

<groupId>org.apache.hive</groupId>

<artifactId>hive-jdbc</artifactId>

<version>2.1.1-cdh6.2.0</version>

</dependency>

</dependencies>

<build>

<plugins>

<plugin>

<artifactId>maven-assembly-plugin</artifactId>

<configuration>

<descriptorRefs>

<descriptorRef>jar-with-dependencies</descriptorRef>

</descriptorRefs>

<archive>

<manifest>

<mainClass>HIVE_JDBC.Hive_JDBC</mainClass>

</manifest>

</archive>

</configuration>

<executions>

<execution>

<id>make-assembly</id>

<phase>package</phase>

<goals>

<goal>single</goal>

</goals>

</execution>

</executions>

</plugin>

</plugins>

</build>

</project>

(2)     准备建立连接参数

· 非Kerberos环境

private static String driveName = "org.apache.hive.jdbc.HiveDriver" ;
//开启kerberos的集群环境,请根据实际环境修改配置
private static String url = "jdbc:hive2://192.168.0.1:10000/default";
private static String user = "hive";

private static String passwd = null;

private static String sql =

private static ResultSet res;

private static ResultSetMetaData m;

· Kerberos环境

private static String driveName = "org.apache.hive.jdbc.HiveDriver" ;
//开启kerberos的集群环境,请根据实际环境修改配置
private static String url = "jdbc:hive2://192.168.0.1:10000/default;principal=hive/[email protected] private static String user = "user1";

private static String passwd = null;

private static String sql =

private static ResultSet res;

private static ResultSetMetaData m;

· 参数(user和url地址)需要根据具体环境设计,url参数需要填写hiveServer2的连接地址

· Kerberos环境下的principal配置值请参考 2.3.2 Kerberos环境

(3)     建立连接

· 非Kerberos环境

private static Connection getConnection() throws ClassNotFoundException,SQLException{
Class.forName(driveName);
Connection con = DriverManager.getConnection(url,user,passwd);
System.out.println("connection success!");
return con;

· Kerberos环境

private static Connection getConnection() throws ClassNotFoundException,SQLException{
String krb5ConfPath = "./krb5.conf";
String keytabPath = "./user1.keytab";
String principalName = "[email protected] ";
//Kerberos身份认证,请将集群中krb5.conf及keytab文件放入该工程resource文件夹中
org.apache.hadoop.conf.Configuration conf = new org.apache.hadoop.conf.Configuration();
conf.set("hadoop.security.authentication", "Kerberos");

//获取krb5.conf配置
if(System.getProperty("os.name").toLowerCase().startsWith("win"))         System.setProperty("java.security.krb5.conf", Hive_JDBC.class.getClassLoader().getResource(krb5ConfPath).getPath());
//进行身份认证
UserGroupInformation.setConfiguration(conf);
UserGroupInformation.loginUserFromKeytab(principalName, Hive_JDBC.class.getClassLoader().getResource(keytabPath).getPath());
}catch(IOException e1){
e1.printStackTrace();
Class.forName(driveName);
Connection con = DriverManager.getConnection(url,user,passwd);
System.out.println("connection success!");
return con;

(4)     对表进行操作

private static void dropTable(Statement stm, String tableName)throws SQLException{
sql = "drop table if exists "+tableName;
System.out.println("Running:"+sql);
stm.executeUpdate(sql);
private static void createTable(Statement stm, String tableName)throws SQLException{
sql = "create table if not exists "+tableName+" (stuid string, name string, sex string, age int)"
+" row format delimited fields terminated by '\t'"
+ " lines terminated by '\n' "
+ " stored as textfile";
System.out.println("Running:"+sql);
stm.executeUpdate(sql);
private static void showTables(Statement stm, String tableName)throws SQLException{
sql = "show tables in default";
System.out.println("Running:"+sql);
res = stm.executeQuery(sql);
System.out.println("执行 show tables 的运行结果如下:");
m=res.getMetaData();
int columns=m.getColumnCount();
while(res.next())
for(int i=1;i<=columns;i++)
System.out.print(res.getString(i)+"\t\t");
System.out.println();

private static void describeTale(Statement stm, String tableName)throws SQLException{

sql = "describe " + tableName;

System.out.println("Running:"+sql);

res = stm.executeQuery(sql);

System.out.println("执行 describe table 的运行结果如下:");

while (res.next()) {

System.out.println(res.getString(1) + "\t" + res.getString(2));

private static void selectData(Statement stm, String tableName)throws SQLException{

sql = "select * from "+tableName;

System.out.println("Running:"+sql);

res = stm.executeQuery(sql);

System.out.println("执行 select *  的运行结果如下:");

while (res.next()) {

System.out.println(res.getString(1) + "\t" + res.getString(2)+ "\t" + res.getString(3)+ "\t" + res.getString(4));

(5)     主类操作

import org.apache.hadoop.security.UserGroupInformation;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;

public static void main(String[] args){
Connection con = null;
Statement stm = null;
con = getConnection();//创建连接
stm = con.createStatement();
String tableName = "stu2";
dropTable(stm,tableName);//若表存在则先删除表
createTable(stm,tableName);//若表不存在则新建
showTables(stm, tableName);//查看当前数据库下的所有表
describeTale(stm, tableName);//查看创建的表的表结构
selectData(stm, tableName);//全表查询
}catch (ClassNotFoundException e){
e.printStackTrace();
System.out.println(driveName + " not found! ");
System.out.println(e.getMessage());
}catch (SQLException e1){
e1.printStackTrace();
System.out.println("connection error! ");
System.out.println(e1.getMessage());
}finally {
if(res!=null){
res.close();
res=null;
if(stm!=null){
stm.close();
stm=null;
if(con!=null){
con.close();
con=null;
}catch (SQLException e2){
e2.printStackTrace();
System.out.println("close connection or statement error!             System.out.println(e2.getMessage());

(6)     打包运行

a.     将步骤(1)中的maven工程进行编译打包,生成的带依赖的jar包(hiveDemo-1.0-jar-with-dependencies.jar)

b.     在客户端服务器上,执行如下命令:

hadoop jar hiveDemo-1.0-jar-with-dependencies.jar HIVE_JDBC.Hive_JDBC

4.1  Hive 操作HBase表

4.1.1  概述

Hive中的StorageHandlers功能不但可以让Hive基于HBase实现,还可以支持基于Cassandra、Azure Table、JDBC(MYSQL and others)、MongoDB、ElasticSearch、Phoenix HBase、VoltDB和Google Spreadsheets等实现。

Hive的StorageHandlers原理是基于Hive以及Hadoop的可扩展性:

· 输入格式化

· 输出格式化

· 序列化/反序列化包

StorageHandlers基于以上可扩展性外,还需实现元数据勾子接口,此接口允许使用Hive的DDL语句定义和管理Hive元数据及其它系统的目录。

通过StorageHandlers,可以实现Hive与HBase的整合。Hive与HBase的整合是利用两者本身对外的API接口相互通信来实现,相互通信主要是依靠hive-hbase-handler.jar工具类(Hive Storage Handlers),即Hive Storage Handlers负责HBase和Hive之间的通信。

4.1.2  操作示例

1. 示例一:在Hive中新建表,并关联到HBase,通过向Hive表插入数据来向关联的HBase表中插入数据。

(1)     在Hive中创建HBase相关联的的表。执行如下命令:

CREATE TABLE hive_table(key int, value string)

STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'

WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,cf1:val")

TBLPROPERTIES ("hbase.table.name"= "hbase_table") ;

其中,hbase.table.name用于定义在HBase中的table名称,hbase.columns.mapping用于定义HBase中的列族。

(2)     在Hive中创建新表(步骤(1)Hive中创建的与HBase整合的表不支持load data导入数据)。

create table pokes (foo int, bar string) row format delimited fields terminated by ',' stored as textFile;

(3)     将数据文件1.txt上传到HDFS,然后向新表中导入数据:

load data inpath '/tmp/1.txt' overwrite into table pokes;

(4)     将数据导入到hive_table中,执行如下命令:

insert overwrite table hive_table select * from pokes;

(5)     可以在Hive中查看导入的数据。

(6)     进入HBase shell控制台,可以查看表hbase_table的表结构,查询该表中的数据。

# hbase shell

hbase(main):005:0>describe 'hbase_table'

hbase(main):005:0>scan 'hbase_table'

后续,在Hive中对hive_table表的更新操作都会相应更新HBase中的hbase_table表,反之,在Hbase中对hbase_table表的更新操作也会相应更新到Hive中的hive_table表。

2. 示例二: 在Hive中建立关联HBase的外部表,并查询HBase表中的数据。

(1)     在Hive中建立关联HBase的外部表,执行如下命令:

CREATE EXTERNAL TABLE hive_table2(key int, info string)

STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'

WITH SERDEPROPERTIES ("hbase.columns.mapping" = "cf1:val")

TBLPROPERTIES("hbase.table.name" = "hbase_table");

(2)     在Hive中查看到HBase表中的数据,执行如下命令:

select * from hive_table2;

4.2  Hive on Spark

4.2.1  概述

· Hive on Spark是由Cloudera发起,由Intel、MapR等公司共同参与的开源项目,其目的是把Spark作为Hive的一个计算引擎,将Hive的查询作为Spark的任务提交到Spark集群上进行计算。通过该项目,可以提高Hive查询的性能,同时为已经部署了Hive或者Spark的用户提供了更加灵活的选择。

· Hive on Spark总体的设计思路是,尽可能重用Hive逻辑层面的功能;从生成物理计划开始,提供一整套针对Spark的实现,比如SparkCompiler、SparkTask等,这样Hive的查询就可以作为Spark的任务来执行了。

· Hive on Spark可在Hive组件自定义配置hive-site中添加以下参数以控制Hive on Spark的资源使用,具体说明如 表4-1 所示,其余参数可参考Spark的参数设置。

表4-1 参数说明

4.2.2  操作示例

(1)     连接Hive,执行如下命令,设置Hive on Spark:

0: jdbc:hive2://cloudos2.hde.com:2181,cloudos> set hive.execution.engine=spark;

(2)     执行插入查询等操作:

0: jdbc:hive2://cloudos2.hde.com:2181,cloudos> insert into hive1 values(1, 'dfs');

0: jdbc:hive2://cloudos2.hde.com:2181,cloudos> select * from hive1;

+-----------+-------------+

| hive1.id  | hive1.name  |

+-----------+-------------+

| 1         | dfs         |

+-----------+-------------+

(3)     从ResouceManager UI中可看到,Hive命令是通过Spark引擎执行的。

图4-1 ResouceManager UI

(4)     同时也可以从Spark history UI中查看到刚执行成功的任务。

图4-2 Spark history UI

5.1  调优类

1. 使用ORC 文件格式,提高查询速度

ORCfile使用了predicate push-down,compression等多种技术。Hive使用ORCfile作为表结构不仅可以节省存储空间,而且能够快速提高Hive Query的速度。

create table t_orc(

id int,

name string,

age int,

address string

) stored as ORC tblproperties("orc.compress"="SNAPPY");

2. 使用VECTORIZATION ,提高执行速度

矢量(Vectorized query)每次处理数据时会将1024行数据组成一个batch进行处理,而不是一行一行进行处理,这样能够显著提高执行速度。可以通过如下配置项来开启。

set hive.vectorized.execution.enabled = true;

set hive.vectorized.execution.reduce.enabled = true;

Vectorized 仅支持如下数据类型:

· tinyint

· smallint

· int

· bigint

· boolean

· float

· double

· decimal

· date

· timestamp

· string

【说明】:若使用其他数据类型会使vetorized失效,即每次还是一行一行读取数据。

当使用支持的数据类型时,也支持如下表达式:

· 数学运算:+,-,*,/,%

· and, or, not

· <, >, <=, >=, =, !=, between, in

· 使用and, or, not, <, >, <=, >=, = !=的布尔表达式

· is [not] null

· 数学函数

· 字符串函数:substr, concat, trim, ltrim, rtrim, lower, upper, length

· 类型转换

· UDFs

· 时间函数

· If表达式等

3. 使用CBO 优化查询

CBO(COST BASED QUERY OPTIMIZATION)可以优化Hive的每次查询。如果想要使用CBO,需要开启如下选项:

set hive.cbo.enable=true;

set hive.compute.query.using.stats=true;

set hive.stats.fetch.column.stats=true;

set hive.stats.fetch.partition.stats=true;

如果想要使用CBO,需要通过Hive的分析模式来收集表的不同统计数据,执行如下命令:

analyze table table_name compute statistics for columns;

至此,Hive才可以通过消耗评估和不同的执行计划来让查询跑的更快。

4. 修改SQL语句,优化执行计划

可以采用多种SQL语句实现该功能。不同SQL语句,执行计划也不同,导致执行时间也不同。因此分析执行计划,选择最优的SQL语句,是很有必要的。可通过 EXPLAIN 命令来查看SQL的执行计划:

EXPLAIN [EXTENDED|DEPENDENCY|AUTHORIZATION] query

场景示例 :创建一个单击事件表,表中的每条数据代表一个单击事件。

· 创建表语句如下:

create table t_click(

click_time date,

sessionId string,

url string,

source_ip string

) stored as ORC tblproperties("orc.compress"="SNAPPY");

如果想要查询每个sessionId最后访问的url,可以采用下面的查询语句。

· 查询语句示例(一):

select t.* from t_click t inner join

( select sessionId, max(click_time) as max_cs from t_click group by sessionId

) l on t.sessionId = l.sessionId and t.click_time = l.max_cs;

¡ 查看示例(一)中语句的explain为:

Vertex dependency in root stage

Map 3 <- Reducer 2 (BROADCAST_EDGE)

Reducer 2 <- Map 1 (SIMPLE_EDGE)

Stage-0

Fetch Operator

limit:-1

Stage-1

Map Join Operator [MAPJOIN_28]

· 查询语句示例(二):

select * from (select * , rank() over (partition by sessionId order by click_time desc) as

rank from t_click) r where r.rank=1;

¡ 查看示例(二)中语句的explain为:

Vertex dependency in root stage

Reducer 2 <- Map 1 (SIMPLE_EDGE)

Stage-0

Fetch Operator

limit:-1

Stage-1

Reducer 2

File Output Operator [FS_8]

compressed:false

通过查看explain语句可知,查询示例(一)通过一个子查询获取每个sessionId最后访问时间,之后通过inner join来过滤其它的事件;查询示例(二)通过hive的开窗函数避免了两个大表的join,查询示例(二)查询效率显著提高。

5. Hive 利用严格模式,防止执行效果差的语句

Hive提供了严格模式,可以防止用户执行一些可能产生不好效果的查询,即在严格模式下,可以禁止用户执行某些操作。当设置hive.mapred.mode=strict,会禁止执行以下三种查询:

· 带有分区的表的查询

如果在一个分区表执行Hive,除非where语句中包含分区字段过滤条件来显示数据范围,否则不允许执行,即在严格模式下用户不允许扫描所有的分区。

进行这个限制的原因是,通常分区表都拥有非常大的数据集,而且数据增加迅速。没有进行分区限制的查询可能会消耗巨大资源来处理这个表。

· 带有orderby的查询

对于使用了orderby的查询,要求必须有limit语句。因为orderby为了执行排序过程会将所有的结果分发到同一个reducer中进行处理,强烈要求用户增加这个limit语句用于防止reducer额外执行太长时间。

· 限制笛卡尔积的查询

对关系型数据库非常了解的用户,可能期望在执行join查询的时候不使用on语句而是使用where语句,这样关系数据库的执行优化器就可以高效的将where语句转换成on语句。而Hive不会执行这种优化。如果表非常大时,这个查询就可能会出现OOM(Out Of Memory,内存溢出)等情况。

6. Hive/Spark任务性能调优

Spark作为Hive的一个计算引擎,将Hive的查询作为Spark的任务提交到Spark集群上进行计算。

当Hive查询出现性能问题时,需要先进行问题定位分析性能瓶颈,然后进行性能调优。

若确定业务sql实现方式无严重性能问题,则可通过以下步骤进行逐步的性能瓶颈分析:

(1)     通过监控界面查看任务监控细节

打开任务运行监控界面并进入任务运行列表页,根据融合集成平台中Hive/Spark运行提交时间或根据运营平台Hive/Spark任务返回的applicationId,找到对应的任务。

(2)     确定任务计算资源分配是否充足

进入任务列表页,查看该任务执行时占用的计算资源量,如 图5-1 所示。计算资源包括vcore数和内存资源。其中,vcore数决定任务执行并行度,内存决定分布式计算内存数。任务分配的计算资源较少,即任务计算资源分配不足。

图5-1 ResouceManager UI

(3)     确认sql执行过程中是否出现数据倾斜

首先确定任务的applicationId,然后点击该任务链接,进入任务监控详情查看MapReduce任务和Spark任务相关信息。

¡ MapReduce任务:任务运行一段时间后,进入任务详情查看该任务的Map及Reduce列表。若出现任务执行后期仅有1~3个Map或Reduce在同时运行,基本可以认定存在数据倾斜。

¡ Spark任务: 任务运行一段时间后,进入任务详情查看该任务Executor列表。若存在其中1~3个Executor执行了查询中50%以上的任务,基本可以认定存在数据倾斜。

根据以上性能瓶颈分析定位的问题,分别进行性能调优,性能调优策略如下:

· 若出现任务计算资源分配不足

¡ 根据sql关联查询的表数据量及关联查询复杂度评估并调整计算资源。

· 若sql计算资源分配足够,但任务运行仍然较慢

¡ 分析sql执行过程中是否出现笛卡尔积。通常生产场景下严格禁止笛卡尔积,若出现笛卡尔积,则该sql禁止执行。

¡ 分析业务sql实现上是否性能最佳。sql实现中需避免使用无用的关联查询、聚合分组等严重影响性能的实现方式。

¡ 业务sql中存在关联查询时,小于25MB的小表强烈建议放在关联操作的左边。

¡ 确定业务sql实现上已保证性能最佳,但实际执行过程仍然较慢,建议分析sql执行过程中是否出现数据倾斜。若出现数据倾斜,首先考虑sql实现上避免严重数据倾斜。如无法避免,建议增加并行度(若关联表中字段值存在少数key数据量比较大,也可考虑数据打散操作),同时适当降低每个执行线程的内存。因为在此性能瓶颈下,再增加内存资源对性能优化效果不再明显,并且由于计算资源有限,增加并行度会成倍的增加总内存消耗。

¡ SparkSQL业务sql中若使用了临时表或者中间表,建议增加driver端内存。

¡ sql关联查询的表数据量较大或者关联查询较复杂,但是无法再分配更多的计算资源。此场景下建议将该sql语句拆分成多条子sql执行,sql中可以按过滤字段值或分区字段值对该sql进行拆分。

7. Hive执行MapReduce任务时,Reduce过程中的Shuffle Copy速度很慢,导致整体查询速度很慢

在麒麟V10操作系统中,若Hive在执行MapReduce任务时出现此性能问题,可通过以下步骤进行逐步的性能瓶颈分析:

(1)     进入YARN组件的ResouceManager UI页面,根据Hive/Spark任务返回的applicationId,进入对应的MapReduce任务页面,如 图5-2 所示。

图5-2 MapReduce 任务页面

(2)     单击任务链接,查看正在执行的Reduce任务。在Reduce任务列表,若发现Shuffle Copy速度很慢,如 图5-3 所示,说明该任务的执行过程严重影响MapReduce任务执行速度。

图5-3 Shuffle copy 速度很慢

根据以上性能瓶颈分析定位的问题,调优策略如下:

(1)     进入YARN组件详情页面,选择[配置]页签。

(2)     在自定义配置的mapred-site中增加自定义属性mapreduce.shuffle.manage.os.cache并配置值为false(该参数表示是否采用操作系统缓存,配置为false即使用程序缓存)。

5.2  运维类问题

1. 使用HiveServer2创建HBase数据源表时,界面卡住,后台日志出现KeeperErrorCode = NoNode for /hbase/hbaseid提示

· 在Hive中创建HBase数据源表时,要求集群中必须安装HBase组件。若在HiveServer2启动时,集群中已经安装HBase,则HiveServer创建HBase数据源表可以成功。

· 若在HiveServer2启动时,集群中没有安装HBase,则需要在安装了HBase后重启Hive组件,然后HiveServer2才能创建HBase数据源表成功。

2. Hive JDBC连接执行load data local inpath时路径指定为/tmp下报无效路径,如何解决?

Hive jdbc连接执行加载本地文件时,要求:

· 每个节点都有该数据文件,同时要求location的owner和建表用户一致,且拥有rw权限。

3. Hive server2 状态不稳定,客户执行beeline有时候报错

· 原因分析:Hive server2 内存不足,Tez container内存不足

· 定位思路:通过日志查看,若tez heap内存溢出较频繁,则可能是处理的数据量较大导致heap内存溢出导致。

· 解决方法:根据客户数据量在DE中调大Hive中的hive.tez.container.size 和hive.heapsize参数

4. 任务执行出现异常 ,报错:Invalid resource request,requested memory < 0, or requested memory > max configured, requestedMemory=6826, maxMemory=4096

· 原因分析:该问题是任务所需内存超出yarn container的最大内存。

· 定位思路:查看yarn container配置大小是否小于6826M。

· 解决方法:在YARN配置界面调整container的最大值超过所需内存大小便可解决。

5. 集群中添加新节点进行扩容后,Hive 或Spark的beeline连接出现异常

· 原因分析:集群中添加新节点后,HDFS以及系统hosts配置文件都进行了更新。但HiveServer及SparkThriftServer加载的配置信息却仍为添加节点之前的信息,所以在客户端连接时会出现HiveServer&SST与HDFS配置不一致的情况,导致连接失败。

· 定位思路:检查HiveServer和SparkThriftServer是否已经重启

· 解决方法:集群扩容增加新节点后,需要重启HiveServer和SparkThriftServer,以保证服务可加载集群的最新配置,确保JDBC连接正常。

6. Hive 在hdfs用户下创建外部表时指定外部表在hdfs的存储路径后显示没有权限

此问题由操作方式不当引起。因为创建Hive外部表时,会对指定的location进行权限检查,要求:

· 如果location存在,要求location的owner和建表用户一致,且拥有rw权限

· 如果location不存在,则会检查location的父级目录,要求父级目录的owner和建表用户一致;且要求父级目录所有子目录(包括子目录的子目录)的owner和建表用户一致,且拥有rw权限。

7. Hive提交join任务执行失败

· 原因分析:Hive进行大小表的join,且开启了自动转换;此时Hive会识别小表,并用mapJoin来实现两个表的联合,造成内存溢出,MapReduce任务执行失败。

· 定位思路:用两张普通表测试hive的join是否正常;排查客户同步的两张表结构;排查hive是否开启自动转换。

· 解决方法:关闭自动转换:set hive.auto.convert.join = false。

8. Hive提交带函数的语句时报错

· 原因分析:提交任务的用户错误。

· 定位思路:排查错误日志,发现:running as root is not allow。

· 解决方法:处理步骤是切换到hdfs用户进行提交。

9. 执行Hive SQL语句失败

· 原因分析:Hive堆内存过小导致任务无法执行

· 定位思路:排查错误日志,发现:java.lang.OutOfMemoryError:GC overhead limit exceeded。

· 解决方法:在hive界面调整堆内存大小不生效,hive堆内存大小对应的是hdfs的hadoop_heapsize参数。

10. Hue执行Hive语句报错或无法执行

· 原因分析:

¡ 可能是硬盘或网络原因导致YARN写filecache(/hadoop/yarn/local/filecache/)失败,Hive提交MapReduce任务无法执行。

¡ SQL语句错误。

¡ 权限不足。

· 定位思路:

¡ 排查Hive日志:Error while processing statement:FAILED:Execution Error. Return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask。

¡ 报错信息:ParseException line 1:9 character ‘ ’not supported here,客户输入的sql语句有非法空格;

¡ 报错信息:Principal [name=admin,type=USER] does not have following privileges for operation QUERY [[SELECT]],客户利用admin用户查询Hive表,但没有对应表权限。

· 解决方法:

¡ 重启YARN即可。

¡ 调整SQL语句后正常。

¡ 退出登录后,采用有权限操作的用户进行查询后正常。

11. Hive beeline连接失败,报错:GSS initiate failed

· 原因分析:beeline连接时候principle配置错误。

· 定位思路:查看HDFS对应的principle,确认配置是否正确。

· 解决方法:beeline连接时采用正确的principle即可。

12. Hive客户端提交SQL语句,报错:SemanticException Failed to get a spark session

· 原因分析:Hive使用Spark计算引擎,在执行SQL语句时会向Yarn申请资源启动SparkSession,当资源不足时,SparkSession会处于等待中,此时就会引起启动SparkSession超时;或者当网络异常或者节点响应较慢时,也会引起该问题。

· 定位思路:修改Hive对应配置项。

· 解决方法:Hive服务中hive-site配置中,修改配置hive.spark.client.server.connect.timeout,默认值为600000,可以适当调大,如1200000。

13. 客户端获取结果时造成HiveServer2服务关掉

· 原因分析:客户端提交SQL语句到HiveServer2,并从HiveServer2端获取SQL语句执行结果,默认是每次以1000条拉取结果,该值可以满足常用场景。若获取SQL语句中每条结果太大时会造成HiveServer2出现OOM现象,引起该服务停掉。

· 定位思路:修改Hive对应配置项。

· 解决方法:在HiveServer2服务中hive-site配置中,添加hive.server2.thrift.resultset.max.fetch.size配置项,设置较小值(如300)。

14. Hive-jdbc高并发执行SQL语句时,HiveServer2由于jvm堆内存溢出:java.lang.OutOfMemoryError: Java heap space不可用

· 原因分析:客户端高并发(HiveServer2默认最大支持500并发)通过hive-jdbc提交SQL语句到HiveServer2,并从HiveServer2端获取SQL语句执行结果。由于存在结果缓存,高并发下需要占用较多堆内存,若HiveServer2进程配置的内存过小则容易出现该异常。

· 定位思路:修改Hive对应配置项。

· 解决方法:在HiveServer2服务组件的基础配置中hive-site配置中调大HiveServer2 Heap Size的值(比如16GB)。

15. Hive任务Insert overwrite语句,目标表分区13万左右,任务执行到最后move阶段,移动临时结果至对应分区执行缓慢

· 原因分析:过多的分区会导致HiveMetaStore的元数据更新压力大,同时也增加NameNode的负担,进而影响一系列依赖于NameNode的服务。

· 解决方法:

¡ 对表设置合理的分区,单表分区数不要超过10万。

¡ 生成数据时尽量避免生成小文件,从而减少NameNode的压力。

16. Hive执行LOAD DATA LOCAL INPATH语句报错Invalid path ''***'': No files matching path file

· 原因分析:Hive使用LOAD DATA LOCAL INPATH时,数据文件必须与HiveServer2服务在同一个节点。否则,当HiveServer2有多个,并且以HA模式使用beeline连接Hive时,会随机选择一个HiveServer2进行连接,然后在执行LOAD DATA LOCAL INPATH语句的时候,如果在连接到的HiveServer2节点对应目录不存在指定的文件就会报该错误。

· 解决方法:当以HA模式使用beeline连接Hive时,需要上传数据文件到所有的HiveServer2节点对应目录。

17. Hive执行长时间任务(超过24小时)报错Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClien ''***''IO error acquiring password

· 原因分析:在Kerberos环境下,当采用DelegationToken(即代理Token)进行认证时,若Token超过最大生命周期或Token的更新截止时间超过当前时间,服务端会自动清理掉对应的DelegationToken,从而导致该问题。

· 解决方法:进入Hive组件详情页面,在[配置]页签下的自定义配置的hivemetastore-site中增加hive.cluster.delegation.token.max-lifetime和hive.cluster.delegation.token.renew-interval两个参数,并根据业务需要配置参数的值(当集群有长时间(超过24h)的任务,就需要调整参数值)。

hive.cluster.delegation.token.max-lifetime

表示代理Token最大生命周期,单位毫秒,默认值为604800000,即7天。

hive.cluster.delegation.token.renew-interval

表示代理Token续期间隔时间,单位毫秒,默认值为86400000,即1天。

示例 】若集群中存在 30天的任务,则需调整参数值为30天(259200000毫秒),如下:

¡ hive.cluster.delegation.token.max-lifetime=2592000000

¡ hive.cluster.delegation.token.renew-interval=2592000000