前置准备
- 安装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来划分桶,我们可以在所有用户集合的随机样本上快速计算基于用户的查询。