一、前情回顾
二、Hive01
三、Hive的安装部署
四、Hive的DDL操作
五、可能涉及的面试题
Hadoop:
狭义:单单指apache hadoop软件(最最重要基础的一个部分)
广义:Hadoop生态圈:Hadoop、Hive、Sqoop、HBase…
每一类的组件都是为了解决特定事情,比如Hive是做sql的分析引擎,生产上需要基于多个框架进行组合来实现业务场景。
如何快速定位问题?及如何快速的解决问题
比如在Hadoop中需要处理如下业务:join/group by ,
===> Hive的产生背景
而对于HDFS上的文件,主要分为:txt文本格式,它不存在表名、列名、列类型;关于文本格式我们顶多能做的是按照分隔符(\t):来知道第一列是什么、第二列是什么
源数据:HDFS上的数据
元数据:是描述数据的数据,比如数据的表名,列名,列类型
Hive官网:hive.apache.org
官网对Hive的描述:
The Apache Hive data warehouse software facilitates(促进)
reading,
writing,
managing large datasets residing
in distributed storage(HDFS/S3)
using SQL.
A command line tool
and JDBC driver are provided to connect users to Hive.
翻译:
1、Hive中的数据是存放在hdfs上;
2、Hive底层的执行引擎有MapReduce/Spark/Tez,只需要修改一个参数即可;
(hive (ruozedata_hive)> set hive.execution.engine;
hive.execution.engine=mr)
3、Hive的作业是提交到Yarn上运行的;
4、Hive提供了HiveQL的查询语言,这个语言和SQL类似,但是不完全相同。
Hive适用于离线处理/批处理(一下子处理一个批次的数据),实时处理/流处理;
至此:HDFS上的数据:文本、压缩、列式存储,Hive就是使用sql来处理hadoop上的数据。
SQL on Hadoop:Hive/Presto/Impala/Spark SQL,如果sql语法兼容不是很好的话,就需要你进行自定义UDF函数。
优点:SQL(处理方便,受众面广)
缺点:Hive的底层执行引擎是MapReduce的话,它的执行性能必然是不高的。
如下这块是Hive自动为我们完成的:
一条SQL只是普通的不能再普通的字符串,它进入到Driver驱动程序,需要借助于SQL Parser(SQL解析器),把SQL的语法进行解析 --> Query Optimizer(查询优化器)–> Pyhsical Plan(逻辑执行计划)–> 如果语法不支持的话你需要自定义UDF函数 --> SerDes(序列化、反序列化)–> Execution(执行)。
一个table,是属于哪个DB,table默认存放在HDFS上的路径/user/hive/warehouse,table的字段信息 --> 存储在MetaStore,这些信息需要让MapReduce知道;红色这个框中的Metastore是非常重要的,元数据默认是存放在derby和MySQL中的,derby一般不用,使用MySQL,此处的MySQL也不能使用单点,单点故障就会出现停止服务,生产上都是使用MySQL主备机制。
第一层是用户接口层:通过linux黑窗口、JDBC的方式
第二层是Driver驱动程序:
SQL解析:SQL --> AST(antlr抽象语法树)
查询优化:逻辑/物理执行计划
UDF/SerDes:
Execution:执行
元数据:表名、列(名字、类型、index)、所属数据库、表类型(内部表和外部表)、表数据在hdfs上的路径:
Hive和RDBMS比较:
相同点:
都使用SQL、Hive现在也支持事务(一般不使用,主要原因:Hive是批处理)
都支持insert、update、delete
针对于离线Hive的数仓来说,写内容是比较少的,一般是批次加载数据到Hive然后进行统计分析;
不同点:体量上:关系型数据库是在页面上点一个按钮,立马能在页面上展示出来;Hive的延时性较高;也体现在Hive的集群规模上(Hive需要部署在性能较高的机器上);
我们千万不要用Hive做的一个操作是:在页面上做一个按钮,后台执行Hive作业,数据量小还好,数据量多的话这个作业跑8 9个小时也正常,这种方式是不行的。
1、在Hive0.14中支持insert语法:
2、在Hive0.14中支持update语法:
3、在Hive0.14中支持delete语法:
此Hive版本指的是Apache Hive
1、前置环境要求:
至少是jdk1.7、Hadoop2.x、注意元数据信息的存储位置:需要提前部署MySQL
2、安装的两种方式:
此处选择解压安装:
因为使用Hadoop版本是:hadoop2.6.0-cdh5.16.2,所以我们Hive使用的是hive-1.1.0-cdh5.16.2版本;使用wget下载:wget http://archive.cloudera.com/cdh5/cdh/5/hive-1.1.0-cdh5.16.2.tar.gz,国内下载极为缓慢,可以购买海外服务器哈哈。
我们下载cdh版本的网址:http://archive.cloudera.com/cdh5/cdh/5/
1、下载并且解压:
[hadoop@hadoop001 software]$ tar -xzvf hive-1.1.0-cdh5.16.2.tar.gz -C /home/hadoop/app/
2、配置环境变量:vi ~/.bashrc
export HIVE_HOME=/home/hadoop/app/hive
export PATH=${HIVE_HOME}/bin:$PATH
3、生效环境变量:
source ~/.bashrc
4、生效完后记得which一下:
[hadoop@hadoop001 app]$ which hive
~/app/hive/bin/hive
bin:脚本
lib:依赖包
conf:配置文件
3、配置$HIVE_HOME/conf/hive-site.zml
默认这个目录下只有4个文件,需要新建一个hive-site.xml,文件内容如下:
hive-site.xml配置内容解析:connection url(hadoop001机器mysql数据库的3306端口,ruozedata_hive不需要手动创建,如果该库不存在会自行创建)、driver name(mysql驱动包)、username(mysql用户名)、password(mysql密码);
javax.jdo.option.ConnectionURL
jdbc:mysql://hadoop001:3306/ruozedata_hive?createDatabaseIfNotExist=true
javax.jdo.option.ConnectionDriverName
com.mysql.jdbc.Driver
javax.jdo.option.ConnectionUserName
root
javax.jdo.option.ConnectionPassword
xxxx
hive.cli.print.current.db
true
//打印出来当前的数据库名称
hive.cli.print.header
true
//打印数据库表内容中的头部信息
4、将MySQL驱动包上传到$HIVE_HOME/conf目录下:
5、启动hive前肯定是需要启动hdfs的,start-dfs.sh
Fri Mar 27 22:18:58 CST 2020 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
翻译:不建议不使用服务器身份验证建立SSL连接;
解决:在尾部添加useSSL=true;
jdbc:mysql://hadoop001:3306/ruozedata_hive?createDatabaseIfNotExist=true&useSSL=true
hive (default)> use default;
FAILED: SemanticException org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient
首先要知道遇到错误,百度到的解决方案不一定能套用到你的身上;我们要学会查看log日志,hive的log日志路径:/tmp/{用户名}/hive.log
1、日志路径如下:
[root@hadoop001 hadoop]# pwd
/tmp/hadoop
[root@hadoop001 hadoop]# ll
total 5508
drwx------ 2 hadoop hadoop 4096 Mar 27 22:27 34490222-9c95-43ba-a00f-e0dddee5cd14
-rw-rw-r-- 1 hadoop hadoop 0 Mar 27 22:27 34490222-9c95-43ba-a00f-e0dddee5cd146362926509336115670.pipeout
-rw-rw-r-- 1 hadoop hadoop 0 Mar 27 22:27 34490222-9c95-43ba-a00f-e0dddee5cd147456770903589387510.pipeout
-rw-rw-r-- 1 hadoop hadoop 5621893 Mar 27 22:46 hive.log
2、tail -F hive.log --> 实时查看hive.log打印出来的日志信息,发现有如下两行信息:
Caused by: java.sql.SQLException: Unable to open a test connection to the given database. JDBC url = jdbc:mysql://hadoop001:3306/ruozedata_hive?createDatabaseIfNotExist=true&useSSL=true, username = root. Terminating connection pool (set lazyInit to true if you expect to start your database after your app). Original Exception: ------
java.sql.SQLException: Access denied for user 'root'@'hadoop001' (using password: YES)
//提示访问受限,哭了,原来是账号密码设置错了;还有可能的情况,注意mysql数据库有没有允许其它地址的主机去访问它,也就是一个“%”权限。
1、展示所有数据库:
hive (default)> show databases;
OK
database_name
default
Time taken: 0.03 seconds, Fetched: 1 row(s)
2、使用default数据库:
hive (default)> use default;
OK
Time taken: 0.025 seconds
3、展示数据表:
hive (default)> show tables;
OK
tab_name
Time taken: 0.128 seconds
4、在default数据库下创建stu表:
hive (default)> create table stu(id int,name string,age int);
OK
Time taken: 0.363 seconds
5、描述stu表:
hive (default)> desc stu;
OK
col_name data_type comment
id int
name string
age int
Time taken: 0.175 seconds, Fetched: 3 row(s)
6、查看表结构:
- desc stu;
- desc extended stu;
- desc formatted stu; //这种方式更好一些
hive (default)> desc formatted stu;
OK
col_name data_type comment
# col_name data_type comment
id int
name string
age int
# Detailed Table Information
Database: default
OwnerType: USER
Owner: hadoop
CreateTime: Fri Mar 27 23:29:21 CST 2020
LastAccessTime: UNKNOWN
Protect Mode: None
Retention: 0
Location: hdfs://hadoop001:9000/user/hive/warehouse/stu
Table Type: MANAGED_TABLE
Table Parameters:
transient_lastDdlTime 1585322961
# Storage Information
SerDe Library: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
InputFormat: org.apache.hadoop.mapred.TextInputFormat
OutputFormat: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
Compressed: No
Num Buckets: -1
Bucket Columns: []
Sort Columns: []
Storage Desc Params:
serialization.format 1
Time taken: 0.138 seconds, Fetched: 29 row(s)
6、展示建表语句:show create table stu;
hive (default)> show create table stu;
OK
createtab_stmt
CREATE TABLE `stu`(
`id` int,
`name` string,
`age` int)
ROW FORMAT SERDE
'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
'hdfs://hadoop001:9000/user/hive/warehouse/stu'
TBLPROPERTIES (
'transient_lastDdlTime'='1585322961')
Time taken: 0.133 seconds, Fetched: 14 row(s)
7、插入语句:千万不要这么用(仅仅做演示)
insert into stu values(1,'john',24);
8、select * from stu;
1、insert插入数据,还会跑mapreduce
hive (default)> insert into stu values(1,"john",24);
Query ID = hadoop_20200327233535_a0100136-77e5-4d07-ad69-de835ec91403
Total jobs = 3
Launching Job 1 out of 3
Number of reduce tasks is set to 0 since there's no reduce operator
1、hive在hdfs上的存储目录:
我们创建的stu表,默认存储在hdfs的目录是:Location: hdfs://hadoop001:9000/user/hive/warehouse/stu
那我们如何更改这个hdfs的默认存储目录呢?
我们找到的存储目录参数如下所示:
Hive.metastore.warehouse.dir
Default Value: /user/hive/warehouse
Added In: Hive 0.2.0
Location of default database for the warehouse.
2、hive的日志文件存储目录:
1、路径如下:
[hadoop@hadoop001 conf]$ pwd
/home/hadoop/app/hive/conf
2、拷贝一份配置文件:
[hadoop@hadoop001 conf]$ cp hive-log4j.properties.template hive-log4j.properties
3、编辑这份配置文件:vi hive-log4j.properties
hive.log.dir=${java.io.tmpdir}/${user.name}
hive.log.file=hive.log
因为linux定期清理规则,所以/tmp下的文件建议进行修改:
hive.log.dir=/home/hadoop/tmp/hive
3、Hive配置属性:
全局:$HIVE_HOME/conf/hive-site.xml中
临时/当前session:
查看当前的属性:set key
设置当前属性:set key = value
1、查看这个显示数据库的参数开关是否打开,发现未打开
hive> set hive.cli.print.current.db;
hive.cli.print.current.db=false
2、显示数据库的参数打开:
hive> set hive.cli.print.current.db=true;
hive (default)>
//注意:临时session只对当前窗口有效,新开窗口后就是无效的
4、Hive上查看文件存储路径:
hive (default)> dfs -ls /user/hive/warehouse;
Found 1 items
drwx------ - hadoop supergroup 0 2020-03-27 23:36 /user/hive/warehouse/stu
查看hive的命令帮助:
[hadoop@hadoop001 conf]$ hive -help
which: no hbase in (/home/hadoop/app/hive/bin:/home/hadoop/app/hadoop/bin:/home/hadoop/app/hadoop/sbin:/usr/java/jdk1.8.0_45/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/hadoop/bin)
20/03/28 00:13:46 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
usage: hive
-d,--define Variable subsitution to apply to hive
commands. e.g. -d A=B or --define A=B
--database Specify the database to use
-e SQL from command line
-f SQL from files
-H,--help Print help information
--hiveconf Use value for given property
--hivevar Variable subsitution to apply to hive
commands. e.g. --hivevar A=B
-i Initialization SQL file
-S,--silent Silent mode in interactive shell
-v,--verbose Verbose mode (echo executed SQL to the
console)
hive -e “select * from stu;”
[hadoop@hadoop001 conf]$ hive -e "select * from stu;"
which: no hbase in (/home/hadoop/app/hive/bin:/home/hadoop/app/hadoop/bin:/home/hadoop/app/hadoop/sbin:/usr/java/jdk1.8.0_45/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/hadoop/bin)
20/03/28 00:13:04 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Logging initialized using configuration in file:/home/hadoop/app/hive-1.1.0-cdh5.16.2/conf/hive-log4j.properties
OK
stu.id stu.name stu.age
1 john 24
Time taken: 6.21 seconds, Fetched: 1 row(s)
1、在ruoze.log中写入如下这句话:
[hadoop@hadoop001 data]$ cat ruoze.log
select * from stu;
2、使用hive -f运行:
[hadoop@hadoop001 data]$ hive -f ruoze.log
which: no hbase in (/home/hadoop/app/hive/bin:/home/hadoop/app/hadoop/bin:/home/hadoop/app/hadoop/sbin:/usr/java/jdk1.8.0_45/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/hadoop/bin)
20/03/28 00:17:36 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Logging initialized using configuration in file:/home/hadoop/app/hive-1.1.0-cdh5.16.2/conf/hive-log4j.properties
OK
stu.id stu.name stu.age
1 john 24
Time taken: 5.523 seconds, Fetched: 1 row(s)
Hive中的表(stu)必须要归属于某个数据库(default)
数据库Database下面包含了0到N张表,每个db对应HDFS上的一个文件夹;
1、官方提供的语法:
CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name
[COMMENT database_comment]
[LOCATION hdfs_path]
[WITH DBPROPERTIES (property_name=property_value, ...)];
2、小括号()有竖线是二选一,中括号[]是可有可无;测试使用如下语句创建数据库:
create database ruozedata_hive;
3、数据库创建好后去hdfs目录上查询目录,发现目录的命名就是:数据库名字加上后缀db
[hadoop@hadoop001 data]$ hdfs dfs -ls /user/hive/warehouse/
20/03/28 00:37:04 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Found 2 items
drwx------ - hadoop supergroup 0 2020-03-28 00:36 /user/hive/warehouse/ruozedata_hive.db
drwx------ - hadoop supergroup 0 2020-03-27 23:36 /user/hive/warehouse/stu
4、建议创建数据库的时候加上if not exists;
hive (default)> create database ruozedata_hive;
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Database ruozedata_hive already exists
hive (default)> create database IF NOT EXISTS ruozedata_hive;
OK
Time taken: 0.014 seconds
2、创建数据库的时候不使用默认/user/hive/warehosue目录,而是自己指定目录:
3、自己指定目录和使用默认存储目录查看的区别:
1、ruozedata_hive2是自己指定的目录,这个库是看不见的
hive (ruozedata_hive2)> desc database ruozedata_hive2;
OK
db_name comment location owner_name owner_type parameters
ruozedata_hive2 hdfs://hadoop001:9000/wordcount hadoop USER
Time taken: 0.019 seconds, Fetched: 1 row(s)
2、ruozedata_hive3是使用的默认目录:
hive (ruozedata_hive2)> desc database ruozedata_hive3;
OK
db_name comment location owner_name owner_type parameters
ruozedata_hive3 hdfs://hadoop001:9000/user/hive/warehouse/ruozedata_hive3.db hadoop USER
Time taken: 0.017 seconds, Fetched: 1 row(s)
4、创建ruozedata_hive3的时候增加属性:
hive (ruozedata_hive2)> create database if not exists ruozedata_hive3 COMMENT 'this is your first created database' WITH DBPROPERTIES('creator'='pk','date'='2020-03-29');
OK
Time taken: 0.049 seconds
hive (ruozedata_hive2)> desc database ruozedata_hive3;
OK
db_name comment location owner_name owner_type parameters
ruozedata_hive3 this is your first created database hdfs://hadoop001:9000/user/hive/warehouse/ruozedata_hive3.db hadoop USER
Time taken: 0.056 seconds, Fetched: 1 row(s)
ALTER (DATABASE|SCHEMA) database_name SET DBPROPERTIES (property_name=property_value, ...); -- (Note: SCHEMA added in Hive 0.14.0)
ALTER (DATABASE|SCHEMA) database_name SET OWNER [USER|ROLE] user_or_role; -- (Note: Hive 0.13.0 and later; SCHEMA added in Hive 0.14.0)
ALTER (DATABASE|SCHEMA) database_name SET LOCATION hdfs_path; -- (Note: Hive 2.2.1, 2.4.0 and later)
1、在ruozedata_hive3数据库下创建测试表test
hive (ruozedata_hive2)> use ruozedata_hive3;
OK
Time taken: 0.012 seconds
hive (ruozedata_hive3)> create table test(id int,name string);
OK
Time taken: 0.16 seconds
hive (ruozedata_hive3)> show tables;
OK
tab_name
test
Time taken: 0.026 seconds, Fetched: 1 row(s)
2、此时ruozedata_hive3数据库下存在数据表test,我们使用drop删除,提示数据库下存在表就无法删除:
hive (ruozedata_hive3)> drop database if exists ruozedata_hive3;
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. InvalidOperationException(message:Database ruozedata_hive3 is not empty. One or more tables exist.)
3、直接加上cascade,就是级联删除,直接删除数据库下的所有表:
hive (ruozedata_hive3)> drop database if exists ruozedata_hive3 cascade;
OK
Time taken: 1.783 seconds
CASCADE:1 db to many table
数据类型:
对于HDFS上的文件来说:string类型
数据类型官网页面:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types
1、对于数值类型来讲:int、bigint、float、double、银行项目精度要求较高的会使用decimal
2、布尔类型boolean:true/false --> PK生产上把布尔类型替换成了TINYINT
3、字符串类型:string 生产上至少90%都用这个
4、日期类型:date、timestamp… -->也可以用string类型来替换
分割符:
delimiter | code | description |
---|---|---|
^A | \001 | 字段和字段之间的分割符 |
\n | \n | 行与行之间的分割符 |
^B | \002 | ARRAY/STRUCT(Hive中的复杂数据类型) |
^C | \003 | key/value of MAP (Hive中的复杂数据类型) |
我们可以自己定义分割符,但是分割符别与字段内容相重合
1,pk,30
1$$$pk$$$30
1、create table stu2(id int, name string, age int) row format delimited fields terminated by ',';
2、暂时不用load data的方式,采用insert插入的方式:
insert into stu2 values(1,'john','24');
3、查询数据是否写进去了:
hive (ruozedata_hive)> select * from stu2;
OK
stu2.id stu2.name stu2.age
1 john 24
Time taken: 0.065 seconds, Fetched: 1 row(s)
4、直接查看hdfs目录上的文件内容是不是以逗号分割:
hive (ruozedata_hive)> dfs -ls /user/hive/warehouse/ruozedata_hive.db/stu2;
Found 1 items
-rwxrwxrwx 1 hadoop supergroup 10 2020-03-28 14:47 /user/hive/warehouse/ruozedata_hive.db/stu2/000000_0
hive (ruozedata_hive)> dfs -cat /user/hive/warehouse/ruozedata_hive.db/stu2/000000_0;
1,john,24
1、把这张表的数据下载到data目录下:
[hadoop@hadoop001 data]$ hdfs dfs -get /user/hive/warehouse/ruozedata_hive.db/stu2/000000_0 ./
20/03/28 14:52:36 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
[hadoop@hadoop001 data]$ ll
total 44
-rw-r--r-- 1 hadoop hadoop 10 Mar 28 14:52 000000_0
-rw------- 1 hadoop hadoop 32768 Mar 26 13:39 15074
-rw-r--r-- 1 hadoop hadoop 14 Mar 28 14:11 ruoze.log
-rw-rw-r-- 1 hadoop hadoop 35 Mar 24 23:23 wordcount.log
2、使用cat查看一下内容:
[hadoop@hadoop001 data]$ cat 000000_0
1,john,24
1、hive是否支持insert,是从哪个版本中出现的
2、HiveQL和SQL的关系?请你说说你对Hive的理解?