Hive命令行界面
命令行界面,也就是CLI,是和Hive交互的最常用的方式。使用CLI,用户可以创建表、检查模式以及查询表,等等。
CLI选项
下面这个命令显示了CLI所提供的选项列表:
[hadoop@localhost hive]$ hive --help --service cli
usage: hive
-d,--define <key=value> Variable subsitution to apply to hive
commands. e.g. -d A=B or --define A=B
--database <databasename> Specify the database to use
-e <quoted-query-string> SQL from command line
-f <filename> SQL from files
-H,--help Print help information
--hiveconf <property=value> Use value for given property
--hivevar <key=value> Variable subsitution to apply to hive
commands. e.g. --hivevar A=B
-i <filename> Initialization SQL file
-S,--silent Silent mode in interactive shell
-v,--verbose Verbose mode (echo executed SQL to the
console)
变量和属性
–define key=value实际上和—hivevar key=value是等价的。二者都可以让用户在命令行定义用户自定义变量以便在Hive脚本中引用,来满足不同情况的执行。这个功能只有Hive v0.8.0版本和之后的版本才支持。
当用户使用这个功能时Hive会将这些键-值对放到hivevar命名空间,这样可以和其他3种内置命名空间(也就是hiveconf、system和env),进行区分。
命名空间 | 使用权限 | 描述 |
---|---|---|
hivevar | 可读/可写 | (Hive v0.8.0以及之后版本)用户自定义变量 |
hiveconf | 可读/可写 | Hive相关的配值属性 |
system | 可读/可写 | Java定义的配值属性 |
env | 只可读 | Shell环境(例如bash)定义的环境变量 |
Hive变量内部是以Java字符串的方式存储的。用户可以在查询中引用变量。Hive会先使用变量值替换掉查询的变量引用,然后才会将查询语句提交给查询处理器。
在CLI中,可以使用SET命令显示或者修改变量值。如:
hive> set env:HOME;
env:HOME=/home/hadoop
在命令行只输入set命令,会打印出命名空间hivevar,hiveconf,env和system中所有的变量;若在其后加上-v参数,则还会打印Hadoop中所定义的所有属性,例如控制HDFS和MapReduce的属性。
set命令还可用于给变量赋新的值。我们特别看一下hivevar命名空间以及如何通过命令行定义一个变量:
[hadoop@localhost hive]$ hive --define foo=bar
hive> set foo;
foo=bar
hive> set hivevar:foo;
hivevar:foo=bar
hive> set hivevar:foo=bar2;
hive> set foo;
foo=bar2
hive> set hivevar:foo;
hivevar:foo=bar2
我们可以看到,前缀hivevar:是可选的。–hivevar标记和–define标记是相同的。
在CLI中查询语句中的变量引用会被替换掉然后才会提交给查询处理器。思考如下这个CLI会话:
hive> CREATE TABLE toss1(i int, ${hivevar:foo} string);
OK
Time taken: 1.94 seconds
hive> DESCRIBE toss1;
OK
i int
bar2 string
Time taken: 0.356 seconds, Fetched: 2 row(s)
hive> CREATE TABLE toss2(i2 int, ${foo} string);
OK
Time taken: 0.285 seconds
hive> DESCRIBE toss2;
OK
i2 int
bar2 string
Time taken: 0.05 seconds, Fetched: 2 row(s)
hive> DROP TABLE toss1;
OK
Time taken: 0.817 seconds
hive> DROP TABLE toss2;
OK
Time taken: 0.162 seconds
我们来看看–hiveconf选项,其用于配置Hive行为的所有属性。我们用它来指定hive.cli.print.current.db属性。开启这个属性可以在CLI提示符前打印出当前所在的数据库名,默认的数据库名为default。这个属性的默认值是false。
[hadoop@localhost hive]$ hive --hiveconf hive.cli.print.current.db=true;
hive (default)> set hive.cli.print.current.db;
hive.cli.print.current.db=true
hive (default)> set hiveconf:hive.cli.print.current.db;
hiveconf:hive.cli.print.current.db=true
hive (default)> set hiveconf:hive.cli.print.current.db=false;
hive> set hiveconf:hive.cli.print.current.db=true;
hive (default)>
我们甚至可以增加新的hiveconf属性:
[hadoop@localhost hive]$ hive --hiveconf y=5;
hive> set y;
y=5
hive> CREATE TABLE whatsit(i int);
OK
Time taken: 0.883 seconds
hive> INSERT INTO TABLE whatsit VALUES(5);
OK
Time taken: 3.206 seconds
hive> SELECT * FROM whatsit WHERE i=${hiveconf:y};
OK
5
Time taken: 0.127 seconds, Fetched: 1 row(s)
我们还有必要了解一下system命名空间,Java系统属性对这个命名空间内容具有可读可写权力;而env命名空间,对于环境变量只提供可读权限:
hive> set system:user.name;
system:user.name=hadoop
hive> set system:user.name=yourusername;
hive> set system:user.name;
system:user.name=yourusername
hive> set env:HOME;
env:HOME=/home/hadoop
hive> set env:HOME=/home;
env:* variables can not be set.
Query returned non-zero code: 1, cause: null
和hivevar变量不同,用户必须使用system:和env:前缀来指定系统属性和环境变量。
env命名空间可作为向Hive传递变量的一个可选的方式,考虑如下这个例子:
[hadoop@localhost hive]$ YEAR=2012
[hadoop@localhost hive]$ hive -e "SELECT * FROM mytable WHERE year= ${env:YEAR}"
查询处理器会在WHERE子句中查看到实际的变量值2012。
提示:Hive中所有的内置属性都在$HIVE_HOME/conf/hive-default.xml.template中列举出来了,这是个“样例“配置文件。配置文件中还说明了这些属性的默认值。
Hive中“一次使用“命令
用户可能有时期望执行一个或者多个查询(使用分号分隔),执行结束后hive CLI立即退出。Hive提供了这样的功能,因为CLI可以接受-e命令这种形式。如果表mytable具有一个字符串字段和一个整型字段,我们可以看到如下输出:
[hadoop@localhost hive]$ hive -e "SELECT * FROM mytable LIMIT 2"
OK
name1 10
name2 20
Time taken: 1.088 seconds, Fetched: 2 row(s)
[hadoop@localhost hive]$
临时应急时可以使用这个功能将查询结果保存到一个文件中。增加-S选项可以开启静态模式,这样可以在输出结果中去掉”OK”和”Time taken”等行,以及其他一些无关紧要的输出信息,如下面这个例子:
[hadoop@localhost hive]$ hive -S -e "SELECT * FROM mytable LIMIT 2"
name1 10
name2 20
[hadoop@localhost hive]$
最后,当用户不能完整记清楚某个属性名时,可以使用下面这个非常有用的技巧来模糊获取这个属性名而无需滚动set命令的输出结果进行查找。假设用户没记清哪个属性指定了管理表的”warehouse(数据仓库)”的路径,通过如下命令可以查看到:
[hadoop@localhost hive]$ hive -S -e "SET" | grep warehouse
hive.metastore.warehouse.dir=/user/hive/warehouse
hive.warehouse.subdir.inherit.perms=true
从文件中执行Hive查询
Hive中可以使用 -f 文件名方式执行指定文件中的一个或者多个查询语句。按照管理,一般把这些Hive查询文件保存为具有.q或者.hql后缀名的文件。
[hadoop@localhost hive]$ hive -f query.hql
OK
name1 10
name2 20
name3 30
Time taken: 1.124 seconds, Fetched: 3 row(s)
[hadoop@localhost hive]$ cat query.hql
SELECT * FROM mytable LIMIT 3;
在Hive shell中用户可以使用SOURCE命令来执行一个脚本文件。如:
hive> SOURCE query.hql;
OK
name1 10
name2 20
name3 30
Time taken: 0.04 seconds, Fetched: 3 row(s)
hiverc文件
-i选项后接文件名,允许用户指定一个文件,当CLI启动时,在提示符出现前会执行这个文件。Hive会自动在HOME目录下寻找名为.hiverc的文件,而且会自动执行这个文件中的命令(如果文件中有的话)。
对于用户需要频繁执行的命令,使用这个文件是非常方便的。例如设置系统属性,或者增加对于Hadoop的分布式内存进行自定义的Hive扩展的Java包。
下面的例子显示的是一个典型的$HOME/.hiverc文件中的内容:
ADD JAR /path/to/custom_hive_extensions.jar;
set hive.cli.print.current.db=true;
set hive.exec.mode.local.auto=true;
上面例子第1行表示向Hadoop分布式内存中增加一个JAR文件。第2行表示修改CLI提示符前显示当前所在的工作数据库,最后1行表示“鼓励“Hive如果可以使用本地模式执行(即使当Hadoop是以分布式模式或伪分布式模式执行时)的话就在本地执行,这样可以加快小数据集的数据查询速度。
警告:一个比较容易犯的错误是忘记在每行的后面加逗号。如果用户犯了这个错误,那么这个属性将包含后面几行所有的文字,直到发现下一个逗号。
使用Hive CLI的更多介绍
CLI支持其他一些有用的功能。
自动补全功能
如果用户在输入的过程中敲击TAB键,那么CLI会自动补全可能的关键字或者函数名。例如,如果用户输入SELE然后按TAB键,CLI将会自动不全这个词为SELECT。
查看操作命令历史
用户可以使用上下箭头来滚动查看之前的命令。事实上,每一行之前的输入都是单独显示的,CLI不会把多行命令和查询作为一个单独的历史条目。Hive会将最近的100,00行命令记录到文件$HOME/.hivehistory中。
如果用户想再执行之前执行过的命令,只需要将光标滚动到那条记录然后按ENTER键就可以了。如果用户需要修改这行记录后再执行,那么需要使用左右方向键将光标移动到需要修改的地方然后重新编辑修改就可以了。修改后用户直接敲击ENTER键就可以提交这条命令而无需切换到命令尾。
执行shell命令
用户不需要退出hive CLI就可以执行简单的bash shell命令。只要在命令前加上!并且以分号(;)结尾就可以:
hive> ! /bin/echo "what up dog";
"what up dog"
hive> ! pwd;
/HOME/hadoop/hive
Hive CLI中不能使用需要用户进行输入的交互式命令,而且不支持shell的管道功能和文件名补全功能。例如,! ls .hql; 这个命令表示的是查找文件名为.hql的文件,而不是表示显示以.hql结尾的所有文件。
在Hive内使用Hadoop的dfs命令
用户可以在Hive CLI中执行Hadoop的dfs命令,只需要将Hadoop命令中的关键字hdfs去掉,然后以分号结尾就可以了:
hive> dfs -ls /;
Found 4 items
drwxr-xr-x - hadoop supergroup 0 2016-01-26 16:09 /hbase
drwxrwxr-x - hadoop supergroup 0 2016-01-26 15:31 /tmp
drwxr-xr-x - hadoop supergroup 0 2016-01-26 15:13 /user
drwxr-xr-x - hadoop supergroup 0 2016-01-26 15:47 /zookeeper
这种使用Hadoop命令的方式实际上比与其等价的在bash shell中执行hdfs dfs … 命令要更高效。因为后者每次都回启动一个新的JVM实例,而Hive会在同一个进程中执行这些命令。
Hive脚本中如何进行注释
用户可以使用以–开头的字符串来表示注释,例如:
-- Copyright (c) 2016
-- This is a hive script
SELECT * FROM mytable;
显示字段名称
我们可以让CLI打印出字段名称(这个功能默认是关闭的)。我们可以通过设置hiveconf配置项hive.cli.print.header为true来开启这个功能:
hive> set hive.cli.print.header=true;
hive> SELECT * FROM mytable;
OK
mytable.str mytable.i
name1 10
name2 20
name3 30
name4 40
Time taken: 1.367 seconds, Fetched: 4 row(s)
如果用户希望总是看到字段名称,那么只需要将这行配置添加到$HOME/.hiverc文件中即可。