Hive的安装和使用

Posted by RussXia on March 28, 2019

前置准备

  • 安装JDK
  • 安装Mysql
  • 安装Hadoop
  • 启动HDFS和YARN

Hive的安装

  • 下载hive https://hive.apache.org/downloads.html
  • 配置相关参数(本例以本地模式(local metastroe)启动)
    • 启动mysql,并创建对应数据库(本例名为hive)
    • 将mysql的jdbc连接驱动cp到HIVE_HOME/lib目录下
    • 修改HIVE_HOME/conf目录下的hive-env.sh
         # Set HADOOP_HOME to point to a specific hadoop install directory
         HADOOP_HOME=/Users/russ/devtools/hadoop-2.9.2
       
        # Hive Configuration Directory can be controlled by:export HIVE_CONF_DIR=/Users/russ/devtools/apache-hive-2.3.4-bin/conf
      
    • 配置hive-site.xml文件
        <property>
            <name>javax.jdo.option.ConnectionURL</name>
            <value>jdbc:mysql://localhost/hive?createDatabaseIfNotExist=true</value>
            <description>JDBC connect string for a JDBC metastore</description>
        </property>
        <property>
            <name>javax.jdo.option.ConnectionDriverName</name>
            <value>com.mysql.jdbc.Driver</value>
            <description>Driver class name for a JDBC metastore</description>
        </property>
        <property>
            <name>javax.jdo.option.ConnectionUserName</name>
            <value>hive</value>
            <description>Username to use against metastore database</description>
        </property>
        <property>
            <name>javax.jdo.option.ConnectionPassword</name>
            <value>123456</value>
            <description>password to use against metastore database</description>
        </property>
      
  • 配置完成,启动hive

Hive的使用

Hive中默认有一个default库,进入hive-cli之后,默认使用的就是default库。

Hive中的数据库在hdfs的存储路径为:${hive.metastore.warehouse.dir}/databasename.db(dir文件夹),

创建hive数据库

hive> create database test_hive;
OK
Time taken: 0.085 seconds
grunt> ls /user/hive/warehouse
hdfs://localhost:9000/user/hive/warehouse/test_hive.db	<dir>

Hive QL

Hive中数据表分为托管表(managed table)和外部表(external table)两种。托管表会在load时把数据移到它的”仓库目录”(${hive.metastore.warehouse.dir}/databasename.db)下,外部表则不会。

两者的区别:

  • 内部表DROP时候会删除HDFS上的数据
  • 外部表DROP时候不会删除HDFS上的数据

内部表适用场景:Hive中间表、结果表、一般不需要从外部(如本地文件、HDFS上load数据)的情况。

外部表适用场景:源表,需要定期将外部数据映射到表中。 关于Hive QL中的建表语句

  • 关键字EXTERNAL: 表示创建的是一个外部表。
  • 关键字PARTITIONED BY: 表示该表为分区表,分区字段为day,类型为string
  • 关键字ROW FORMAT DELIMITED:指定表的分隔符,通常后面要与以下关键字连用:
    • FIELDS TERMINATED BY ‘,’ //指定每行中字段分隔符为逗号
    • LINES TERMINATED BY ‘\n’ //指定行分隔符
    • COLLECTION ITEMS TERMINATED BY ‘,’ //指定集合中元素之间的分隔符
    • MAP KEYS TERMINATED BY ‘:’ //指定数据中Map类型的Key与Value之间的分隔符
  • 关键字STORED AS:指定表在HDFS上的文件存储格式,可选的文件存储格式有 TEXTFILE(文本,默认值)、SEQUENCEFILE(二进制序列化文件)、RCFILE、ORC、PARQUET。
  • 关键词LOCATION:指定表在HDFS上的存储位置。

建表

hive> create table records(year string, temperature int, quality int)
    > row format delimited
    > fields terminated by '\t';
OK
Time taken: 1.081 seconds
hive> CREATE EXTERNAL TABLE hello_hive (
    > id INT,
    > name STRING COMMENT 'name'
    > ) COMMENT 'hello_hive'
    > PARTITIONED BY (day STRING)
    > ROW FORMAT DELIMITED
    > FIELDS TERMINATED BY ','
    > STORED AS textfile
    > LOCATION 'hdfs://localhost:9000/test_data';
OK
Time taken: 0.187 seconds
grunt> ls /user/hive/warehouse/test_hive.db
hdfs://localhost:9000/user/hive/warehouse/test_hive.db/records	<dir>  ##hello_hive是外部表
grunt> ls /user/hive/warehouse/test_hive.db/records ##此时表中无数据
grunt>

此时的mysql库中存储的metastore数据,DBS表和TBLS表中可以看到以下数据,可以看到records表和hello_hive表的数据类型分别是MANAGED_TABLE和EXTERNAL_TABLE。

dbs表数据

1	Default Hive database	hdfs://localhost:9000/user/hive/warehouse	default	public	ROLE
6	NULL	hdfs://localhost:9000/user/hive/warehouse/test_hive.db	test_hive	russ	USER

tbls表数据

2	1553760921	6	0	russ	0	2	records	MANAGED_TABLE	NULL	NULL	0
4	1553761800	6	0	russ	0	4	hello_hive	EXTERNAL_TABLE	NULL	NULL	0

加载数据

加载数据,对于hive来说,加载数据时是不做验证的,所以加载速度很快。

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

如果指定了 LOCAL, load 命令会去查找本地文件系统中的 filepath。如果没有指定 LOCAL 关键字,则根据inpath中的uri查找文件。

如果使用了 OVERWRITE 关键字,则目标表(或者分区)中的内容会被删除,然后再将 filepath 指向的文件/目录中的内容添加到表/分区中。如果目标表(分区)已经有一个文件,并且文件名和 filepath 中的文件名冲突,那么现有的文件会被新文件所替代。

hive> load data inpath 'hdfs://localhost:9000/test_data/hello_hive1.txt' into table hello_hive partition(day = '20190328');
Loading data to table test_hive.hello_hive partition (day=20190328)
OK
hive> select count(*) from hello_hive;
WARNING: Hive-on-MR is deprecated in Hive 2 and may not be available in the future versions. Consider using a different execution engine (i.e. spark, tez) or using Hive 1.X releases.
Query ID = ruzzzz_20190328165647_916ad839-00dc-4c06-8a3e-c09e62d0705f
Total jobs = 1
Launching Job 1 out of 1
>>>中间省略
Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 1
2019-03-28 16:57:22,431 Stage-1 map = 0%,  reduce = 0%
2019-03-28 16:57:29,920 Stage-1 map = 100%,  reduce = 0%
2019-03-28 16:57:38,281 Stage-1 map = 100%,  reduce = 100%
Ended Job = job_1553763421343_0001
MapReduce Jobs Launched:
Stage-Stage-1: Map: 1  Reduce: 1   HDFS Read: 8011 HDFS Write: 102 SUCCESS
Total MapReduce CPU Time Spent: 0 msec
OK
20

关于Hive中的分区和桶

Hive中把表组织成分区(partition)。这是一种根据分区列(partition colim,如日期)的值对表进行粗略划分的机制。使用分区可以加快数据分片(slice)的查询速度。

表或分区可以进一步分为桶(bucket)。它会为数据提供额外的结构以获得更高效的查询处理。例如,通过根据用户ID来划分桶,我们可以在所有用户集合的随机样本上快速计算基于用户的查询。