Hive

Hive概念

  • Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类SQL查询功能
  • 本质上:将 HQL 转化成 MapReduce 程序

Hive的优缺点

优点

  1. 操作接口采用类 SQL 语法,提供快速开发的能力(简单、容易上手)
  2. 避免写 MapReduce,减少开发人员的学习成本
  3. Hive的执行延迟比较高,因此 Hive 常用于数据分析,对实时性要求不高的场合
  4. Hive优势在于处理大数据,对于处理小数据没有优势,因为Hive的执行延迟比较高
  5. Hive支持用户自定义函数,用户可以根据自己的需求来实现自己的函数

缺点

  1. Hive的HQL`表达能力有限
    1. 迭代式算法无法表达
    2. 数据挖掘方面不擅长,由于MapReduce数据处理流程的限制,效率更高的算法却无法实现
  2. Hive的效率比较低
    1. Hive自动生成的MapReduce作业,通常情况下不够智能化
    2. Hive调优比较困难,

HIVE架构原理

  1. 用户接口:Client
  2. 元数据:Metastore
    • 元数据包括:表名、表所属的数据库、表的拥有者、列/分区字段、表的类型(是否是外部表)、表的数据所在目录等
    • 默认存储在自带的derby 数据库中,推荐使用MySQL存储Metasore
  3. Hadoop
    • 使用HDFS进行存储,使用MapReduce进行计算
  4. 驱动器:Driver
    1. 解析器(SQL Parser):将sql字符串转换成抽象语法树AST,这一步一般都用第三方工具完成,比如antir:对AST进行语法分析,比如表是否存在、字段是否存在、SQL语义是否有误
    2. 编译器(Physical Plan):将AST编译生成逻辑执行计划
    3. 优化器(Query Opimizer):对逻辑执行计划进行优化
    4. 执行器(Execution):把逻辑执行计划转换成可以运行的物理计划,对于Hive来说,就是MR/Spark
  • Hive通过给用户提供的一系列交互接口,接收到用户的指令(SQL),使用自己的Driver,结合元数据(MetaStore),将这些指令翻译成MapReduce,提交到Hadoop中执行,最后,将执行返回的结果输出到用户交互接口

Hive安装

Hive安装地址

  1. Hive官网地址
    • http://hive.apache.org/
  2. 文档查看地址
    • https://cwiki.apache.org/confluence/display/Hive/GettingStarted
  3. 下载地址
    • http://archive.apache.org/dist/hive/
  4. github地址
    • https://github.com/apache/hive

Hive安装部署

  1. apache-hive-3.1.3-bin.tar.gz上传到Linux/opt/software目录下

  2. 解压apache-hive-3.1.3-bin.tar.gz/opt/module/目录下面

  3. 修改apache-hive-3.1.3-bin.tar.gz的名称为hive

  4. 修改/etc/profile.d/my_env.sh,添加环境变量

    sudo vim /etc/profile.d/my_env.sh
    
    #HIVE_HOME
    export HIVE_HOME=/opt/module/hive
    export PATH=$PATH:$HIVE_HOME/bin
    
  5. 初始化元数据库(默认是derby数据库)

    bin/schematool -dbType derby -initSchema
    
  • tips
    • Hive 默认使用 Hadoop 的配置文件来连接到 HDFS。Hadoop 的配置文件通常位于 $HADOOP_HOME/etc/hadoop 目录下,其中包括 core-site.xmlhdfs-site.xml 文件。这些文件中定义了 Hadoop 集群的相关配置,包括 NameNode 的地址和端口号。
    • 如果您在安装 Hive 时指定了 Hadoop 的安装目录,那么 Hive 会自动读取 Hadoop 的配置文件来连接到 HDFS。
    • 如果您没有指定 Hadoop 的安装目录,那么 Hive 会在默认的位置查找 Hadoop 的配置文件。
    • 如果您的 Hadoop 配置文件不在默认位置,那么您需要在 Hive 的配置文件中指定 Hadoop 配置文件的位置。
  1. 启动Hive

    bin/hive
    
  2. 另一个会话启动hive,产生报错

    • 原因是Hive默认使用的元数据库作为derby,开启Hive之后就会占用源数据库,且不与其他客户端共享数据,所以需要将Hive的元数据地址改为MySQL

MySQL安装

  1. 检查当前系统是否安装过MySQL

    rpm -qa | grep mariadb
    //如果存在,则卸载
    sudo rpm -e --nodeps mariadb-libs
    
  2. 卸载系统自带的mariadb

    sudo rpm -qa | grep mariadb | xargs sudo rpm -e --nodeps
    
  3. MySQL安装包拷贝到/opt/software目录

  4. 解压MySQL安装包

tar -xf mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar -C mysql_lib/
  1. 执行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-client-5.7.28-1.el7.x86_64.rpm
sudo rpm -ivh mysql-community-server-5.7.28-1.el7.x86_64.rpm
  1. 初始化
sudo systemctl start mysqld
  1. 启动 MySQL
sudo systemctl start mysqld
  1. 查看MySQL密码
sudo cat /var/log/mysqld.log | grep password
  1. 用刚刚查到的密码进入MySQL(如果报错,给密码加单引号)
mysql -uroot -p'password'
  1. 更改MySQL密码策略
set global validate_password_policy=0;
set global validate_password_length=4;
  1. 设置简单好记的密码
set password=password("123456");
  1. 进入MySQL
use mysql
  1. 修改user表,把Host表内容修改为%
update user set host="%" where user="root";

配置Hive元数据存储到MySQL

  1. 新建Hive元数据库
mysql -uroot -p123456

create database metastore;
quit;
  1. MySQLJDBC驱动拷贝到Hivelib目录下
cp /opt/software/mysql-connector-java-5.1.37.jar $HIVE_HOME/lib
  1. $HIVE_HOME/conf目录下新建hive-site.xml文件
vim $HIVE_HOME/conf/hive-site.xml
  1. 添加如下内容
<configuration>
    <!-- jdbc连接的URL -->
    <property>
        <name>javax.jdo.option.ConnectionURL</name>
        <value>jdbc:mysql://hadoop102: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>
</configuration>

  1. 初始化Hive元数据库(修改为采用MySQL存储元数据)
bin/schematool -dbType mysql -initSchema -verbose

查看MySQL中的元数据

  1. 查看元数据库中存储的库信息
select * from DBS;
  1. 查看元数据库中存储的表信息
select * from TBLS;
  1. 查看元数据库中存储的表中列相关信息
select * from COLUMNS_V2;
  1. 查看元数据中 主键相关信息
select * from KEY_CONSTRAINTS
  1. 有关 hive的元数据信息可以查官网

Hive服务部署

hiveserver2服务

  • Hive的hiveserver2服务的作用是提供jdbc/odbc接口,为用户提供远程访问Hive数据的功能

  • 用户说明

    • 在远程访问Hive数据时,客户端并未直接访问Hadoop集群,而是由Hivesever2代理访问。由Hiveserver2的hive.server2.enable.doAs参数决定,该参数的含义是是否启用Hiveserver2用户模拟的功能。若启用,则Hiveserver2会模拟成客户端的登录用户去访问Hadoop集群的数据,不启用,则Hivesever2会直接使用启动用户访问Hadoop集群数据。模拟用户的功能,默认是开启的。
  • hiveserver2部署

    1. Hadoop端配置

      • hivesever2的模拟用户功能,依赖于Hadoop提供的proxy user(代理用户功能),只有Hadoop中的代理用户才能模拟其他用户的身份访问Hadoop集群。因此,需要将hiveserver2的启动用户设置为Hadoop的代理用户,配置方式如下:
      1. 修改配置文件core-site.xml
      cd $HADOOP_HOME/etc/hadoop
      vim core-site.xml
      
      1. 增加如下配置
      <!--配置所有节点的atguigu用户都可作为代理用户-->
      <property>
          <name>hadoop.proxyuser.atguigu.hosts</name>
          <value>*</value>
      </property>
      
      <!--配置atguigu用户能够代理的用户组为任意组-->
      <property>
          <name>hadoop.proxyuser.atguigu.groups</name>
          <value>*</value>
      </property>
      
      <!--配置atguigu用户能够代理的用户为任意用户-->
      <property>
          <name>hadoop.proxyuser.atguigu.users</name>
          <value>*</value>
      </property>
      
      
      1. Hive端配置,在hive-site.xml文件中添加如下配置信息
      <!-- 指定hiveserver2连接的host -->
      <property>
      	<name>hive.server2.thrift.bind.host</name>
      	<value>hadoop102</value>
      </property>
      
      <!-- 指定hiveserver2连接的端口号 -->
      <property>
      	<name>hive.server2.thrift.port</name>
      	<value>10000</value>
      </property>
      
      1. 启动hiveserver2
      nohup bin/hive --service hiveserver2 &
      
      1. 启动beeline客户端
      bin/beeline -u jdbc:hive2://hadoop102:10000 -n atguigu
      

metastore服务

  • Hive的``metastore服务的作用是为Hive CLI或者Hiveserver2`提供元数据访问接口。
  1. metastore运行模式

    • metastore有两种运行模式,分别为嵌入式模式和独立服务模式
    1. 嵌入式模式::在内嵌模式下,Metastore 服务运行在 HiveServer2 进程中。客户端可以直接连接到 HiveServer2 来访问和管理元数据。这种模式适用于小型集群和测试环境。
    2. 独立服务模式:在远程模式下,Metastore 服务运行在独立的进程中。客户端需要连接到 Metastore 服务所在的主机和端口来访问和管理元数据。这种模式适用于大型集群和生产环境。
  2. 配置嵌入式模式

        <!-- jdbc连接的URL -->
        <property>
            <name>javax.jdo.option.ConnectionURL</name>
            <value>jdbc:mysql://hadoop102: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>
    
    
  3. 独立服务模式

    <!-- jdbc连接的URL -->
     <property>
         <name>javax.jdo.option.ConnectionURL</name>
         <value>jdbc:mysql://hadoop102: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>
    
     <!-- 指定metastore服务的地址 -->
    <property>
    	<name>hive.metastore.uris</name>
    	<value>thrift://hadoop102:9083</value>
    </property>
    
    1. 启动metastore
    hive --service metastore
    
    1. 启动hiveserver2
    hive --service hiveserver2
    

编写 Hive启动脚本

#!/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 &"
    [ -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
  • tips
    • netstat -nltp
      • netstat:用于在 Linux 系统中显示网络连接、路由表和网络接口信息
        • -n:表示以数字形式显示地址和端口号,而不是使用主机名和服务名
        • -l:表示仅显示监听套接字
        • -t:选项表示仅显示 TCP 连接
        • -p:表示显示每个套接字所属的进程 ID 和名称
    • function check_process()方法:该函数接受两个参数,第一个参数是程序名字,第二个参数是监听的端口号。返回程序的pid,同时返回状态代码:0是执行成功,1是不成功。用于判断程序状态有没有异常

hiveserver2常用交互命令

beeline -u jdbc:hive2://hadoop102:10000 -n atguigu --help

Hive常见属性配置

  1. Hive客户端显示当前库和表头,修改``hive-site.xml`
<!--Hive客户端显示当前库和表头,hive-site.xml-->
<property>
    <name>hive.cli.print.header</name>
    <value>true</value>
    <description>Whether to print the names of the columns in query output.</description>
</property>
<property>
    <name>hive.cli.print.current.db</name>
    <value>true</value>
    <description>Whether to include the current database in the Hive prompt.</description>
</property>
  1. Hive的``log默认存放路径,修改hive-log4j2.properties`
property.hive.log.dir = ${sys:java.io.tmpdir}/${sys:user.name}
property.hive.log.file = hive.log
  1. Hive的``JVM`堆内存设置
    • 新版本的Hive启动的时候,默认申请的JVM堆内存大小为256MJVM堆内存申请的太小,导致后期开启本地模式,执行复杂的SQL时经常会报错:java.lang.OutOfMemoryError: Java heap space,因此最好提前调整一下HADOOP_HEAPSIZE这个参数。
export HADOOP_HEAPSIZE=2048

DDL(Data Definition Language)数据定义

数据库

建表语法

CREATE DATABASE [IF NOT EXISTS] database_name
[COMMENT database_comment]
[LOCATION hdfs_path]
[WITH DBPROPERTIES (property_name=property_value, ...)];

查询数据库

DESCRIBE DATABASE [EXTENDED] db_name;

修改数据库

--修改dbproperties
ALTER DATABASE database_name SET DBPROPERTIES (property_name=property_value, ...);

--修改location
ALTER DATABASE database_name SET LOCATION hdfs_path;

--修改owner user
ALTER DATABASE database_name SET OWNER USER user_name;

删除数据库

DROP DATABASE [IF EXISTS] database_name [RESTRICT|CASCADE];

RESTRICT:严格模式,若数据库不为空,则会删除失败,默认为该模式。
CASCADE:级联模式,若数据库不为空,则会将库中的表一并删除。

切换当前数据库

USE database_name;

表(table

创建表

CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name   
[(col_name data_type [COMMENT col_comment], ...)]
[COMMENT table_comment]
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]
[CLUSTERED BY (col_name, col_name, ...) 
[SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]
[ROW FORMAT row_format] 
[STORED AS file_format]
[LOCATION hdfs_path]
[TBLPROPERTIES (property_name=property_value, ...)]
  • 关键字说明

    1. TEMPORARY
      • 临时表,该表只在当前会话可见,会话结束,表会被删除。
    2. EXTERNAL(重点)
      • 外部表,与之相对应的是内部表(管理表)。管理表意味着Hive会完全接管该表,包括元数据和HDFS中的数据。而外部表则意味着Hive只接管元数据,而不完全接管HDFS中的数据。

data_type(重点)

Hive说明定义
tinyint1byte有符号整数
smallint2byte有符号整数
int4byte有符号整数
bigint8byte有符号整数
boolean布尔类型,true或者false
float单精度浮点数
double双精度浮点数
decimal十进制精准数字类型decimal(16,2)
varchar字符序列,需指定最大长度,最大长度的范围是[1,65535]varchar(32)
string字符串,无需指定最大长度
timestamp时间类型
binary二进制数据
类型说明定义取值
array数组是一组相同类型的值的集合arrayarr[0]
mapmap是一组相同类型的键-值对集合map<string, int>map['key']
struct结构体由多个属性组成,每个属性都有自己的属性名和数据类型struct<id:int, name:string>struct.id
  • 类型转换

    1. 隐式转换

      • 任何整数类型都可以隐式地转换为一个范围更广的类型
      • 所有整数类型、float和string类型都可以隐式地转换成double
      • tinyintsmallintint都可以转换为float
      • boolean类型不可以转换为任何其它的类型
    2. 显示转换

      • 借助cast函数完成显示的类型转换
    3. PARTITIONED BY

      • 创建分区表
    4. CLUSTERED BY ... SORTED BY...INTO ... BUCKETS

      • 创建分桶表
    5. ROW FORMAT(重点)

      • 指定SERDE,SERDE是Serializer and Deserializer的简写。Hive使用SERDE序列化和反序列化每行数据。
      ROW FORAMT DELIMITED 
      [FIELDS TERMINATED BY char] 
      [COLLECTION ITEMS TERMINATED BY char] 
      [MAP KEYS TERMINATED BY char] 
      [LINES TERMINATED BY char] 
      [NULL DEFINED AS char]
      
      • fields terminated by :列分隔符

      • collection items terminated bymapstructarray中每个元素之间的分隔符

      • collection items terminated bymapstructarray中每个元素之间的分隔符

      • lines terminated by :行分隔符

      • SERDE关键字可用于指定其他内置的SERDE或者用户自定义的SERDE。例如JSON SERDE,可用于处理JSON字符串

        ROW FORMAT SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value,property_name=property_value, ...)] 
        
      • STORED AS(重点)

        • 指定文件格式,常用的文件格式有,textfile(默认值),sequence file,orc file、parquet file等等。
      • TBLPROPERTIES

        • 用于配置表的一些KV键值对参数
      • Create Table As SelectCTAS)建表

        • 该语法允许用户利用select查询语句返回的结果,直接建表,表的结构和查询语句的结构保持一致,且保证包含select查询语句放回的内容。不包含分区表
      • Create Table Like语法

        • 该语法允许用户复刻一张已经存在的表结构,与上述的CTAS语法不同,该语法创建出来的表中不包含数据。

查看表

  • 展示所有表
SHOW TABLES [IN database_name] LIKE ['identifier_with_wildcards'];
  • 查看表信息
DESCRIBE [EXTENDED | FORMATTED] [db_name.]table_name

修改表

  • 重命名表
ALTER TABLE table_name RENAME TO new_table_name
  • 增加列
ALTER TABLE table_name ADD COLUMNS (col_name data_type [COMMENT col_comment], ...)
  • 更新列
ALTER TABLE table_name CHANGE [COLUMN] col_old_name col_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]
  • 替换列
ALTER TABLE table_name REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...)

删除表

DROP TABLE [IF EXISTS] table_name;

清空表

TRUNCATE [TABLE] table_name
  • 注意:truncate只能清空管理表,不能删除外部表中数据。

DML(Data Manipulation Language)数据操作

Load

  • Load语句可将文件导入到Hive表中。
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)];
  • 关键字说明:
    1. local:表示从本地加载数据到Hive表;否则从HDFS加载数据到Hive表。
    2. overwrite:表示覆盖表中已有数据,否则表示追加。
    3. partition:表示上传到指定分区,若目标是分区表,需指定分区。

Insert

INSERT (INTO | OVERWRITE) TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement;
  • 关键字说明:
    1. INTO:将结果追加到目标表
    2. OVERWRITE:用结果覆盖原有数据

将查询结果写入目标路径

INSERT OVERWRITE [LOCAL] DIRECTORY directory
  [ROW FORMAT row_format] [STORED AS file_format] select_statement;

Export&Import

  • Export导出语句可将表的数据和元数据信息一并到处的HDFS路径,Import可将Export导出的内容导入Hive,表的数据和元数据信息都会恢复。Export和Import可用于两个Hive实例之间的数据迁移。