Hive 总结

Hive

hive.apache.org
Hive由Facebook开源,处理海量结构化数据的统计问题。

每一个框架的诞生都是为了去解决一类问题,没有一个框架能兼容所有场景。

对大数据处理,最后落地最好都是SQL实现,受众所有语言的编程人员。而对MapReduce来说需要开发大量代码,因此诞生了Hive。

对于MR来说,就是用于:批计算、离线计算。 ==> Hive 也是。

基于Hadoop

SQL on Hadoop:以SQL 和方式运行在Hadoop上。

  • SQL
  • UDF
构建在Hadoop之上:
  1. Hive的数据是存在hdfs
  2. Hive作业是以MR的方式运行(也可以Hive on Spark)
  3. Hive作业跑在Yarn上

Hive以类SQL 的语言(Hive QL),可编译为MR作业,提交到Yarn上运行。

  • Hive数据:hdfs
默认会将 hive 数据文件放在hdfs “/user/hive/warehouse/” 下

hdfs://Gargantua:9000/user/hive/warehouse
  • Hive元数据:MySQL
Hive 底层引擎(不止MR):
  1. MR
  2. Tez
  3. Spark

Hive仅仅是个客户端,只负责将SQL作业翻译为对于引擎作业,再提交到Yarn运行。不需要集群。

Hive SQL 如何运行:

由Driver 完成:

  1. SQL 解析
  2. 查询优化
  3. 物理执行计划
  4. UDF
  5. 序列化
  6. 翻译为对于的作业(MR、Tez、Spark SQL)
MetaStore 元数据

Hive 可以将MetaStore 共享给 Spark SQL、Presto、Impala…

元数据:定义数据的数据。就是一种Schema,存放了数据所在的(表、字段、…)
一般将元数据存在在MySQL(内置是存放在Derby,问题很多,测试都别用);
MySQL 也要部署HA,主备。

Hive 与 RDBS:

  1. Hive 也支持事务,但对于离线计算每用,重新跑即可。
  2. Insert、Update 和 Delete 都支持但一般不用。

Hive 部署

https://blog.csdn.net/qq_45494908/article/details/122228034

注意下Hive 与 MySQL 也有版本匹配要求,最低支持MySQL 5.6.17。
整合MySQL的配置文件是在Hive-site.xml。这个文件hive不提供,需要自己在 conf/下添加,driver、url、user、password

[liqiang@Gargantua conf]$ cd /home/liqiang/app/hive/conf
[liqiang@Gargantua conf]$ vi hive-site.xml
	<property>
	    <name>javax.jdo.option.ConnectionDriverName</name>
	    <value>com.mysql.jdbc.Driver</value>
	</property>
	
	 <property>
   	     <name>javax.jdo.option.ConnectionURL</name>
    	 <value>jdbc:mysql://ip:3306/my_hive?createDatabaseIfNotExist=true</value>
 	 </property>

	<property>
	    <name>javax.jdo.option.ConnectionUserName</name>
	    <value>账号</value>
	</property>

	<property>
	    <name>javax.jdo.option.ConnectionPassword</name>
	    <value>密码</value>
	</property>

Hive目录(app/hive/lib/)添加MySQL驱动包:如mysql-connector-java-5.1.49.jar

初始化Hive元数据到MySQL(不是所有版本都需要做)

配置

日志:

关于log4j.propertities,是放在HIVE_HOME/conf:hive-log4j2.properties,其中配置了运行时日志文件存放的目录和文件名hive.log

property.hive.log.dir = ${sys:java.io.tmpdir}/${sys:user.name}
Hive官网关于Hive配置所有信息

在 WiKi -> Home-> User Documentation -> Hive Configuration Properties

关于hive配置的默认值:

// 控制是否打印查询结果头信息 (是否打印表名)
set hive.cli.print.header;  // 查看
set hive.cli.print.header=true;  // 临时设置只作用当前session

// 控制是否打印当前数据库名 hive (default)>
hive.cli.print.current.db

// 数据在hdfs 存放的目录
hive.metastore.warehouse.dir=/user/hive/warehouse
设置配置属性
  1. set临时设置,只作用当前session

    set hive.cli.print.header=true;
    
  2. 启动时设置( --hiveconf ),只作用当前session

    hive --hiveconf hive.cli.print.current.db=false
    
  3. 持久设置:hive-site.xml。

    <property>
        <name>hive.cli.print.header</name>
        <value>true</value>
    </property>
    

    优先级:set 临时的配置是可以改掉 xml的设置(约定大于配置)

启动参数

hive -e 可以直接指定sql,直接在linux而不用进入hive就能运行

hive -e "select * from emp;"

hive -f 可以指定一个sql脚本文件,效果同 hive -e。很常用,可以调度。

hive -f pk.sql
// 执行后会回到linux,不启动hive

hive -i 可以指定一个初始化sql来启动Hive

hive -i <filename>                    Initialization SQL file
// 执行后会启动hive,并留在hive中

Hive的数据组织方式

~~~
database [文件夹]
    table [文件夹]
        partition  [文件夹]
            bucket  桶[文件]
~~~

元数据存哪些内容

在MySQL的如下表名中存放对于的元数据:

    DATANASE_PARAMS:Hive db的信息
    TBLS: Hive表
    DBS: 库
    COLUMNS_V2:字段信息
    ...
修复元数据与数据

如操作不当导致元数据信息被删除,即便hdfs上数据还在,也无法通过Hive SQL 查询出。
修复不一致:

msck repair table table_name;

DDL语句

数据定义语言

在 WiKi -> Home-> User Documentation -> DDL
以下只是最常用语句的总结,其他需求可查看官网

database
    create database my_db;
    // 数据库是在 hdfs : /user/hive/warehouse/my_db
    // default 数据库是直接在 /user/hive/warehouse
    
    // 但也可以指定
    create database my_db location '/user/hive/warehouse/xxx';
    
    // 列出所有库
    show databases;
    
    // 库详细信息 (信息不要轻易改,元数据信息易改漏)
    desc database [extanded] my_db;
    
    // 删除库 (库里无表时才能删)
    drop database [if exists] my_db;
    
    // 进入库
    use my_db;
table
    create table [db_name.]table_name (
        colnum_name data_type,
        ...
    ) 
    ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' /* 不同列之间的分隔符 (必须ROW FORMAT 开头) */
    
    COMMENT /* 表的注释 */
    EXTERNAL /* 是否是外部表,默认true */   
    COLLECTION ITEMS TERMINGATED BY ','  /* 指列类型为集合时,取值时依赖的分隔符 */ 
    
    
    // 增加/修改列
    alter  table_name ADD|REPLACE colnums (colnum_name data_type)
   
内/外部表
  • 内部表managed: (受Hive管控的),对表做drop操纵时,表和表数据一并删除。
  • 外部表external,对表做drop时,只会删除元数据metastore,而表中的数据(存在hdfs上)不会被删除。重新建表仍然可以查原来的数据。多用外部表,防止误操作
  • 内部表、外部表转换:
    alter table emp set tblproperties("EXTERNAL"="true"); // "EXTERNAL"只支持大写

DML语句

从已存在的表复制(备份)

Inserting data into Hive Tables from queries

// 复制结构+数据新表,新表不能事先存在
create table table_name as select ... ==> CTAS  

// 先复制表结构(或本就已存在的表) + insert [overwrite or into]  (列的数量/类型要匹配)
create table table_name like table_name;
INSERT OVERWRITE table table_name select * from table_name; // 覆盖
INSERT INTO table table_name select * from table_name; // 追加

// 还能同时将一个表的数据复制到多个表
FROM from_statement INSERT OVERWRITE TABLE tablename select_statement1 FROM from_statement

Load 导入

Loading files into tables

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
# [LOCAL] // 加LOCAL表示从当前linux机器加载,不加LOCAL则是从hdfs
# [OVERWRITE]  // 覆盖 or 追加数据

数据导出

Writing data into the filesystem from queries

// 将文件写到本地(从hdfs)
INSERT OVERWRITE [LOCAL] DIRECTORY directory1
  [ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' ] 
  SELECT ... FROM ...

// 直接hdfs命令将数据拉下来也是一样的效果
hdfs dfs -get /usr/warehouse/db_name/table_name ~/data/
日志数据 ==> 数据清洗ETL ==> 数据仓库 ==》 各种维度的统计分析(SQL) ==> RDBMS ==> 前端(BI报表等)
RDBMS(sqoop、DataX、Spark) ==> 数据仓库 ==》 各种维度的统计分析(SQL) ==> RDBMS ==> 前端(BI报表等)

数据类型

在 WiKi -> Home-> User Documentation -> Data Types
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types

Hive03

map<string,string>
// create 
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' // 不同列之间的分隔
COLLECTION ITEMS TERMINGATED BY '#'  //  指列类型为集合时,取值时依赖的分隔符。类型为:array<string>、map<string,string>...
MAP KEYS TERMINATED BY ':'  // 指定map类型 key 与 value之间的分隔

// query
select map_keys[colnum] \ members['key']

分区

分区表也是一个表,但是多了一个分区字段。
分区字段对于hdfs上是一个文件夹

// 按天分区
/usr/warehouse/db/table/day=20220401/...
/usr/warehouse/db/table/day=20220402/...

// 对查询来说,也只是一个字段条件 (多级分区就是两个条件and)
select * from table where day=20220401
静态分区
// create 
PARTITIONED BY (col_name data_type, ...)  // 多级分区,用逗号分隔

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

// insert
INSERT INTO TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] ...

静态分区装载数据是需要静态写出分区字段的partcol1=val1,分区较多时不利逐个编写。

动态分区

动态分区不需显示写出分区条件,指定分区字段后去匹配列最后一个字段,执行分区是自动按内容去重分区。(不太适用日期,适用重复性较强的字段)

// creat 
create table [db_name.]table_name PARTITION(colnum_name) (
        ...,
        colnum_name data_type
    ) 

严格模式

严格模式下:

  1. 使用全局排序要求必须加limit
  2. 对分区表查询,必须带分区where条件
// 关闭严格模式
set hive.exec.dynamic.partition.mode=nonstrict;
// 开启
set hive.exec.dynamic.partition.mode=strict;

分桶 bucket

// create   (num_buckets 表示最终桶的个数(文件个数))
CLUSTERED BY (col_name, ...) [SORTED BY (col_name [DESC], ...)] INTO num_buckets BUCKETS

// 是根据分桶字段,用hash运算取模决定存放在哪个桶。(并不是按顺序分桶的)

四个 by

  • group by 分组。一般结合聚合函数一起使用。
  • order by 全局排序。只使用一个reduce必然性能低,在严格模式下会要求全局排序时必须要加limit。
  • sort by 分区排序。只能保证在分区内是有序的,会按rdeuce的个数分区,在一个reduce中排序才能有序,不同reduce不能保证有序。只有一个reduce时分区排==全局排。
    // 修改redeuce个数
    set mapred.reduce.tasks=3;
    
  • distribute by 只负责数据分发。作用类似MR中的partitioner,指定字段作为分区规则,相同的规则进入同一个reduce。结合 sort by使用时,distribute by 和 sort by 可以是不同字段,也可以是相同字段。
  • cluster by 如果 distribute by + sort by是相同字段就可以简写为 cluster by。(不支持手动设置降序)

函数

Operators and User-Defined Functions (UDFs)

在 WiKi -> Home-> User Documentation -> DML(Operators and UDFs)

Build-in

列转行。就是为集合类型的某列数据,查询拆分成多行。
使用split(),拆分成数组后,配合explode栅列函数展开到多行:

	select  name, c
	from teacher_course
	lateral view
	explode(split(course,',')) tmp as c;

行转列。对单个字段内容的行转列,如分组聚合。(多行多列转换?)

collect_list: 配合group by 将多行数据收集为一个数组
concat_ws: 将多个拼接为一个
UDF
  • UDF 一进一出。 如:upper lower substr
  • UDAF 多进一出 。 如:sum …
  • UDTF 一进多出。 如:explode

自定义UDF函数:https://blog.csdn.net/qq_45494908/article/details/122266503

启动Hive

所以命令都在 HIVE_HOME/bin 目录里

  • hive

    就能进入Hive >
    退出:hive> quit;

    // 只启动元数据.默认启动在端口9083。
    hive --service metastore
    hive --service metastore -p 9083
    
    // 不挂断后台启动
    nohup hive --service metastore &
    
  • hiveserver2

    简称HS2,启动后作为服务端,接受客户端(beeline、jdbc) 操作
    在 WiKi -> Home-> User Documentation -> Hice Clients ==> HiveServer2

  • nohup sh hiveserver2 &

    后端启动HS2。不会挂断。(注意不要写成nohub)
    (想退出时exit,再关闭shell。直接关闭shell会一直后台运行)

  • 启动HS2前提下,可以在同目录启动 beeline

    % ./beeline
    
    beeline> !connect jdbc:hive2://localhost:10000 liqiang // 启动不指定则默认端口10000;密码任意敲
    
    // 进入后可以像在hive> 中一样操作库、表
    
  • jdbc 连接

    启动HS2前提下,可在java客户端连接获取hive数据(是能查hdfs数据,不是metastore元数据)

    <dependency>
        <groupId>org.apache.hive</groupId>
        <artifactId>hive-jdbc</artifactId>
        <version>3.1.2</version>
    </dependency>
    

    官方demo

    import java.sql.SQLException;
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.Statement;
    import java.sql.DriverManager;
    /**
    * 从官网https://cwiki.apache.org/confluence/display/Hive/HiveClient#HiveClient-JDBC
    * 
    * HS2 需要保持打开(不指定则默认端口10000)
    *
    * No suitable driver found for jdbc:hive://Gargantua:14000/my_db 改成hive2
    * */
    public class HiveJdbcClient {
     // private static String driverName = "org.apache.hadoop.hive.jdbc.HiveDriver"; // 官网给的有错
     private static String driverName = "org.apache.hive.jdbc.HiveDriver";
    
     public static void main(String[] args) throws SQLException {
       try {
         Class.forName(driverName);
        } catch (ClassNotFoundException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
         System.exit(1);
        }
        Connection con =  DriverManager.getConnection("jdbc:hive2://Gargantua:10000/my_db", "liqiang",  "1"); // 账号为主机名?密码任意
        Statement stmt = con.createStatement();
        String tableName = "emp_hive";
        ResultSet res = stmt.executeQuery("select * from " + tableName);
    
        while (res.next()){
          System.out.println(res.getInt("empno") + "," + res.getString("ename"));
        }
        res.close();
        stmt.close();
        con.close();
      }
    }
    

后台程序

前台程序,直接执行 Ctrl+c 就可以终止了。
后台程序,需要先执行exit,再关闭shell。直接关闭shell会一直后台运行。
前台程序转后台程序:Ctrl + z (转后台后,但是是暂停的,需要借助bg命令)

nohup : no hang up(不挂断) 的缩写。不挂断的运行,免疫session的SIGHUP信号。
& :在后台运行,免疫(Ctrl + C)SIGINT信号。

参考:运行查看和关闭后台程序

执行计划

issues

apache所有顶级项目的issues都在:issues.apache.org ==> JIRA

patch:补丁
Hive的解决了的issues是以patch提交。
其他很多开源项目都以 pull request提交到社区。

执行计划三部分
  • The Abstract Syntax Tree for the query。AST 抽象语法树(执行计划里已移除)。将SQL字符串翻译成AST ==> MR作业
  • The dependencies between the different stages of the plan。MR依赖关系(一条SQL可能有多个MR作业,翻译这个依赖)
  • The description of each of the stages。MR 做了什么
reducejoin 和 mapjoin 的执行计划
hive.auto.convert.join 默认为true,代表会自动根据情况将 reducejoin转成mapjoin。

树状层级,从上往下阅读。开头列出了一共使用到达的 几个tage
每一层级会按执行顺序逐次解读SQL Fetch opertor => filter op => join op => select op

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值