# Hive的体系结构

为了更好地理解Hive如何与Hadoop的基本组件一起协同工作,可以把Hadoop看作一个操作系统,HDFS和MapReduce是这个操作系统的组成部分,而像Hive、HBase这些组件,则是操作系统的上层应用或功能。Hadoop生态圈的通用底层架构是HDFS提供分布式存储,MapReduce为上层功能提供并行处理能力。

在HDFS和MapReduce之上,图中显示了Hive驱动程序和元数据存储。Hive驱动程序及其编译器负责编译、优化和执行HiveQL。依赖于具体情况,Hive驱动程序可能选择在本地执行Hive语句或命令,也可能是产生一个MapReduce作业。Hive驱动程序把元数据存储在数据库中。

默认配置下,Hive在内建的Derby关系数据库系统中存储元数据,这种方式被称为嵌入模式。在这种模式下,Hive驱动程序、元数据存储和Derby全部运行在同一个Java虚拟机中(JVM)。这种配置适合于学习目的,它只支持单一Hive会话,所以不能用于多用户的生产环境。Hive还允许将元数据存储于本地或远程的外部数据库中,这种设置可以更好地支持Hive的多会话生产环境。并且,可以配置任何与JDBC API兼容的关系数据库系统存储元数据,如MySQL、Oracle等。

对应用支持的关键组件是Hive Thrift服务,它允许一个富客户端访问Hive,开源的SQuirreL SQL客户端被作为示例包含其中。任何与JDBC兼容的应用,都可以通过绑定的JDBC驱动访问Hive。与ODBC兼容的客户端,如Linux下典型的unixODBC和isql应用程序,可以从远程Linux客户端访问Hive。如果在客户端安装了相应的ODBC驱动,甚至可以从微软的Excel访问Hive。通过Thrift还可以用Java以外的程序语言,如PHP或Python访问Hive。就像JDBC、ODBC一样,Thrift客户端通过Thrift服务器访问Hive。

架构图的最上面包括一个命令行接口(CLI),可以在Linux终端窗口向Hive驱动程序直接发出查询或管理命令。还有一个简单的Web界面,通过它可以从浏览器访问Hive管理表及其数据。

# 一、Hive 的工作流程

从接收到从命令行或是应用程序发出的查询命令,到把结果返回给用户,期间Hive的工作流程(第一版的MapReduce)如下图,从中不难看出,Hive的执行过程与关系数据库的非常相似,只不过是使用分布式计算框架来实现。

步骤 操作
1.执行查询 从Hive的CLI或Web UI发查询命令给驱动程序(任何JDBC、ODBC数据库驱动)执行
2.获得计划 驱动程序请求查询编译器解析查询、检查语法、生成查询计划或者查询所需要的资源
3.获得元数据 编译器向元数据存储数据库发送元数据请求
4.发送元数据 作为响应,元数据存储数据库向编译器发送元数据
5.发送计划 编译器检查需要的资源,并把查询计划发送给驱动程序。至此,查询解析完成
6.执行计划 驱动程序向执行引擎发送执行计划
7.执行作业 执行计划的处理是一个MapReduce作业。执行引擎向Name node上的JobTracker进程发送作业,JobTracker把作业分配给Data node上的TaskTracker进程,此时,查询执行MapReduce作业
7.1操作元数据 执行作业的同时,执行引擎可能会执行元数据操作,如DDL语句等。
8.取回结果 执行引擎从Data node 接收结果
9.发送结果 执行引擎向驱动程序发送合成的结果值
10.发送结果 驱动程序向Hive接口(CLI或者WebUI)发送结果

# 二、存储格式

# 2.1 支持的存储格式

Hive 会在 HDFS 为每个数据库上创建一个目录,数据库中的表是该目录的子目录,表中的数据会以文件的形式存储在对应的表目录下。Hive 支持以下几种文件存储格式:

格式 说明
TextFile 存储为纯文本文件。 这是 Hive 默认的文件存储格式。这种存储方式数据不做压缩,磁盘开销大,数据解析开销大。
SequenceFile SequenceFile 是 Hadoop API 提供的一种二进制文件,它将数据以<key,value>的形式序列化到文件中。这种二进制文件内部使用 Hadoop 的标准的 Writable 接口实现序列化和反序列化。它与 Hadoop API 中的 MapFile 是互相兼容的。Hive 中的 SequenceFile 继承自 Hadoop API 的 SequenceFile,不过它的 key 为空,使用 value 存放实际的值,这样是为了避免 MR 在运行 map 阶段进行额外的排序操作。
RCFile RCFile 文件格式是 FaceBook 开源的一种 Hive 的文件存储格式,首先将表分为几个行组,对每个行组内的数据按列存储,每一列的数据都是分开存储。
ORC Files ORC 是在一定程度上扩展了 RCFile,是对 RCFile 的优化。
Avro Files Avro 是一个数据序列化系统,设计用于支持大批量数据交换的应用。它的主要特点有:支持二进制序列化方式,可以便捷,快速地处理大量数据;动态语言友好,Avro 提供的机制使动态语言可以方便地处理 Avro 数据。
Parquet Parquet 是基于 Dremel 的数据模型和算法实现的,面向分析型业务的列式存储格式。它通过按列进行高效压缩和特殊的编码技术,从而在降低存储空间的同时提高了 IO 效率。

以上压缩格式中 ORC 和 Parquet 的综合性能突出,使用较为广泛,推荐使用这两种格式。 我也做过SequenceFile和ORC File的,压缩和执行测试 Sequence Files VS ORC Files (opens new window)

# 2.2 指定存储格式

通常在创建表的时候使用 STORED AS 参数指定:

CREATE TABLE page_view(viewTime INT, userid BIGINT)
 ROW FORMAT DELIMITED
   FIELDS TERMINATED BY '\001'
   COLLECTION ITEMS TERMINATED BY '\002'
   MAP KEYS TERMINATED BY '\003'
 STORED AS SEQUENCEFILE;
1
2
3
4
5
6

各个存储文件类型指定方式如下:

  • STORED AS TEXTFILE
  • STORED AS SEQUENCEFILE
  • STORED AS ORC
  • STORED AS PARQUET
  • STORED AS AVRO
  • STORED AS RCFILE

# 2.3 Sequence Files VS ORC Files

群集磁盘资源紧张,需要对表数据进行压缩,将从SequenceORC中选其一作为以后仓库表文件的存储格式。本文就SnappyZLIB(Gzip)压缩级别进行表大小以及查询效率的对比

  1. 压缩参数

Sequence

-- Snappy
set hive.exec.compress.output=true;
set mapred.output.compress=true;
set mapred.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
set mapred.output.compression.type=BLOCK;

-- Gzip
set hive.exec.compress.output=true;
set mapred.output.compress=true;
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;
set mapred.output.compression.type=BLOCK;
1
2
3
4
5
6
7
8
9
10
11

ORC

-- Snappy
set hive.exec.orc.default.compress=SNAPPY;

-- ZLIB
set hive.exec.orc.default.compress=ZLIB;
1
2
3
4
5
  1. 大小对比

订单主表

格式 文件大小 占用大小 压缩比(倍)
text 19.8G 59.5G
seq_snappy 6.1G 18.4G 3.24
orc_snappy 4.2G 12.5G 4.71
seq_gzip 3.4G 10.3G 5.82
orc_zlib 3.0G 9.0G 6.6

订单明细表

格式 文件大小 占用大小 压缩比(倍)
text 18.8G 56.5G
seq_snappy 4.2G 12.5G 4.38
orc_snappy 2.6G 7.8G 7.23
seq_gzip 2.3G 6.9G 8.17
orc_zlib 1.7G 5.0G 11.05
  1. SQL查询效率

简单Count

格式 第一次 第二次 第三次
seq_snappy 23.16 21.813 23.031
orc_snappy 22.154 19.911 20.582
seq_gzip 33.362 26.446 27.537
orc_zlib 21.197 19.23 18.499

过滤并分组

格式 第一次 第二次 第三次
seq_snappy 27.436 26.453 27.796
orc_snappy 21.568 25.971 29.075
seq_gzip 35.16 78.649 38.198
orc_zlib 20.273 21.491 19.539

联查询Count

主表与明细表通过订单ID关联

格式 第一次 第二次 第三次
seq_snappy 64.336 68.128 63.755
orc_snappy 71.017 100.511 65.912
seq_gzip 98.201 79.246 79.736
orc_zlib 99.996 69.23 74.677

实际查询

主表与明细表通过订单ID关联,分组,单表select * , max ,sum等聚合

格式 第一次 第二次 第三次 第四次 第五次 第六次
seq_snappy 580.938 1065.992 787.999 1365.383 622.456 605.303
orc_snappy 696.887 1333.952 1034.791 806.678 789.647 794.424
seq_gzip 806.734 1448.114 1237.069 901.431 901.75 854
orc_zlib 1983 1983 1294.967 906.825 926.922 975.837

第六次细节

类型 Job Stage Map Reduce Elapsed Vcore Map(Seconds) Vcore Reduce(Seconds) Vcore Total(Sedonds) -(orc-seq)/seq
seq_snap job_1583725051064_59160 Stage-1 57 11 5mins,44sec 1694222 2924159 4618381
orc_snap job_1583725051064_59190 Stage-1 49 7 8mins,45sec 1494752 2895072 4389824 4.95%
seq_snap job_1583725051064_59187 Stage-2 38 10 4mins,8sec 1193042 1820443 3013485
orc_snap job_1583725051064_59198 Stage-2 39 10 4mins,12sec 1197185 1941388 3138573 -4.15%
seq_gzip job_1583725051064_59028 Stage-1 49 6 9mins,39sec 1667028 2851133 4518161
orc_zlib job_1583725051064_59046 Stage-1 48 5 11mins,24sec 1477584 2937803 4415387 2.27%
seq_gzip job_1583725051064_59043 Stage-2 42 10 4mins,19sec 1213325 2140155 3353480
orc_zlib job_1583725051064_59065 Stage-2 40 10 4mins,37sec 1206666 2188277 3394943 -1.24%
类型 Elapsed Vcore Total(Sedonds) -(orc-seq)/seq
seq_snap 9mins,52sec 7631866
orc_snap 12mins,57sec 7528397 1.36%
seq_gzip 13mins,58sec 7871641
orc_zlib 16mins 7810330 0.78%
  1. 结论
  • 以数据压缩后的大小来看,ORC完胜。
  • SQL查询方面,因为orc的文件更小,所以map和reduce数相对较小,导致运算时间增长(20%左右),但总体CPU资源耗用还是要比Seq格式少1%左右。

# 三、数据类型

# 3.1 基本数据类型

Hive 表中的列支持以下基本数据类型:

大类 类型
Integers(整型) TINYINT—1 字节的有符号整数
SMALLINT—2 字节的有符号整数
INT—4 字节的有符号整数
BIGINT—8 字节的有符号整数
Boolean(布尔型) BOOLEAN—TRUE/FALSE
Floating point numbers(浮点型) FLOAT— 单精度浮点型
DOUBLE—双精度浮点型
Fixed point numbers(定点数) DECIMAL—用户自定义精度定点数,比如 DECIMAL(7,2)
String types(字符串) STRING—指定字符集的字符序列
VARCHAR—具有最大长度限制的字符序列
CHAR—固定长度的字符序列
Date and time types(日期时间类型) TIMESTAMP — 时间戳
TIMESTAMP WITH LOCAL TIME ZONE — 时间戳,纳秒精度
DATE—日期类型
Binary types(二进制类型) BINARY—字节序列

TIMESTAMP 和 TIMESTAMP WITH LOCAL TIME ZONE 的区别如下:

  • TIMESTAMP WITH LOCAL TIME ZONE:用户提交时间给数据库时,会被转换成数据库所在的时区来保存。查询时则按照查询客户端的不同,转换为查询客户端所在时区的时间。
  • TIMESTAMP :提交什么时间就保存什么时间,查询时也不做任何转换。

# 3.2 隐式转换

Hive 中基本数据类型遵循以下的层次结构,按照这个层次结构,子类型到祖先类型允许隐式转换。例如 INT 类型的数据允许隐式转换为 BIGINT 类型。额外注意的是:按照类型层次结构允许将 STRING 类型隐式转换为 DOUBLE 类型。

# 3.3 复杂类型

类型 描述 示例
STRUCT 类似于对象,是字段的集合,字段的类型可以不同,可以使用 名称.字段名 方式进行访问 STRUCT ('xiaoming', 12 , '2018-12-12')
MAP 键值对的集合,可以使用 名称[key] 的方式访问对应的值 map('a', 1, 'b', 2)
ARRAY 数组是一组具有相同类型和名称的变量的集合,可以使用 名称[index] 访问对应的值 ARRAY('a', 'b', 'c', 'd')

# 3.4 示例

如下给出一个基本数据类型和复杂数据类型的使用示例:

CREATE TABLE students(
  name      STRING,   -- 姓名
  age       INT,      -- 年龄
  subject   ARRAY<STRING>,   --学科
  score     MAP<STRING,FLOAT>,  --各个学科考试成绩
  address   STRUCT<houseNumber:int, street:STRING, city:STRING, province:STRING>  --家庭居住地址
) ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t";
1
2
3
4
5
6
7

# 四、内容格式

当数据存储在文本文件中,必须按照一定格式区别行和列,如使用逗号作为分隔符的 CSV 文件 (Comma-Separated Values) 或者使用制表符作为分隔值的 TSV 文件 (Tab-Separated Values)。但此时也存在一个缺点,就是正常的文件内容中也可能出现逗号或者制表符。

所以 Hive 默认使用了几个平时很少出现的字符,这些字符一般不会作为内容出现在文件中。Hive 默认的行和列分隔符如下表所示。

分隔符 描述
\n 对于文本文件来说,每行是一条记录,所以可以使用换行符来分割记录
^A (Ctrl+A) 分割字段 (列),在 CREATE TABLE 语句中也可以使用八进制编码 \001 来表示
^B 用于分割 ARRAY 或者 STRUCT 中的元素,或者用于 MAP 中键值对之间的分割,
在 CREATE TABLE 语句中也可以使用八进制编码 \002 表示
^C 用于 MAP 中键和值之间的分割,在 CREATE TABLE 语句中也可以使用八进制编码 \003 表示

使用示例如下:

CREATE TABLE page_view(viewTime INT, userid BIGINT)
 ROW FORMAT DELIMITED
   FIELDS TERMINATED BY '\001'
   COLLECTION ITEMS TERMINATED BY '\002'
   MAP KEYS TERMINATED BY '\003'
 STORED AS SEQUENCEFILE;
1
2
3
4
5
6

# 六、Hive客户端

Hive最初的形式是一个重量级的命令行工具,它接收查询指令并利用MapReduce执行查询。后来Hive采用了客户端-服务器模式,HiveServer(简称HS1)作为服务器端,负责将查询语句编译成MapReduce作业,并监控它们的执行。而Hive CLI(hive shell命令)是一个命令行接口,负责接收用户的HiveQL语句,并传送到服务器。 Hive社区在0.11版中引入了HS2,并推荐使用新的Beeline命令行接口(beeline shell命令),HS1及其Hive CLI不再建议使用,甚至过时的Hive CLI客户端方案以后可能将不能与HS2一起使用。下面重点介绍Beeline客户端,在本小节最后说明Hive CLI和Beeline用法上的主要差别。

Beeline是为与新的Hive服务器进行交互而特别开发的。与Hive CLI不同,Beeline不是基于Thrift的客户端,而是一个基于SQLLine CLI的JDBC客户端,尽管用于和HS2通信的JDBC驱动程序还是使用的Thrift API。Beeline有嵌入和远程两种操作模式。在嵌入模式中,它运行一个嵌入的类似于hive的shell命令;而在远程模式中,它通过Thrift服务连接一个分离的HS2进程。从Hive 0.14开始,当Beeline与HS2联合使用时,还会在交互式查询中打印很长的HS2消息信息。生产系统推荐使用远程HS2模式,因为它更安全,不需要授予用户直接访问HDFS或元数据存储的权限。

# Beeline命令

$HIVE_HOME/bin/beeline这个shell命令(后面简称为beeline)用于连接Hive服务器。假定已经将$HIVE_HOME/bin加入到环境变量PATH中,则只需要在shell提示符中输入beeline,就可以使用户的shell环境如bash找到这个命令。\

# 进入Beeline后链接服务器
beeline > !connect jdbc:hive2://cdh2:10000
1
2

也可以在命令行直接指定连接参数。这意味着能够在Linux shell的命令历史history中找到含有连接字符串的beeline命令。

beeline -u jdbc:hive2://cdh2:10000/test
1

# 连接URL

Beeline客户端使用URL格式连接Hive数据库,HS2的URL连接字符串语法如下:

jdbc:hive2://<host1>:<port1>,<host2>:<port2>/dbName;initFile=<file>;sess_var_list?hive_conf_l ist#hive_var_list

  • <host1>:<port1>,<host2>:<port2>:要连接的一个服务器实例,或者是用逗号分隔的多个服务器实例,如果为空,将使用嵌入模式。
  • dbName:初始连接的数据库名称。
  • <file>:初始化脚本的路径(Hive 2.2.0及以后版本支持)。这个脚本文件中的HiveQL语句会在连接后自动执行。该选项可以为空。
  • sess_var_list:以一个逗号分隔的、会话级变量的键/值对列表。
  • hive_conf_list:以一个逗号分隔的、Hive配置变量的键/值对列表。
  • hive_var_list:以一个逗号分隔的、Hive变量的键/值对列表。

JDBC连接具有jdbc:hive2://前缀,驱动的类是org.apache.hive.jdbc.HiveDriver。注意这和老的HS1不同。

对于远程连接模式,连接URL的格式为:

jdbc:hive2://<host>:<port>/<db>;initFile=<file>(HS2 默认的端口是 10000)。

对于嵌入连接模式,连接URL的格式为:

jdbc:hive2:///;initFile=<file>(没有主机名和端口)。

当HS2以HTTP模式运行时,连接URL的格式为:

jdbc:hive2://<host>:<port>/<db>;transportMode=http;httpPath=<http_endpoint>,其中 <http_endpoint>对应的是hive-site.xml文件中配置hive.server2.thrift.http.path 属性值,默认值为 cliservice。默认的HTTP传输端口为10001。

当HS2启用了SSL时,连接URL的格式为:

jdbc:hive2://<host>:<port>/<db>;ssl=true;sslTrustStore=<trust_store_path>;trustStorePassword= <trust_store_password>

其中<trust_store_path>是客户端信任文件所在路径,<trust_store_password>是访问信任文件所需的密码。相应HTTP模式的格式为:

jdbc:hive2://<host>:<port>/<db>;ssl=true;sslTrustStore=<trust_store_path>;trustStorePassword= <trust_store_password>;transportMode=http;httpPath=<http_endpoint>。

从Hive 2.1.0开始,Beeline支持命名URL连接串,这是通过环境变量实现的。如果使用!connect连接一个名称,而不是URL,那么Beeline会查找一个名为BEELINE_URL_<name>的环境变量。例如,如果命令为!connect blue,Beeline会查找BEELINE_URL_BLUE环境变量,并使用该变量的值做连接。对于系统管理员来说,为用户设置环境变量相对方便些,用户也不需要在每次连接时都键入完整的URL字符串。 !reconnect命令用于刷新已经建立的连接,如果已经执行!close命令关闭了连接,则不能再刷新连接。从Hive 2.1.0起,Beeline会记住一个会话最后成功连接的URL,这样即使已经运行了!close命令也能够重连。另外,如果用户执行了!save命令,连接会被保存到beeline.properties文件中,当执行!reconnect时,会连接到这个保存的URL。也可以在命令行使用-r参数,在启动Beeline时执行重连操作。

# 变量和属性

--hivevar参数可以让用户在命令行定义自己的变量以便在Hive脚本中引用,以满足不同情况的需要。这个功能只有Hive 0.8.0及其之后版本才支持。当使用这个功能时,Hive会将键/值对放到hivevar命名空间,这样就能和另外三种内置的命名空间(hiveconf、system和env)加以区分。下表描述了Hive的4种命名空间选项。

命名空间 使用权限 描述
hivevar 可读写 用户自定义变量(Hive 0.8.0及以后版本)
hiveconf 可读写 Hive相关的配置属性
system 可读写 Java定义的配置属性
Env 只读 shell环境(如bash)定义的环境变量

变量在Hive内部是以Java字符串的方式存储的。用户可以在查询中引用变量。Hive会先使用变量值替换掉查询的变量引用,然后才会将查询语句提交给查询处理器。在beeline环境中,可以使用set命令显示或者修改变量值。例如,下面这个会话先显示一个env变量的值,然后再显示所有命名空间中定义的变量。为了更清晰地表现,我们省略掉这个Hive会话中大量的输出信息:

set env:HOME;
set;
set -v;
1
2
3

如果不加-v标记,set命令会打印出hivevar、hiveconf、system和env中所有的变量。使用-v标记,则会打印出Hadoop中所定义的所有属性。例如控制HDFS和MapReduce的属性。set命令还可用于给变量赋新的值。我们特别看下hivevar命名空间以及如何通过命令行定义一个变量:

beeline --hivevar foo=bar
0: jdbc:hive2://bihell:10000/default> set foo;
+----------+--+
|   set    |
+----------+--+
| foo=bar  |
+----------+--+
1 row selected (6.41 seconds)
0: jdbc:hive2://bihell:10000/default> set hivevar:foo;
+-------------------+--+
|        set        |
+-------------------+--+
| hivevar:foo=bar2  |
+-------------------+--+
1 row selected (0.005 seconds)
0: jdbc:hive2://bihell:10000/default> set foo;
+-----------+--+
|    set    |
+-----------+--+
| foo=bar2  |
+-----------+--+
1 row selected (0.005 seconds)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

可以看到,前缀hivevar:是可选的,如果不加前缀,默认的命名空间就是hivevar。在beeline环境中,查询语句的变量引用会先被替换掉,然后才提交给查询处理器。

0: jdbc:hive2://bihell:10000/default> create table bihell(i int,${hivevar:foo} string);
+-----------+------------+----------+--+
| col_name  | data_type  | comment  |
+-----------+------------+----------+--+
| i         | int        |          |
| bar2      | string     |          |
+-----------+------------+----------+--+

0: jdbc:hive2://bihell:10000/default> create table bihell2 (i int,${foo} string);
+-----------+------------+----------+--+
| col_name  | data_type  | comment  |
+-----------+------------+----------+--+
| i         | int        |          |
| bar2      | string     |          |
+-----------+------------+----------+--+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

--hiveconf选项是hive 0.7版本后支持的功能,用于配置Hive行为的所有属性。我们甚至可以增加新的hiveconf属性。

0: jdbc:hive2://bihell:10000/default> set hiveconf:y=1;
No rows affected (0.002 seconds)
0: jdbc:hive2://bihell:10000/default> set hiveconf:y;
+---------------+--+
|      set      |
+---------------+--+
| hiveconf:y=1  |
+---------------+--+
1 row selected (0.005 seconds)
0: jdbc:hive2://bihell:10000/default> select * from t where id=${hiveconf:y);
1
2
3
4
5
6
7
8
9
10

运行指定文件中的SQL

beeline -u "jdbc:hive2://xxx.xxx.com:10000" --hiveconf rptdate=`date --date='1 days ago' "+%Y%m%d"` -n hdfs -f /xx/xx/xx.SQL
# --hiveconf rptdate用来把变量带入SQL脚本,SQL脚本中使用${hiveconf:rptdate}获变量值。
1
2

我们还有必要了解一下system命名空间,它定义Java系统属性。Beeline对这个命名空间内容具有可读写权利,而对于env命名空间的环境变量只提供读权限。

0: jdbc:hive2://bihell:10000/default> set ststem:user.name;
+--------------------------------+--+
|              set               |
+--------------------------------+--+
| ststem:user.name is undefined  |
+--------------------------------+--+
1 row selected (0.005 seconds)
0: jdbc:hive2://bihell:10000/default> set system:user.name;
+------------------------+--+
|          set           |
+------------------------+--+
| system:user.name=hive  |
+------------------------+--+
1 row selected (0.006 seconds)
0: jdbc:hive2://bihell:10000/default> set system:user.name=hive2;
No rows affected (0.007 seconds)
0: jdbc:hive2://bihell:10000/default> set system:user.name;
+-------------------------+--+
|           set           |
+-------------------------+--+
| system:user.name=hive2  |
+-------------------------+--+
1 row selected (0.005 seconds)
0: jdbc:hive2://bihell:10000/default> set env:HOME;
+-------------------------+--+
|           set           |
+-------------------------+--+
| env:HOME=/var/lib/hive  |
+-------------------------+--+
1 row selected (0.005 seconds)
0: jdbc:hive2://bihell:10000/default> set env:HOME=/var/lib/hive2;
Error: Error while processing statement: null (state=,code=1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

和hivevar变量不同,用户必须使用system:或者env:前缀来指定系统属性和环境变量。env命名空间可作为向Hive传递变量的一个可选的方式。

YEAR=2020
beeline -u jdbc:hive2://bihell:10000/test -e "select * from t where yar = ${env:YEAR}";
1
2

查询处理器会在where子句中查看到实际的变量值为2020。Hive中所有的内置属性都在$HIVE_HOME/conf/hive-default.xml.template文件中列举出来了,这是个样例配置文件,其中还说明了这些属性的默认值。

# 输出格式

在Beeline中,查询结果能以不同的格式显示出来。显示格式可以通过outputformat选项设置。支持的输出格式有table、vertical、xmlattr、xmlelements和分隔值格式(csv、tsv、csv2、tsv2、dsv)。以下是一些不同格式的输出示例。

# Hive CLI和Beeline使用上的主要差别

随着Hive从原始的HS1服务器进化为新的HS2,用户和开发者也需要将客户端工具从原来的Hive CLI切换为新的Beeline,然而这种切换并不只是将“hive”命令换成“beeline”命令这么简单。下面介绍两种客户端用法上的主要差异。

  • Hive CLI提供了一个可以打印RCFile格式文件内容的工具,如:hive --service rcfilecat /user/hive/warehouse/columntable/000000_0 Beeline没有此项功能。
  • Hive CLI可以使用source命令来执行脚本文件,如:hive> source /path/to/file/queries.hql; Beeline没有此项功能。
  • Hive CLI可以配置hive.cli.print.current.db属性,在命令行提示符前打印当前数据库名,如:$hive -hiveconf hive.cli.print.current.db=true。Beeline使用--showDbInPrompt命令行参数实现此功能(2.2.0版本新增)。
  • Hive CLI可以使用“!”操作符执行shell命令,如hive> ! pwd; Beeline中不能执行shell命令,其中的“!”符号是用来执行Beeline命令的,如:beeline> !connect jdbc:hive2://cdh2:10000
  • Hive CLI中,默认时在查询结果中不显示字段名称,需要设置hive.cli.print.header选项打印字段名称,如:hive> set hive.cli.print.header=true; 而Beeline不需要此项设置就会在输出中显示字段名称。
  • Hive CLI中可以使用--define命令行参数设置变量,它和--hivevar是相同的,如:hive --define foo=bar 而在Beeline中--define参数是无效的,只能使用--hivevar参数。
  • Hive CLI可以使用-S选项开启静默模式,这样可以在输出结果中去掉额外的输出信息,而Beeline虽然提供了-silent参数,似乎能起到相同的效果,但实际上不行(至少在CDH 5.7.0上,该参数和hive的-S作用是不同的)。
  • Hive CLI支持管道符。例如,用户没有记清楚哪个属性指定了管理表的“warehouse”路径,通过如下的命令可以查看到: hive -e "set" | grep warehouse 上面的命令换成beeline则不会得到想要的结果。Beeline需要在客户端脚本中添加设置支持事务的set命令,即使在服务器端的hivesite.xml文件中已经设置,而Hive CLI则不需要。
更新时间: 9/23/2021, 7:22:06 PM