Hive的基本概念
HIve简介
- Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类SQL的查询功能
Hive本质
- 将HQL转化成MapReduce程序
- Hive处理的数据存储在HDFS
- Hive分析数据底层的实现是MapReduce
- 执行程序运行在Yarn上
Hive的优缺点
优点
- 采用类SQL语法,简单
- 避免了去写MapReduce
- 支持用户自定义函数
缺点
- 执行延迟比较高,常用于对实时性要求不高的场合如数据分析
- 优势在于处理大数据,对处理小数据没有优势
- 无法表达迭代式算法
- 不擅长数据挖掘。由于MapReduce数据处理流程的限制,效率更高的算法却无法实现
- Hive自动生成的MapReduce作业,通常情况下不够智能化
- Hive调优比较困难,粒度比较粗
Hive架构原理
- Metastore元数据
- 包括表名、表所属的数据库(默认是default)、表的拥有者、列/分区字段、表的类型(是否是外部表)、表的数据所在的目录等
- 解析器
- 将SQL字符串转换成抽象语法树AST,对AST进行语法分析,比如表是否存在,字段是存在,SQL语义是否有错误
- 编译器
- 将AST编译生成逻辑执行计划
- 优化器
- 对逻辑执行计划进行优化
Hive和数据库的比较
数据更新
- Hive是针对数据仓库应用设计的,读多写少
- 因此中不建议对数据的改写,所有数据都是在加载的时候确定好的
Hive安装
安装MySQL
# 检测是否安装过MySQL,如果有则卸载
rpm -qa|grep mariadb
sudo rpm -e --nodeps mariadb-libs
# 解压安装包
tar -xf mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar
# 在安装目录下执行rpm安装,注意按顺序执行
sudo rpm -ivh mysql-community-common-5.7.28-1.el7.x86_64.rpm
sudo rpm -ivh mysql-community-libs-5.7.28-1.el7.x86_64.rpm
sudo rpm -ivh mysql-community-libs-compat-5.7.28-1.el7.x86_64.rpm
sudo rpm -ivh mysql-community-client-5.7.28-1.el7.x86_64.rpm
sudo rpm -ivh mysql-community-server-5.7.28-1.el7.x86_64.rpm
# 如果Linux是最小化安装的,可能会出现错误,需要安装缺少的依赖然后重新安装 mysql-community-server-5.7.28-1.el7.x86_64
yum install -y libaio
#删除/etc/my.cnf文件中datadir指向的目录下的所有内容
# 查看datadir的值
[mysqld]
datadir=/var/lib/mysql
# 删除/var/lib/mysql目录下的所有内容
cd /var/lib/mysql
sudo rm -rf ./*
# 初始化数据库
sudo mysqld --initialize --user=mysql
# 查看临时生成的root用户的密码
cat /var/log/mysqld.log
# 启动mysql服务
sudo systemctl start mysqld
# 登录mysql数据库
mysql -uroot -p
# 修改root用户的密码
set password = password("123456");
# 修改mysql库下的user表中的root用户允许任意ip连接
update mysql.user set host='%' where user='root';
flush privileges;
Hive安装部署
# 解压
tar -zxvf /opt/software/apache-hive-3.1.2-bin.tar.gz -C /opt/module/
# 添加环境变量
sudo vim /etc/profile.d/my_env.sh
#HIVE_HOME
HIVE_HOME=/opt/module/hive-3.1.2
PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$HIVE_HOME/bin
export PATH JAVA_HOME HADOOP_HOME HIVE_HOME
# 解决日志Jar包冲突
mv $HIVE_HOME/lib/log4j-slf4j-impl-2.10.0.jar $HIVE_HOME/lib/log4j-slf4j-impl-2.10.0.bak
Hive元数据配置到Mysql
# 拷贝驱动
cp /opt/software/mysql-connector-java-5.1.37.jar $HIVE_HOME/lib
# 配置Metastore到Mysql
vim $HIVE_HOME/conf/hive-site.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!-- jdbc连接的URL -->
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://node01:3306/metastore?useSSL=false</value>
</property>
<!-- jdbc连接的Driver-->
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<!-- jdbc连接的username-->
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<!-- jdbc连接的password -->
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>123456</value>
</property>
<!-- Hive默认在HDFS的工作目录 -->
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
</property>
<!-- Hive元数据存储的验证 -->
<property>
<name>hive.metastore.schema.verification</name>
<value>false</value>
</property>
<!-- 元数据存储授权 -->
<property>
<name>hive.metastore.event.db.notification.api.auth</name>
<value>false</value>
</property>
<!-- 指定存储元数据要连接的地址 -->
<property>
<name>hive.metastore.uris</name>
<value>thrift://node01:9083</value>
</property>
<!-- 指定hiveserver2连接的host -->
<property>
<name>hive.server2.thrift.bind.host</name>
<value>node01</value>
</property>
<!-- 指定hiveserver2连接的端口号 -->
<property>
<name>hive.server2.thrift.port</name>
<value>10000</value>
</property>
<!-- hadoop高可用时要加入下面的配置 -->
<property>
<name>hive.server2.active.passive.ha.enable</name>
<value>true</value>
</property>
</configuration>
Hive的基本使用
初始化元数据库
# 登录Mysql
mysql -uroot -p123456
# 新建元数据库
create database metastore;
quit;
# 初始化Hive元数据库
schematool -dbType mysql -initSchema
启动Hive
先启动Hadoop集群
启动Hive
bin/hive
使用Hive
show databases; show tables; create table test (id int); insert into test values(1); select * from test;
使用元数据服务的方式访问Hive
# 启动Metastore hive --service metastore # 启动后窗口不能再操作,需要打开一个新的shell窗口 # 启动Hive bin/hive
使用JDBC方式访问Hive
# 启动hiveserver2 bin/hive --service hiveserver2 # 启动beeline客户端j bin/beeline -u jdbc:hive2://node01:10000 -n lixuan
编写hiveserver2启动脚本hiveservices.sh
#!/bin/bash HIVE_LOG_DIR=$HIVE_HOME/logs if [ ! -d $HIVE_LOG_DIR ] then mkdir -p $HIVE_LOG_DIR fi #检查进程是否运行正常,参数1为进程名,参数2为进程端口 function check_process() { pid=$(ps -ef 2>/dev/null | grep -v grep | grep -i $1 | awk '{print $2}') ppid=$(netstat -nltp 2>/dev/null | grep $2 | awk '{print $7}' | cut -d '/' -f 1) echo $pid [[ "$pid" =~ "$ppid" ]] && [ "$ppid" ] && return 0 || return 1 } function hive_start() { metapid=$(check_process HiveMetastore 9083) cmd="nohup hive --service metastore >$HIVE_LOG_DIR/metastore.log 2>&1 &" cmd=$cmd" sleep 4; hdfs dfsadmin -safemode wait >/dev/null 2>&1" [ -z "$metapid" ] && eval $cmd || echo "Metastroe服务已启动" server2pid=$(check_process HiveServer2 10000) cmd="nohup hive --service hiveserver2 >$HIVE_LOG_DIR/hiveServer2.log 2>&1 &" [ -z "$server2pid" ] && eval $cmd || echo "HiveServer2服务已启动" } function hive_stop() { metapid=$(check_process HiveMetastore 9083) [ "$metapid" ] && kill $metapid || echo "Metastore服务未启动" server2pid=$(check_process HiveServer2 10000) [ "$server2pid" ] && kill $server2pid || echo "HiveServer2服务未启动" } case $1 in "start") hive_start ;; "stop") hive_stop ;; "restart") hive_stop sleep 2 hive_start ;; "status") check_process HiveMetastore 9083 >/dev/null && echo "Metastore服务运行正常" || echo "Metastore服务运行异常" check_process HiveServer2 10000 >/dev/null && echo "HiveServer2服务运行正常" || echo "HiveServer2服务运行异常" ;; *) echo Invalid Args! echo 'Usage: '$(basename $0)' start|stop|restart|status' ;; esac
添加执行权限
chmod u+x hiveservices.sh
启动Hive后台服务
hiveservices.sh start
连接Hiveserver2客户端
bin/beeline -u jdbc:hive2://node01:10000 -n lixuan
Hive常用交互命令
-e 不进入hive的交互窗口执行sql语句
bin/hive -e "select id from student;"
-f 执行脚本中sql语句
bin/hive -f /opt/module/hive/datas/hivef.sql
退出窗口
exit; quit;
Hive常见属性配置
打印当前库和表头,
hive-site.xml
中加入如下两个配置<property> <name>hive.cli.print.header</name> <value>true</value> </property> <property> <name>hive.cli.print.current.db</name> <value>true</value> </property>
Hive运行日志信息配置
Hive的log默认存放在
/temp/lixuan/hive.log
目录下修改hive的log存放日志到
/opt/module/hive-3.12/logs
cd /opt/module/hive-3.1.2/conf mv hive-log4j2.properties.template hive-log4j2.properties # 在hive-log4j.properties文件中修改log存放位置 property.hive.log.dir=/opt/module/hive-3.1.2/logs
Hive数据类型
基本数据类型
Hive数据类型 | Java数据类型 | 长度 | 例子 |
---|---|---|---|
TINYINT | byte | 1byte有符号整数 | 20 |
SMALINT | short | 2byte有符号整数 | 20 |
INT | int | 4byte有符号整数 | 20 |
BIGINT | long | 8byte有符号整数 | 20 |
BOOLEAN | boolean | 布尔类型,true或者false | TRUE FALSE |
FLOAT | float | 单精度浮点数 | 3.14159 |
DOUBLE | double | 双精度浮点数 | 3.14159 |
STRING | string | 字符系列。可以指定字符集。可以使用单引号或者双引号。 | ‘now is the time’ “for all good men” |
TIMESTAMP | 时间类型 | ||
BINARY | 字节数组 |
- Hive的String 类型相当于数据库的varchar类型,该类型是一个可变的字符串
集合数据类型
数据类型 | 描述 | 语法示例 |
---|---|---|
STRUCT | 和c语言中的struct类似,都可以通过“点”符号访问元素内容。例如,如果某个列的数据类型是STRUCT{first STRING, last STRING},那么第1个元素可以通过字段.first来引用。 | struct() 例如struct<street:string, city:string> |
MAP | MAP是一组键-值对元组集合,使用数组表示法可以访问数据。例如,如果某个列的数据类型是MAP,其中键->值对是’first’->’John’和’last’->’Doe’,那么可以通过字段名[‘last’]获取最后一个元素 | map() 例如map<string, int> |
ARRAY | 数组是一组具有相同类型和名称的变量的集合。这些变量称为数组的元素,每个数组元素都有一个编号,编号从零开始。例如,数组值为[‘John’, ‘Doe’],那么第2个元素可以通过数组名[1]进行引用。 | Array() 例如array |
案例实操
有如下JOSN个数的数据结构
{ "name": "songsong", "friends": ["bingbing" , "lili"] , //列表Array, "children": { //键值Map, "xiao song": 19 , "xiaoxiao song": 18 } "address": { //结构Struct, "street": "hui long guan" , "city": "beijing" } }
创建本地测试文件test.txt
songsong,bingbing_lili,xiao song:18_xiaoxiao song:19,hui long guan_beijing yangyang,caicai_susu,xiao yang:18_xiaoxiao yang:19,chao yang_beijing
Hive上创建测试表
create table test( name string, friends array<string>, children map<string, int>, address struct<street:string, city:string> ) row format delimited fields terminated by ',' collection items terminated by '_' map keys terminated by ':' lines terminated by '\n';
导入文本数据到测试表
load data local inpath '/opt/module/hive/datas/test.txt' into table test;
访问数据
select friends[1],children['xiao song'],address.city from test where name="songsong";
隐式类型转化
- 任何整数类型都可以隐式地转换为一个范围更广地类型,如TINYINT可以转换成INT,INT可以转换成BIGINT
- 所有整数类型、FLOAT和STRING类型都可以隐式地转换成DOUBLE
- TINYINT、SMALLINT、INT都可以转换为FLOAT
- BOOLEAN类型不可以转换为任何其它的类型
附加:Hive的启动顺序
先启动mysql数据库
sudo systemctl start mysqld
再启动Hadoop集群
然后用脚本启动Metastore和hive2
hiveservices.sh start
最后连接hive2
bin/beeline -u jdbc:hive2://node01:10000 -n lixuan