Hive入门

Posted 杀智勇双全杀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hive入门相关的知识,希望对你有一定的参考价值。

Hive入门(一)

Hive客户端与服务端

Hive Shell

客户端与服务端是一体的,交互为纯文本,对新手极不友好,用于封装SQL脚本。直接使用hive命令即可启动。

由于多人操作时会开启多个客户端与多个配套的服务端,可能导致资源抢占等问题,正常的方式应该是1个服务端多个客户端的一主多从结构。这种方式使用不多。

beeline与hiveserver2

beeline是纯客户端,hiveserver2是Hive中独立的服务端进程。

先结束掉Hive,切换目录到hive,并且查看bin目录下的文件:

[root@node3 ~]# cd /export/server/hive-2.1.0-bin/
[root@node3 hive-2.1.0-bin]# ll ./bin
总用量 64
-rwxr-xr-x 1 root root 1436 6月   3 2016 beeline
-rwxr-xr-x 1 root root 2553 6月   3 2016 beeline.cmd
drwxr-xr-x 3 root root 4096 5月   1 21:31 ext
-rwxr-xr-x 1 root root 8692 6月  17 2016 hive
-rwxr-xr-x 1 root root 8823 6月   3 2016 hive.cmd
-rwxr-xr-x 1 root root 1584 6月   3 2016 hive-config.cmd
-rwxr-xr-x 1 root root 1900 6月   3 2016 hive-config.sh
-rwxr-xr-x 1 root root  885 6月   3 2016 hiveserver2
-rwxr-xr-x 1 root root 1030 6月   3 2016 hplsql
-rwxr-xr-x 1 root root 2278 6月   3 2016 hplsql.cmd
-rwxr-xr-x 1 root root  832 6月   3 2016 metatool
-rwxr-xr-x 1 root root  884 6月   3 2016 schematool

自带了启动命令。

启动beeline可以这样:

beeline -u jdbc地址 -n  用户名  -p 密码

或者这样(就像mysql也可以一步输入账号密码或者密码作为第二次输入。。。beeline也可以分多次输入内容):

beeline
!connect jdbc地址
用户名
密码

启动hiveserver2可以:

hive --service hiveserver2

或者直接:

hiveserver2

当前状态metastore服务已经开启,如果读者的该服务未开启,使用:

hive --service metastore

之后再换一个命令行启动hiveserver2:

hiveserver2

再新建个命令行,使用jps查看进程:

[root@node3 ~]# jps
5670 Jps
5529 RunJar
4858 NodeManager
4491 DataNode
4747 ResourceManager
3820 RunJar

这货一般是用10000端口

[root@node3 ~]# netstat -atunlp |grep 10000
tcp        0      0 0.0.0.0:10000           0.0.0.0:*               LISTEN      5529/java 

偶尔会有用10001端口的情况,但是协议不同。。。也能用。。。

服务端启动了,但是没有客户端,形同虚设。。。

配置用户授权

当前情况没办法使用客户端。。。

命令行多按几次escctrl+c先结束掉之前开启的hiveserver前台程序。。。

老规矩,为了防止意外故障。。。

关闭HDFS和YARN:

stop-dfs.sh
stop-yarn.sh

使用jps查看,确保3个节点的无关进程都已退出。

修改core-site.xml

在node1:

cd /export/server/hadoop-2.7.5/etc/hadoop/
vim core-site.xml

找个空插入:

<property> 
    <name>hadoop.proxyuser.root.hosts</name>
    <value>*</value> 
</property> 
<property> 
    <name>hadoop.proxyuser.root.groups</name> 
    <value>*</value> 
</property>

记得保存。

分发

node1使用:

scp core-site.xml node2:$PWD
scp core-site.xml node3:$PWD

启动HDFS和YARN

start-dfs.sh
start-yarn.sh

复制standalone包

[root@node3 hive-2.1.0-bin]# cd /export/server/hive-2.1.0-bin
[root@node3 hive-2.1.0-bin]# ll
总用量 112
drwxr-xr-x 3 root root   209 5月   1 21:31 bin
drwxr-xr-x 2 root root  4096 5月   2 19:52 conf
drwxr-xr-x 4 root root    34 5月   1 21:31 examples
drwxr-xr-x 7 root root    68 5月   1 21:31 hcatalog
drwxr-xr-x 2 root root    44 5月   1 21:31 jdbc
drwxr-xr-x 4 root root  8192 5月   1 21:59 lib
-rw-r--r-- 1 root root 29003 6月   3 2016 LICENSE
-rw-r--r-- 1 root root   513 6月   3 2016 NOTICE
-rw-r--r-- 1 root root  4122 6月   3 2016 README.txt
-rw-r--r-- 1 root root 50294 6月  17 2016 RELEASE_NOTES.txt
drwxr-xr-x 4 root root    35 5月   1 21:31 scripts
[root@node3 hive-2.1.0-bin]# ll ./jdbc/
总用量 17084
-rw-r--r-- 1 root root 17491833 6月  17 2016 hive-jdbc-2.1.0-standalone.jar

可以看到歪果仁脑回路比较新奇。。。这个jar包是依赖库而不是可执行脚本,放错了位置。。。

还是node3:

cd /export/server/hive-2.1.0-bin
cp jdbc/hive-jdbc-2.1.0-standalone.jar lib/

启动

先启动metastore:

hive --service metastore

再启动hiveserver2:

hiveserver2

由于都是前台程序,只好开第三个命令行。。。

[root@node3 ~]# beeline
which: no hbase in (::/export/server/jdk1.8.0_241/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/export/server/hadoop-2.7.5/bin:/export/server/hadoop-2.7.5/sbin:/export/server/hive-2.1.0-bin/bin:/root/bin)
Beeline version 2.1.0 by Apache Hive
beeline> !connect jdbc:hive2://node3:10000
Connecting to jdbc:hive2://node3:10000
Enter username for jdbc:hive2://node3:10000: root
Enter password for jdbc:hive2://node3:10000: ******
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/export/server/hive-2.1.0-bin/lib/hive-jdbc-2.1.0-standalone.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/export/server/hive-2.1.0-bin/lib/log4j-slf4j-impl-2.4.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/export/server/hadoop-2.7.5/share/hadoop/common/lib/slf4j-log4j12-1.7.10.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]
Connected to: Apache Hive (version 2.1.0)
Driver: Hive JDBC (version 2.1.0)
21/05/02 22:01:16 [main]: WARN jdbc.HiveConnection: Request to set autoCommit to false; Hive does not support autoCommit=false.
Transaction isolation: TRANSACTION_REPEATABLE_READ
0: jdbc:hive2://node3:10000> 

或者:

beeline -u jdbc:hive2://node3:10000 -n root -p 123456

都可以进入。

还可以查看下数据库:

0: jdbc:hive2://node3:10000> show databases;
+----------------+--+
| database_name  |
+----------------+--+
| aaa            |
| default        |
+----------------+--+
2 rows selected (1.603 seconds)
0: jdbc:hive2://node3:10000> 

由于是客户端直连服务端,并由metastore服务直接读取数据库,比起用Hive的SQL还是要快不少的。。。

JDBC连接server2

在新项目的pom.xml配置:

<properties>
        <hadoop.version>2.7.5</hadoop.version>
        <mysql.version>5.1.38</mysql.version>
        <hive.version>2.1.0</hive.version>
    </properties>

    <dependencies>
        <!--引入单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <!-- Hadoop Client 依赖 -->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>${hadoop.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>${hadoop.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>${hadoop.version}</version>
        </dependency>
        <!-- MySQL Client 依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>
        <!-- Hive依赖 -->
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-exec</artifactId>
            <version>${hive.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-common</artifactId>
            <version>${hive.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-cli</artifactId>
            <version>${hive.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-jdbc</artifactId>
            <version>${hive.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

使用代码:


import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;

//使用JDBC访问Hive数据的客户端
public class HiveJdbcClient {

    private static String driverName = "org.apache.hive.jdbc.HiveDriver";

    public static void main(String[] args) throws SQLException {
        try {
            Class.forName(driverName);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.exit(1);
        }

        Connection con = DriverManager.getConnection("jdbc:hive2://node3:10000/default", "root", "123456");
        Statement stmt = con.createStatement();
        String tableName = "tb_house";
        String sql = "select region,t_price,s_price from " + tableName +" limit 100";
        System.out.println("Running: " + sql);
        ResultSet res = stmt.executeQuery(sql);
        while (res.next()) {
            System.out.println(res.getString(1) + "\\t" + res.getInt(2)+ "\\t" + res.getInt(3));
        }

    }
}

成功读取出所需数据:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Program%20Files/apache-maven-3.3.9/Maven_Repository/org/slf4j/slf4j-log4j12/1.7.10/slf4j-log4j12-1.7.10.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Program%20Files/apache-maven-3.3.9/Maven_Repository/org/apache/logging/log4j/log4j-slf4j-impl/2.4.1/log4j-slf4j-impl-2.4.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
log4j:WARN No appenders could be found for logger (org.apache.hive.jdbc.Utils).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Running: select region,t_price,s_price from tb_house limit 100

浦东	472	60629

Process finished with exit code 0

(数据太多没什么用,此处为了节省篇幅全删了。。。)

Hive启动脚本

很多操作是异常不方便。。。使用脚本可以实现自动化,解放人力。。。

由于Hive是安装在node3,脚本当然也应该在node3。。。又得开个新的命令行。。。安装Linux时没有安装GUI,出现前台应用是真的烦。。。

Hive服务端启动脚本

mkdir /export/server/hive-2.1.0-bin/logs

Metastore启动脚本

vim /export/server/hive-2.1.0-bin/bin/start-metastore.sh
#!/bin/bash
#HIVE_HOME
HIVE_HOME=/export/server/hive-2.1.0-bin
#run metastore
$HIVE_HOME/bin/hive --service metastore >> $HIVE_HOME/logs/metastore.log 2>&1 &

这个脚本最后的&代表后台运行,>>代表输出重定向,2>&1是把错误的日志也写入日志中(否则会输出到前台的命令行)。。。

HiveServer2启动脚本

vim /export/server/hive-2.1.0-bin/bin/start-hiveserver2.sh
#!/bin/bash
#HIVE_HOME
HIVE_HOME=/export/server/hive-2.1.0-bin
#run hiveserver2
$HIVE_HOME/bin/hiveserver2  >> $HIVE_HOME/logs/hiveserver2.log 2>&1 &

客户端Beeline启动脚本

vim /export/server/hive-2.1.0-bin/bin/start-beeline.sh
#!/bin/bash
#HIVE_HOME
HIVE_HOME=/export/server/hive-2.1.0-bin
#run beeline
$HIVE_HOME/bin/beeline -u jdbc:hive2://node3:10000 -n root -p 123456

修改权限

chmod u+x /export/server/hive-2.1.0-bin/bin/start-*

Hive的SQL脚本

很多时候需要让脚本自动运行以节省人力,但是shell并不能自动跑Hive的SQL脚本。。。

使用:

hive -h
Unrecognized option: -h
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)

显然需要-e-f的命令。
-e:执行命令行中的SQL语句。直接执行命令行中提供的SQL语句,适合要执行比较少的单条SQL语句。
-f:执行一个SQL文件。

例如:

命令行启动SQL

hive -e 'show databases;'

虽然很慢,但还是:

Logging initialized using configuration in jar:file:/export/server/hive-2.1.0-bin/lib/hive-common-2.1.0.jar!/hive-log4j2.properties Async: true
OK
aaa
default
Time taken: 1.561 seconds, Fetched: 2 row(s)

成功显示出正确结果。。。

文件中启动SQL

创建个SQL文件:

vim /export/data/hive.sql
show databases;
use default;
select region,s_price,area from tb_house limit 10;

执行SQL:

hive -f /export/data/hive.sql

定时任务

#!/bin/bash


#定义变量
HIVE_HOME=/export/server/hive-2.1.0-bin
#运行SQL语句
#$HIVE_HOME/bin/hive -e 'show databases;'
$HIVE_HOME/bin/hive -f /export/data/hive.sql

借助Crontab,配置:

01	00	*	*	*	bash  /export/data/exec.sh

可以实现定时启动。

SQL脚本中传递变量

很多时候脚本的参数是变化的,不能写死。。。这种情况需要:
–hiveconf:用于定义Hive中属性的值或者定义Hive中的变量。
例如:
shell脚本:

#!/bin/bash

#获取昨天的日期
yesterday=`date -d '-1 day' +%Y%m%d`

#定义变量
HIVE_HOME=/export/server/hive-2.1.0-bin
#运行SQL语句
#$HIVE_HOME/bin/hive -e 'select  count(*) from table where daystr = '${yesterday}';'

$HIVE_HOME/bin/hive --hiveconf yester=${yesterday} -f /export/data/hive.sql

SQL文件:

select  count(*) from table where daystr = '${hiveconf:yester}';

经过了变量传递,将shell的变量传到了文件中。

Hive常用命令

很多和dfs命令很像,例如:

0: jdbc:hive2://node3:10000> dfs -ls /;
+--------------------------------------------------------------------------+--+
|                                DFS Output                                |
+--------------------------------------------------------------------------+--+
| Found 5 items                                                            |
| drwxr-xr-x   - killer supergroup          0 2021-04-25 22:56 /bigdata    |
| drwxr-xr-x   - root   supergroup          0 2021-05-01 23:05 /export     |
| drwx-w----   - root   supergroup          0 2021-05-01 22:30 /tmp        |
| drwx------   - root   supergroup          0 2021-05-01 22:15 /user       |
| drwxr-xr-x   - root   supergroup          0 2021-04-26 20:23 /wordcount  |
+--------------------------------------------------------------------------+--+
6 rows selected (0.039 seconds)
0: jdbc:hive2://node3:10000> 

由于是客户端直连,速度很快。

0: jdbc:hive2://node3:10000> set hive.exec.mode.local.auto
. . . . . . . . . . . . . .> ;
+----------------------------------+--+
|               set                |
+----------------------------------+--+
| hive.exec.mode.local.auto=false  |
+----------------------------------+--+
1 row selected (0.016 seconds)
0: jdbc:hive2://node3:10000> 

使用set hive.exec.mode.local.auto可以设置模式。默认false为完全分布式,使用:

set hive.exec.mode.local.auto=true;

即可设置为本地模式,单机跑MapReduce测试逻辑的正确性(小数据量的MR程序运行的比较快,不提交给YARN)。。。

MapTask的个数不允许超过4个。
ReduceTask个数不允许超过1个。
输入数据量不允许超过128M。

可以使用add添加jar包/文件到Hive的环境变量:

add jar  xxx.jar;
add file xxx

可以使用list列举添加的文件/jar包:

list files
list jars

还可以使用delete删除添加的文件或者jar包。

Hive日志配置

日志

DEBUG:详细的日志级别。
INFO:显示的信息会包含主要的日志信息。
WARN:只记录警告级别的日志。
ERROR:只记录错误级别的日志。

日志存储配置

重命名配置文件

cd /export/server/hive-2.1.0-bin/conf/
mv hive-log4j2.properties.template hive-log4j2.properties

修改配置

vim hive-log4j2.properties

注释/直接修改24行:

property.hive.log.dir = /export/server/hive-2.1.0-bin/logs

在这里插入图片描述
还需要重启Hive的服务器node3才能生效。。。

使用ctrl+c干掉前台进程,clear清空内容。使用jps查看进程,确保Hive程序已经关闭。

node1:

stop-dfs.sh

node3:

stop-yarn.sh

使用jps查看进程,确保关闭后使用reboot重启或者poweroff掉电。笔者选择掉电,先拍个快照再说!!!

以上是关于Hive入门的主要内容,如果未能解决你的问题,请参考以下文章

Hive函数入门--案例:UDF实现手机号加密--代码实现与效果演示

大数据仓库Hive实战视频教程-HIVE完美入门学习视频教程 HIVE教程 HIVE从入门到精通

Hive入门

Hive入门

Hive入门

Atom编辑器入门到精通 Atom使用进阶