Hive主要介绍

Hive介绍

hive是基于 Hadoop平台操作 HDFS 文件的插件工具

   可以将结构化的数据文件映射为一张数据库表

   可以将 HQL 语句转换为 MapReduce 程序

1.hive 是由驱动器组成,驱动器主要由4个组件组成(解析器、编译器、优化器、执行器)
2.hive本身不存储数据,数据是存储在hdfs上
3.hive的元数据默认是存储在detby数据库中,但是它支持一个客户端进行连接,为了支持多客户端连接,可将元数据存储在关系型数据库中(如mysql)
4.hive本身不参与数据计算,数据计算交由计算引擎,hive支持的计算引擎由3种(MapReduce默认、Tez、Spark )


Hive的数据都是存储在 hdfs 上的,默认有一个根目录。由文件 hive-site.xml 中的参数是hive.metastore.warehouse.dir指定。默认为 /user/hive/warehouse

比如名为itcast的数据库存储路径为:/user/hive/warehouse/itcast.db


表所对应的数据是存储 在HDFS上的,而表相关的元数据是存储在关系型数据库中
hive有两种类型的表:内部表(默认表)和外部表

 1.内部表:在创建表的时候没有设置external关键字,则创建的是一张内部表
           表结构中:table_type:managed_table
           特点:在删除表的时候,不光删除表结构,会同步将hdfs上对应的文件夹一起删除。
           使用场景:由于内部表在删除表的时候会将数据文件同步删除,所以在实际的工作中,一些核心表是不会采用内部表,
             如果要临时保存一些数据,或者是一些临时的计算结果则可以使用内部表   
    2.外部表:在创建表的时候指定了external关键字,则创建的属于一张外部表
           表结构中:table_type:external_table
           特点:在删除表的时候,只删除表结构,不会删除hdfs上对应的文件夹
           使用场景:在实际的工作中,绝大部分的表都会采用的是外部表。

修改外部表emp为内部表(emp为表名)
alter table emp set tblproperties ('EXTERNAL'='FALSE');
修改内部表emp为外部表
alter table emp set tblproperties ('EXTERNAL'='TRUE');

内部表和外部表之间允许相互转换
        语法:alter table 表名 set tblproperties('EXTERNAL'='FALSE|TRUE')
              EXTERNAL=FALSE:代表设置为内部表
              EXTERNAL=TRUE:代表设置为外部表
     如果要删除外部表的数据文件方式:
      1.先将表结构转换成内部表,然后删除内部表
      2.先删除表结构,然后使用hdfs的命令来删除:hdfs dfs -rm -r 文件地址      

分区
分区是hive的一种优化手段。分区是指根据表的字段(例如“日期day”)将表划分为不同分区
一个分区表示一个文件夹

分区:将一个大的文件夹进行拆分

分桶:将一个大的文件进行分桶

hive 静态分区

静态分区指的是分区字段值在加载数据时,是由用户手动指定的

创建分区表

(1)关键语句:partitioned by (field string)

(2)分区字段不能是表中已经存在的字段
(3)分区字段是虚拟字段,其数据并不存储在底层的文件中
(4)分区不同,对应数据存放的文件夹不同
    静态分区:手工分区,分区的名称和分区额数据都是用户来直接添加,并且一次只能向一个分区中添加数据。
      添加数据的方式:
      1.load data [local] inpath '文件地址' into table 表名 partition(分区列名=值)
      --静态分区数据加载
      load data local inpath '/root/EMP.txt' into table emp_partition partition (deptno=20);
      2.insert into|overwrite table 表名 partition(分区列名=值) select 列名,列名,....from 表;
      如果是静态分区加载数据,使用insert into则查询出来的数据中不能包含分区列的值。

~单分区查询

select * from emp_partition where dept=20;

~多分区查询

select * from emp_partition where dept=20unionselect * from emp_partition where dept=30
增加分区

alter table emp_partitionadd  partition(dept=40);

hive msck 修复分区
dfs -mkdir -p /user/hive/warehouse/emp_partition/dept=50;

1.上传数据到分区

dfs -put /opt/modules/input/emp.txt  /user/hive/warehouse/emp_partition/dept=50;

2.查询数据

select * from emp_partition where dept=50;

3.修复关系:

msck repair table emp_partition;
 

删除分区数据

-- 这将删除该分区的数据和元数据
alter table emp_partition drop  partition(dept=50);

  • 删除多个分区

alter table dept_partition drop partition ( month = '2021-02-11' ), partition(month = '2021-02-12');

alter table dept_partition drop partition ( month <= '2021-02-12' );

重命名分区表名

-- dept_partition 旧表名 ---> dept_partition2 是新表名
alter table emp_partition rename to emp_partition2;

更改分区文件存储格式

alter table table_name partition (dt='2008-08-09') set fileformat file_format;
 

更改分区位置

alter table table_name partition (dt='2008-08-09') set location "new location";
 

hive 动态分区

动态分区指的是分区的字段值是基于查询结果自动推断出来的。要借助核心语法(insert+select)

开启动态分区功能(默认 true,开启)

hive (default)> set hive.exec.dynamic.partition=true;

设置为非严格模式

  1. 动态分区的模式,默认 strict,表示必须指定至少一个分区为静态分区
  2. nonstrict 模式表示允许所有的分区字段都可以使用动态分区

hive (default)>set hive.exec.dynamic.partition.mode=nonstrict;

1.创建分区表

create table dept_par
(deptno string, -- 部门编号dname  string -- 部门名
)partitioned by (change_dt string)  -- 部门改头换面日期row format delimited fields terminated by '\t';

2、从 表dept 中查询数据,动态插入到 表dept_par 的不同分区中

insert into table dept_par partition (change_dt)
select deptno ,dname  ,change_dt 
from dept;

① 从表dept 中查询出 列deptno,列dname 中的数据,然后插入到 表dept_par 中
② 再从 表dept 中 查询出 列change_dt,让这一列作为 表dept_par 的分区字段

Hive 分桶

分桶表 分区表 区别与联系

 分区针对的是数据的存储路径(分区是根据表的某一列得到的,分区不同,HDFS上的文件夹不同);分桶针对的是数据文件(分桶是根据表的某一列下数据值,经hash取余得到的)

 分区字段不能是表中已经存在的字段;分桶的字段必须是表中已经存在的字段

 2者都是hive的一种优化手段,为了提高查询效率

 设置分桶
create [external] table 表名(列名,......)partitioned by (....)clustered by (分桶列) into n buckets......

注意:1.分桶的列是从表中的列中选出来一个作为分桶列,不需要单独定义。
          2.n代表数字,表示要分的桶的数量
          3.在加载数据的时候如果没有设置reduce的数量则默认reduce的数量就和桶的数量是一致的。
          4.如果处理数据的时候没有设置reduce的数量,默认1个reduce,但是如果reduce处理的数据量超过1G,则系统会启动新的reduce
            如果设置了reduce的数量,则处理数据的reduce就是设置的数量

分桶建议:1.选择分桶列的时候尽量选择关联的列进行分桶,这样可以提高表的关联效率。
              2.选择桶的数量的时候尽量使用质数,这样可以减少数据倾斜的发生。
              3.尽量在大文件中进行分桶。
              4.分桶列尽量选择一些重复率比较低的列,可以减少数据与倾斜。
  分桶规则:先将分桶的列的值计算hash值,然后使用改hash值对桶的数量进行取余,余数就是对应的数据所在的桶的位置,0代表第一桶。

分桶表的优点
  1. 基于分桶字段查询时,减少全表扫描

  2. JOIN时可以提高MR程序效率,减少笛卡尔积数量

分桶抽样

抽样:从所有的样本中抽取一部分的数据作为样本来进行进行数据分析和调试。。
    注意:1.抽样可以在任何表中进行,不限制于分桶表。
          2.分桶抽样其实就是在查询数据的时候对数据按照指定的列,进行逻辑分桶,不受原来表中是否分桶限制,可以重新设置分桶的列以及分桶的数量
    抽样的语法:
    select * from 表 tablesample(bucket n out of m [on 分桶列]);    
    n:代表获取的第几桶数据
    m:代表桶的数量
    on用来设置分桶抽样的时候分桶列,如果在一个分桶表上进行抽样,则可以将on省略,默认使用分桶表的分桶列,
    如果在一个没有分桶的表上进行分桶抽样,则on是不能省略。

OLTP 和 OLAP 的区别

OLTP(on-line transaction processing):联机事务处理

OLAP(On-Line Analytical Processing):联机分析处理

OLTPOLAP
主要应用数据库数据仓库
业务目的侧重于业务处理,如订单、支付等业务侧重于数据分析
主要功能CRUD查询
响应速度实时响应对时间要求不严格
数据库设计遵循3NF遵循星型模式/雪花模型

hive和mysql主要区别

mysqlhive
业务目的侧重于业务处理,如订单、支付等侧重于数据分析
主要功能CRUD查询
响应速度实时响应对时间要求不严格
数据库设计遵循3NF遵循星型模式/雪花模型
处理数据规模

hive 和 hbase 的区别

hive 和 hbase 在大数据架构中处在不同位置,hive 主要解决数据处理和计算问题hbase 主要解决实时数据查询问题,一般是配合使用

hive sql 和spark sql 的区别

(1)mr是基于磁盘的进行计算的,计算过程会有shuffle
(2)sql语句的解析、编译、优化、及数据的计算都由hive自身来完成

(1)spark是基于内存进行计算的
(2)sql的解析、编译、优化交由hive来处理,数据的计算却使用的是spark的rdd

sql语句的解析、编译、优化、及数据的计算都由spark自身来完成,但数据计算却不是rdd了,而是使用的是spark帮我们优化好的api( DataFrame 和 DataSet),这个api底层调用的也是rdd,但是给我spark给们进行了系统优化,开发人员直接使用api就行了

hive 运行日志 数据仓库 数据仓库显示 配置

1.hive 修改 log 存储位置

重命名hive-3.1.2/conf目录下的hive-log4j.properties.template文件名称为 hive-log4j.properties

mv hive-log4j.properties.template    hive-log4j.properties

2.修改log存放位置

vim hive-log4j.properties
#向其中hive.log.dir后添加你的hive所在的路径
property.hive.log.dir = /root/bigdata/hive-3.1.2/logs
 

hive 数据仓库的位置配置

hive 数据仓库的原始位置是在hdfs上的:/user/hive/warehouse路径下

编辑conf目录下的hive-site.xml

<property>
    <name>hive.metastore.warehouse.dir</name>
    <value>/user/hive/warehouse</value>
    <description>location of default database for the warehouse</description>
</property>
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>
 

配置元数据库

1.hive内置的元数据库:Derby数据库

内嵌模式是hive metastore的默认部署模式。此种模式下,元数据存储在内置的Derby数据库,并且Derby数据库和metastore服务都嵌入在主hiveserver2进程中,即当启动hiveserver2进程时,Derby和metastore服务都会启动。缺点是一次只能支持一个客户端连接

本地模式

hive metastore服务随主hiveserver2而启动,并且运行在同一进程当中,但是存储元数据的数据库在单独的进程中运行,并且可以在单独的主机上,metastore服务将通过JDBC与元数据库进行通信
存储元数据的数据库推荐使用MySQL
hive根据hive.metastore.uris 参数值来判断,如果为空,则为本地模式
缺点是每启动一次hiveserver2,都会启动一个metastore服务

远程模式

1.远程模式下,Metastore服务在其自己的单独JVM上运行,而不随hiveserver2启动而启动,需要单独手动启动metastore服务。如果其他进程希望与Metastore服务进行通信,就需要使用Thrift Network API进行通信
2.在生产环境中,建议用远程模式来配置Hive Metastore。在这种情况下,其他依赖hive的软件都可以通过Metastore访问hive。由于还可以完全屏蔽数据库层,因此这也带来了更好的可管理性/安全性
3.远程模式下,需要配置hive.metastore.uris 参数来指定metastore服务运行的机器ip和端口

Hive复杂数据格式

hive \001格式数据 这种格式是hive默认的格式,不用指定任何的分割符

hive 多字节分隔符

  1. 情况一:每一行数据的分隔符是多字节分隔符,例如:”||”、“–”等

2.情况二:数据的字段中包含了分隔符

RegexSerDe正则加载(推荐)

面对情况一和情况二的问题,Hive中提供了一种特殊的方式来解决,Hive提供了一种特殊的Serde来加载特殊数据的问题,使用正则匹配来加载数据,匹配每一列的数据

>>>Hive中默认提供了多种SerDe用于解析和加载不同类型的数据文件,常用的有ORCSerde 、RegexSerde、JsonSerDe等

分析数据,写正则表达式

 原始数据格式
01||周杰伦||中国||台湾||男||七里香
 写正则表达式
([0-9]*)\\|\\|(.*)\\|\\|(.*)\\|\\|(.*)\\|\\|(.*)\\|\\|(.*)
搜索一个在线网站,看看是否匹配

hive json格式数据

{"device":"device_30","deviceType":"kafka","signal":98.0,"time":1616817201390}
{"device":"device_32","deviceType":"kafka","signal":65.0,"time":1616817207131}
{"device":"device_32","deviceType":"kafka","signal":95.0,"time":1616817207714}
{"device":"device_71","deviceType":"bigdata","signal":45.0,"time":1616817207907}

create table tb_json_test2 (
   device string,
   deviceType string,
   signal double,
   `time` string
 )
ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' -- 指定使用专门解析json的类JsonSerDe
STORED AS TEXTFILE;
复杂json建表(array、struct)

{"common": {"ar": "230000","ba": "iPhone","ch": "Appstore","is_new": "1","md": "iPhone 8","mid": "YXfhjAYH6As2z9Iq","os": "iOS 13.2.9","uid": "485","vc": "v2.1.134"},"actions": [{"action_id": "favor_add","item": "3","item_type": "sku_id","ts": 1585744376605}],"displays": [{"displayType": "query","item": "3","item_type": "sku_id","order": 1,"pos_id": 2},{"displayType": "query ","item": "6","item_type": "sku_id","order": 5,"pos_id": 1}],"page": {"during_time": 7648,"item": "3","item_type": "sku_id","last_page_id": "login","page_id": "good_detail","sourceType": "promotion"},"err": {"error_code": "1234","msg": "***********"},"ts": 1585744374423
}
create external table ods_log_inc
(`common`   struct<ar :string,ba :string,ch :string,is_new :string,md :string,mid :string,os :string,uid :string,vc:string> comment '公共信息',`page`     struct<during_time :string,item :string,item_type :string,last_page_id :string,page_id:string,source_type :string> comment '页面信息',`actions`  array<struct<action_id:string,item:string,item_type:string,ts:bigint>> comment '动作信息',`displays` array<struct<display_type :string,item :string,item_type :string,`order` :string,pos_id:string>> comment '曝光信息',`err`      struct<error_code:bigint,msg:string> comment '错误信息',`ts`       bigint comment '时间戳'
) comment '活动信息表'row format serde 'org.apache.hadoop.hive.serde2.jsonserde';

hive 事务表

Hive事务表的局限性

  1. 默认情况下事务配置为关闭。需要配置参数开启使用
  2. 仅支持ORC文件格式(STORED AS ORC)
  3. 表必须是分桶表(Bucketed)才可以使用事务功能
  4. 表参数transactional必须为true
  5. 外部表无法创建事务表

1.开启事务配置

set hive.support.concurrency = true; --Hive是否支持并发
set hive.enforce.bucketing = true; -- 是否开启分桶功能 从Hive2.0开始不再需要 
set hive.exec.dynamic.partition.mode = nonstrict; --动态分区模式  非严格
set hive.txn.manager = org.apache.hadoop.hive.ql.lockmgr.DbTxnManager; -- 事务管理类
set hive.compactor.initiator.on = true; --是否在Metastore实例上运行启动线程和清理线程
set hive.compactor.worker.threads = 1; --在此metastore实例上运行多少个压缩程序工作线程

2.创建Hive事务表

create table trans_student(id int,name String,age int
)clustered by (id) into 2 buckets stored as orc TBLPROPERTIES('transactional'='true');

Hive 拉链表

1.什么是拉链表

保存表中的所有的数据的历史变化状态,记录数据从开始到当前的所有状态变化的信息

2.拉链表特殊的两个列

生效时间:该数据添加或者是修改的时间
失效时间:该条数据过期的时间,一般如果没有失效使用9999-12-31表示,如果失效了泽一般设置的时间就是抽取时间-1天

使用场景:表中数据量过大,部分字段发生变化 ,变化频率不高

3.闭链和开链

闭链:拉链表中某一个数据发生变化,修改这条数据的失效时间为抽取的前天

开链:修改表中的数据或是新增的数据,作为数据的最新状态;

4.拉链表实现

Oracle中:

1.先增量抽取数据。
 2.将抽取到的数据和拉链表中现有的数据进行匹配(merge into),找到能够匹配到的并且是最新的那一条数据,进行闭链操作(修改失效时间)。

3.将抽取过来的数据直接追加到拉链表中,进行开链操作(insert into)。

--编写存储过程来实现拉链表
                CREATE  OR REPLACE PROCEDURE pro_increment_his(work_date VARCHAR2)
                IS
                BEGIN
                  --闭链操作
                  MERGE INTO user_t_his t USING (SELECT * FROM user_t WHERE to_char(last_date,'yyyy-mm-dd')=work_date)s
                  ON(t.id=s.id)
                  WHEN MATCHED THEN
                    --修改失效时间
                    UPDATE SET end_date=to_date(work_date,'yyyy-mm-dd')-1 WHERE t.end_date=to_date('9999-12-31','yyyy-mm-dd');
                  
                  --开链
                  INSERT INTO user_t_his
                  SELECT t.*,
                  to_date(work_date,'yyyy-mm-dd'),
                  to_date('9999-12-31','yyyy-mm-dd') 
                  FROM user_t t WHERE to_char(last_date,'yyyy-mm-dd')=work_date;
                END;

1.查询所有的最新的数据
            select * from 拉链表 where 失效时间=‘9999-12-31’;

 2.查询某一个时间节点的切片数据
            select * from 拉链表 where 生效时间<=时间节点  and 失效时间>=时间节点

Hive中:

在hive中构建拉链表使用左连接来完成拉链表的闭链操作,然后在使用union all完成开链操作,最后将处理的结果使用
insert overwrite将原来拉链表的数据进行覆盖操作

拉链表语法结构:

insert overwrite table 临时拉链表
select  a.*,'抽取日期','9999-12-31'  from  原表 a where 日期=抽取日期
union all
select   a.列名   .....
   if(b.列名 is not null and a.失效时间='9999-12-31','抽取日期-1',a.失效日期)
 from 拉链表 a left join (select * from 原表 where 日期=抽取日期) b
on a.关联字段=b.关联字段

数据导入hive

1. load data local inpath '本地文件路径' [overwrite] into table 表名;

overwrite:是覆盖文件,没有overwrite是追加新的内容

hive hql查询

hive SQL查询执行顺序

from>on>join>where>Group by>聚合函数(例如分组后统计数量)>select>

Hiving>distinct>order>limit

hive count(*)&count(1)&count(字段名称)的区别

count(*)==count(1)

count(1)统计所有行,包含null
count(字段名称)统计所有行,但不包含该字段下为null的行

hive union&union all 联合查询

--对两表并行查询,删除重复行,同时进行排序
select num,name from student_local
union
select num,name from student_hdfs;
--对两表并行查询,保留重复行,进行排序
select num,name from student_local
union all
select num,name from student_hdfs;

排序

order by
  1. 全局排序,所有数据会进入一个reducetask,容易导致内存溢出
  2. 强烈建议将limit与Order By一起使用。避免数据集行数过大
  3. 当hive.mapred.mode设置为strict严格模式时,使用不带 limit 的Order By时会引发异常
sort by

Sort By 分区排序,数据排序在Reducer前完成,数据随机被分配到各个分区,如果要指定数据去哪个分区,需要使用Distribute By

Cluster By
  1. 分区升序排序,分区和排序的字段一致(不能自己指定排序规则,例如降序)
  2. 分组的规则为hash散列:hash_func(col_name) % reduce task nums
Distribute By+Sort By

Distribute By+Sort By 类似于Cluster By,不过Distribute By负责分区,Sort By 负责区内排序,分区字段和排序字段可以不同

Distribute By:类似MR中partition,进行分区,分区规则:hash散列
Hive要求DISTRIBUTE BY语句要写在SORT BY语句之前
如果DISTRIBUTE BY +SORT BY的字段一样,并且升序排序,可以得出下列结论:
CLUSTER BY=DISTRIBUTE BY +SORT BY(字段一样)

hive 连接

1.内连接:和oracle中的内连接一样,但是hive中默认是不支持笛卡尔积和不等值连接,
    如果要进行不等值连接,则必须要设置模式为:nonstrict
    --设置非严格模式
    set hive.mapred.mode=nostrict;

   2.左半开连接:left semi join
     由于早期的hive中不支持in和exists子查询,所以使用左半开连接来实现子查询的功能。
     语法:select * from 表 a left semi join 表 b on a.列=b.列;
     
     执行结果:只返回左表总符合关联条件的数据,并不会返回右表的数据。
    

Hive 中行列转换

行转列

方式一 : 通过 GROUP BY  + CASE WHEN + 聚合函数
create table if not exists stu(uid int,cname string,score int
);insert into stu values (1,'语文',98);
insert into stu values (1,'数学',78);
insert into stu values (1,'英语',88);
insert into stu values (2,'语文',67);
insert into stu values (2,'数学',87);
insert into stu values (2,'英语',79);
insert into stu values (3,'语文',69);
insert into stu values (3,'数学',92);
insert into stu values (3,'英语',91);
insert into stu values (4,'语文',100);Select * from stu;-- 方式一 : 通过 GROUP BY  + CASE WHEN + 聚合函数
select uid,sum(case when cname='语文' then score else 0 end) chinese,sum(case when cname='数学' then score else 0 end) math,sum(case when cname='英语' then score else 0 end) English
from stu group by uid;
方式二: 通过 GROUP BY  + CONCAT_WS + COLLECT_LIST
CREATE TABLE IF NOT EXISTS user_order (uid BIGINT,order_id BIGINT
);insert into  user_order values (1,112);
insert into  user_order values (1,113);
insert into  user_order values (2,114);
insert into  user_order values (2,155);
insert into  user_order values (3,11);
-- 方式二: 通过 GROUP BY + CONCAT_WS + COLLECT_LIST
-- 不去重 列表形式
select uid,collect_list(order_id) from user_order group by uid;
-- 去重:
select uid,collect_set(order_id) from user_order group by uid;
SELECTuid,CONCAT_WS(',', COLLECT_LIST(order_str)) AS order_list
FROM
(SELECT uid , CAST(order_id AS STRING) AS order_strFROM user_order
) tmp
GROUP BY uid
;


列转行

方式一 :采用 UNION ALL 的方式
CREATE TABLE IF NOT EXISTS explode_laterview_org(day1_num BIGINT,day2_num BIGINT,day3_num BIGINT,day4_num BIGINT,day5_num BIGINT,day6_num BIGINT,day7_num BIGINT,campaign_name STRING,campaign_id BIGINT
);INSERT OVERWRITE TABLE explode_laterview_org VALUES
(40, 20, 10, 4, 4, 2, 1, 'zoo', 2 )
,(100, 80, 53, 40, 7, 6, 5, 'moji', 3)
;
select * from explode_laterview_org;select campaign_id,campaign_name,'day1_num' type ,day1_num  num from explode_laterview_org
union all
select campaign_id,campaign_name,'day2_num' type ,day2_num  num from explode_laterview_org
union all
select campaign_id,campaign_name,'day3_num' type ,day3_num  num from explode_laterview_org
union all
select campaign_id,campaign_name,'day4_num' type ,day4_num  num from explode_laterview_org
union all
select campaign_id,campaign_name,'day5_num' type ,day5_num  num from explode_laterview_org
union all
select campaign_id,campaign_name,'day6_num' type ,day6_num  num from explode_laterview_org
union all
select campaign_id,campaign_name,'day7_num' type ,day7_num  num from explode_laterview_org
order by campaign_id;
方式二:使用lateral view和str_to_map

SELECTcampaign_id, campaign_name, type, num
FROM explode_laterview_org
LATERAL VIEWEXPLODE(STR_TO_MAP(CONCAT('day1_num=',CAST (day1_num AS STRING),'&day2_num=',CAST (day2_num AS STRING),'&day3_num=',CAST (day3_num AS STRING),'&day4_num=',CAST (day4_num AS STRING),'&day5_num=',CAST (day5_num AS STRING),'&day6_num=',CAST (day6_num AS STRING),'&day7_num=',CAST (day7_num AS STRING)),'&', '=')) lateral_table AS type, num
;

Hive 优化

表设计

hive 数据存储格式

hive支持的数据存储格式有TextFile(默认) SequenceFile  Parquet   ORC,但是尽量使用Parquet和ORC文件存储格式

  1. TextFile和 SequenceFile 的存储格式都是基于行存储的
  2. ORC 和 Parquet 是基于列式存储的
  3. Hive行式存储和列式存储的优缺点

(1)行式存储:

优点:数据被保存在一起了,insert和update更加容易
缺点:如果查询只涉及某几个列,它会把整行数据都读取出来,不能跳过不必要的列读取

(2)列式存储:

优点:最大的优势是查询时可以快速跳过没有涉及到的列,从而避免全表扫描;支持编码压缩;谓词下推、映射下推
缺点:insert/update会比较麻烦并且不适合扫描小量的数据

  • Parquet&ORC
  1. 均为二进制列式存储,均有行组、列块的概念(二进制列式存储,可以快速跳过没有涉及到的列,从而避免全表扫描)
  2. 均支持基本数据类型、复杂数据类型(复杂数据类型不等同嵌套数据类型)
  3. 均支持压缩
  4. 均支持谓词下推、映射下推

选择parquet原因:

  1. 支持嵌套数据类型(eg:json字符串),ORC不支持。 虽然ORC不支持嵌套数据类型(eg:json字符串),但可以通过复杂数据类型(eg:array和struct)把嵌套类型给表达出来
  2. Parquet 存储格式对Spark非常友好

选择ORC原因:

(1)比Parquet 的压缩效率高(eg:snappy)
(2)ORC存储格式对hive非常友好

(3)支持事务ACID(支持事务的表必须为分桶表)

(4)支持不同的索引索引机制(意味着orc查询速度快)

ORC为我们提供了两种索引机制:Row Group Index(行组索引) 和 Bloom Filter Index(布隆过滤器)

Row Group Index(行组索引)
在stripe(行组)记录了每个字段的最大最小值,当查询中有<,>,=的操作时,会根据最大最小值,跳过扫描不包含的stripes

Bloom Filter Index(布隆过滤器)
判读数据在不在,当它说一个值不存在的时候,一定不存在,当它说一个值存在的时候,可能存在

数据压缩

在数据规模很大和工作负载密集的情况下,采用数据压缩对磁盘I/O操作、网络数据传输有极大的帮助

hive 中的压缩就是使用了hadoop中的压缩实现的,所以hadoop中支持的压缩在hive 中都可以直接使用

hadoop中支持的压缩算法:

压缩方式选择时重点考虑:解压缩速度、压缩率、压缩后是否可以支持切片

压缩格式是否支持切片解压缩速度压缩率
snappyno最快很差
lzoyes很快很高
bzip2yes最慢最高
gzipno一般很高

lzo压缩算法的缺点需要手动为文件创建索引,没有索引不支持文件切片

所有压缩算法的缺点加重CPU负荷,算法越复杂,解压时间越长

设置map后输出压缩
1.开启hive中间传输数据压缩功能
set hive.exec.compress.intermediate=true;2.开启mapreduce中map输出压缩功能
set mapreduce.map.output.compress=true;3.设置mapreduce中map输出数据的压缩方式
set mapreduce.map.outout.compress.codec=
org.apache.hadoop.io.compress.SnappyCodec
org.apache.hadoop.io.compress.GzipCodec 
org.apache.hadoop.io.compress.BZip2Codec 
org.apache.hadoop.io.compress.Lz4Codec
设置reduce后输出压缩
1.开启hive最终输出数据压缩功能
set hive.exec.compress.output=true;2.开启mapreduce最终输出数据压缩
set mapreduce.output.fileoutputformat.compress=true;3.设置mapreduce最终数据输出压缩方式
set mapreduce.output.fileoutputformat.compress.codec =
org.apache.hadoop.io.compress.SnappyCodec
org.apache.hadoop.io.compress.GzipCodec 
org.apache.hadoop.io.compress.BZip2Codec 
org.apache.hadoop.io.compress.Lz4Codec4.设置mapreduce最终数据输出压缩为块压缩
set mapreduce.output.fileoutputformat.compress.type=BLOCK;

mr属性优化

开启本地模式
原因:有时候数据量不大的表用本地计算模式处理,时间会很短,但是默认情况下会将任务提交到集群,等待资源分配,这个过程不仅繁琐,而且更浪费时间

限制条件:如果以下任意一个条件不满足,那么即使开启了本地模式,将依旧会提交给YARN集群运行

1.处理的数据量不超过128M
2.MapTask的个数不超过4个
3.ReduceTask的个数不超过1个

开启JVM重用

原理:JVM指代一个Java进程,假设一个mr程序中有100个MapTask,那么Hadoop默认会为每个MapTask启动一个JVM(共100个),JVM频繁的创建和销毁,会导致内存开销较大,为了解决上述问题,Hadoop中提供了JVM重用机制来,JVM重用机制可以使得一个JVM实例在同一个job中被使用N次(不同mr job中不可以),即当一个MapTask运行结束以后,JVM不会进行释放,而是继续供让一个MapTask使用,直到运行了N个以后,就会释放,N的值可以在Hadoop的mapred-site.xml文件中进行配置,通常在10-20之间,也可以再hive中直接进行设置

使用条件:适用于大量小文件场景,没有大量小文件,就不需要开启。因为开启JVM重用将一直占用使用到的task插槽,以便进行重用,直到任务完成后才能释放

  • 开启Stage的并行执行

Hive会将一个查询解析为多个Stage,即阶段(例如MapReduce阶段、抽样阶段、合并阶段、limit阶段),有时候Stage彼此之间有依赖关系,只能挨个执行,但是在一些别的场景下,很多的Stage之间是没有依赖关系的,例如Union语句,Join语句等等,这些Stage没有依赖关系,但是Hive依旧默认挨个执行每个Stage,这样会导致性能非常差,我们可以通过修改参数,开启并行执行,当多个Stage之间没有依赖关系时,允许多个Stage并行执行,提高性能
 

-- 打开任务并行执行,默认为falseset hive.exec.parallel=true; 
-- 同一个sql允许最大并行度,默认为8 
set hive.exec.parallel.thread.number=16;
开启关联优化

一个Select 语句有Group by 也有 order by 时

Hive会使用两个MapReduce来完成这两个操作,第一个MapReduce做group by,经过shuffle阶段对id做分组,第二个MapReduce对第一个MapReduce的结果做order by,经过shuffle阶段对id进行排序,这样会导致性能相对较差,当我们在Hive中开启关联优化后,可以把分组和排序放在同一个MapReduce中实现

-- 默认false
set hive.optimize.correlation=true;

表之间的Join

Hive实现Join时,为了提高性能,提供了多种Join方案,例如适合小表Join大表的Map Join,大表Join大表的Reduce Join,以及大表Join的优化方案Bucket Join等

  • 如果至少有一个表是小表,则尽量使用Map Join
-- 默认已经开启了Map Join
hive.auto.convert.join=true
-- hive会自动对表数据量进行判读,若到达小表条件,就将小表就加入内存

Hive会自动判断是否满足Map Join,如果不满足Map Join的条件,则自动执行Reduce Join

小表数据首会分发给每个MapTask的内存一份,然后逐次取出大表部分数据和小表进行join,底层不需要经过shuffle

  • 如果2个表都是大表且频繁join,则可以选择Bucket Join
  1. 普通的Bucket Join
  2. 排序的Bucket Join,简称SMB Join(不仅分桶了,而且在桶内进行了排序)

            分桶字段 = Join字段 ,桶的个数相等或者成倍数

-- 开启分桶普通join,默认false
set hive.optimize.bucketmapjoin = true;
-- 开启分桶SMB join
set hive.optimize.bucketmapjoin = true;
-- 默认true
set hive.auto.convert.sortmerge.join=true;
-- 默认false
set hive.optimize.bucketmapjoin.sortedmerge = true;
-- 默认true
set hive.auto.convert.join.noconditionaltask=true;
  • 如果实在没有办法避免大表之间的join,且无法使用Bucket Join,则老老实实的使用 Reduce Join

经shuffle分组后,将key相同的数据分发到同一个reducer,实现大表之间的joinHive会自动判断是否满足Map Join,如果不满足Map Join,则自动执行Reduce Join

SQL语句

使用 from … insert 代替 union all
使用group by 代替 count(distict)

distinct的命令会在内存中构建一个hashtable,查找去重的时间复杂度是O(1),但这个关键字在使用后所有数据只会由一个Reduce Task进行处理,在大数据背景下,可能会导致Reduce Task内存溢出

group by 会分组,然后在分组内排序,如果排序方式为快速排序的话,时间复杂度是比较高O(nlogn),虽然排序花费时间长,但是不会内存溢出;另外(group by)去重会转化为两个任务,会消耗更多的磁盘网络I/O资源

  • 谓词下推

 on 中谓词 where 中谓词,on不仅可以作为连接条件,也可以作为过滤条件

(1)left join:右侧的表过滤条件写在on后面,左侧的表过滤条件写在where后面,性能上有提高
(2)join:写在哪里都一样
(3)full join:过滤条件写在 where 后可以谓词下推,写在 on 后不可以谓词下推(默认cbo引擎下)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/317412.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

访问jwt生成token404解决方法

背景&#xff1a; 1.在部署新的阿里云环境后发现调用jwt生成token的方法404&#xff0c;前端除了404&#xff0c;台不报任何错误 在本地好用&#xff0c;在老的阿里云环境好用&#xff0c; 2.缩短生成私钥的参数报错&#xff0c;以为私钥太长改了tomcat参数也无效&#xff0…

《MySQL对库的基本操作》

文章目录 一、查看数据库列表查看数据库中的所有表想知道当前处于哪个数据库里 二、创建一个数据库三、删除一个数据库知道两个集1.字符集2.校验集修改数据库的字符集和编码集 不同的校验码对数据库的影响四、数据库的备份与恢复注意事项&#xff1a;备份数据库中的表 总结 一、…

算法训练营第十三天 | LeetCode 239 滑动窗口最大值、LeetCode 347 前K个高频元素

LeetCode 239 滑动窗口最大值 本体初始思路是这样的&#xff0c;首先看下给定数组长度和维持一个滑动窗口所需要花费的时间复杂度之间的关系。初步判断是还行的&#xff0c;当然后面被样例打脸了。需要更新成优先队列的解法。原本的解法能通过37/51和46/51的测试用例。但这还不…

【Kotlin】Channel简介

1 前言 Channel 是一个并发安全的阻塞队列&#xff0c;可以通过 send 函数往队列中塞入数据&#xff0c;通过 receive 函数从队列中取出数据。 当队列被塞满时&#xff0c;send 函数将被挂起&#xff0c;直到队列有空闲缓存&#xff1b;当队列空闲时&#xff0c;receive 函数将…

python可视化学习笔记折线图问题-起始点问题

问题描述&#xff1a; 起始点的位置不对 from pyecharts.charts import Line import pyecharts.options as opts # 示例数据 x_data [1,2,3,4,5] y_data [1, 2, 3, 4, 5] # 创建 Line 图表 line Line() line.add_xaxis(x_data) line.add_yaxis("test", y_data) li…

基于Hyperf的CMS,企业官网通用php-swoole后台管理系统

2023年9月11日10:47:00 仓库地址&#xff1a; https://gitee.com/open-php/zx-hyperf-cms CMS&#xff0c;企业官网通用PHP后台管理系统 框架介绍 hyperf SCUI 后端开发组件 php 8.1 hyperf 3.1 数据库 sql(使用最新日期文件) hyperf\doc\sql_bak mysql 8. 系统默认账号…

STM32 F103C8T6学习笔记17:类IIC通信—MLX90614红外非接触温度计

今日学习配置MLX90614红外非接触温度计 与 STM32 F103C8T6 单片机的通信 文章提供测试代码讲解、完整工程下载、测试效果图 本文需要用到的大概基础知识&#xff1a;1.3寸OLED配置通信显示、IIC通信、 定时器配置使用 这里就只贴出我的 OLED驱动方面的网址链接了&#xff1a…

ChatGPT4.0知识问答、DALL-E生成AI图片、Code Copilot辅助编程,打开新世界的大门

目录 1、DALL-E 文字转图片 在线AI修改2、Write For Me3、Code Copilot 目前最强的AI编程大模型4、Diagrams: Show Me5、Instant Website [Multipage] 网站合成神器6、AskYourPDF Research Assistant 无限PDF7、Diagrams & Data: Research, Analyze, Visualize 精读Excel …

TCP/IP和HTTP协议

TCP/IP OSI 七层模型在提出时的出发点是基于标准化的考虑&#xff0c;而没有考虑到具体的市场需求&#xff0c;使得该模型结构复杂&#xff0c;部分功能冗余&#xff0c;因而完全实现 OSI 参考模型的系统不多。而 TCP/IP 参考模型直接面向市场需求&#xff0c;实现起来也比较…

LeetCode 543.二叉树的直径

题目描述 给你一棵二叉树的根节点&#xff0c;返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。 示例 1&#xff1a; 输入&#xff1a;root [1,2,3,4,5]…

报错“Install Js dependencies failed”【鸿蒙开发Bug已解决】

文章目录 项目场景:问题描述原因分析:解决方案:此Bug解决方案总结Bug解决方案寄语项目场景: 最近也是遇到了这个问题,看到网上也有人在询问这个问题,本文总结了自己和其他人的解决经验,解决了【报错“Install Js dependencies failed”】的问题。 报错如下 问题描述 …

【高质量】2024五一数学建模C题保奖思路+代码(后续会更新)

你的点赞收藏是我后续更新的最大动力&#xff01; 一定要点击文末的卡片&#xff0c;那是获取资料的入口&#xff01; 你是否在寻找数学建模比赛的突破点&#xff1f; 作为经验丰富的数学建模团队&#xff0c;我们将为你带来2024 年五一数学建模&#xff08;C题&#xff09;…

复旦微JFM7VX690计算后IO接口模块,用于雷达信号处理、数据处理等需要高速密集计算的应用场景

计算后IO接口模块 1 介绍 1.1 产品概述 计算后IO接口模块主要由复旦微JFM7VX690型FPGA、国产以太网收发器YT8521、国产BMC芯片GD32F450、国产CPLD芯片EF2L45BG256B、国产内存颗粒等主要芯片组成&#xff0c;采用标准6U VPX尺寸设计。 本计算后IO接口模块主要用于雷达信号处…

Nginx负载均衡主备模式

1. 背景 使用Nginx代理后端服务&#xff0c;有时候某些服务是不能使用多台负载均衡&#xff0c;但又想保障高可用&#xff0c;所以采用主备模式&#xff0c;记录如下&#xff1a; 2. 参考 nginx 负载均衡Nginx-负载均衡-后端状态max_conns、down、backup、max_fails、fail_t…

【webrtc】MessageHandler 1: 基于线程的消息处理:以10毫秒处理音频为例

基于m98 G:\CDN\rtcCli\m98\src\audio\null_audio_poller.h分发的消息由MessageHandler 类通过其抽象接口OnMessage 实现处理 NullAudioPoller NullAudioPoller 是一个处理audio的消息的分发器 poll 启动:

2024深圳杯数学建模竞赛A题(东三省数学建模竞赛A题):建立火箭残骸音爆多源定位模型

更新完整代码和成品完整论文 《2024深圳杯&东三省数学建模思路代码成品论文》↓↓↓&#xff08;浏览器打开&#xff09; https://www.yuque.com/u42168770/qv6z0d/zx70edxvbv7rheu7?singleDoc# 2024深圳杯数学建模竞赛A题&#xff08;东三省数学建模竞赛A题&#xff0…

【Go 语言入门专栏】Go 语言的起源与发展

前言 Go 语言是当下最为流行的编程语言之一&#xff0c;大约在 2020、2021 年左右开始于国内盛行&#xff0c;许多大厂很早就将部分 Java 项目迁移到了 Go&#xff0c;足可看出其在性能方面的优越性。 相信各位都知道&#xff0c;在爬虫业务中&#xff0c;并发是一个关键的需…

解决iview(view ui)中tabs组件中使用图片预览组件ImagePreview,图片不显示问题

同学们可以私信我加入学习群&#xff01; 正文开始 前言一、问题描述二、原因分析三、解决方案总结 前言 最近在写个人项目的web端和浏览器插件&#xff0c;其中一个功能是base64和图片的转换。因为分成四个小功能&#xff0c;所以使用的iview的tabs来展示不同功能&#xff0c…

如何解决DA14531编译工程出现大量报错的问题

在编译DA14531某个工程时&#xff0c;在这台电脑可以编译&#xff0c;另外一台电脑就编译不过&#xff0c;出现很多错误问题。那要怎样处理呢&#xff1f; 建议安装新MDK版本 可能是MDK版本问题&#xff0c;在不同的电脑安装不同的MDK版本&#xff0c;用新的版本可以编译通过&…

计算机网络—数据链路层

一、数据链路层的基本概念 结点&#xff1a;主机、路由器 链路&#xff1a;网络中两个结点之间的物理通道&#xff0c;链路的传输介质主要有双绞线、光纤和微波。分为有线链路、无线链路 数据链路&#xff1a;网络中两个结点之间的逻辑通道&#xff0c;把实现控制数据协议的…