Hive数仓框架详解

news2024/11/27 16:40:33

Hive框架详解

1、Hive的介绍

在这里插入图片描述

​ Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能。

​ 本质是将SQL转换为MapReduce程序。

​ 主要用途:用来做离线数据分析,比直接用MapReduce开发效率更高。

2、Hive的架构

在这里插入图片描述

用户接口:包括 CLI、JDBC/ODBC、WebGUI。其中,CLI(command line interface)为shell命令行;JDBC/ODBC是Hive的JAVA实现,与传统数据库JDBC类似;WebGUI是通过浏览器访问Hive。

元数据存储:通常是存储在关系数据库如 mysql/derby中。Hive 将元数据存储在数据库中。Hive 中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等。

解释器、编译器、优化器、执行器:完成 HQL 查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在 HDFS 中,并在随后有 MapReduce 调用执行。

3、Hive 数据模型

Hive中所有的数据都存储在HDFS中,没有专门的数据存储格式

在创建表时指定数据中的分隔符,Hive 就可以映射成功,解析数据。

Hive中包含以下数据模型

**db:**在hdfs中表现为hive.metastore.warehouse.dir目录下一个文件夹

**table:**在hdfs中表现所属db目录下一个文件夹

**external table:**数据存放位置可以在HDFS任意指定路径

**partition:**在hdfs中表现为table目录下的子目录

**bucket:**在hdfs中表现为同一个表目录下根据hash散列之后的多个文件

4、常用操作

4.1、数据库相关

Hive配置单元包含一个名为 default 默认的数据库.

  • —创建数据库

create database [if not exists] ;

  • –显示所有数据库

show databases;

  • –删除数据库

drop database if exists [restrict|cascade];

​ 默认情况下,hive不允许删除含有表的数据库,要先将数据库中的表清空才能drop,否则会报错
–加入cascade关键字,可以强制删除一个数据库

hive> drop database if exists users cascade;
  • –切换数据库

use ;

4.2、内部表外部表
建内部表
create table 
student(Sno int,Sname string,Sex string,Sage int,Sdept string) 
row format delimited fields terminated by ',';
建外部表
create external table 
student_ext(Sno int,Sname string,Sex string,Sage int,Sdept string) 
row format delimited fields terminated by ',' location '/stu';
内、外部表加载数据:
load data local inpath '/root/hivedata/students.txt' overwrite into table student;

load data inpath '/stu' into table student_ext;
4.3、创建分区表
  • 分区建表分为2种,一种是单分区,也就是说在表文件夹目录下只有一级文件夹目录。另外一种是多分区,表文件夹下出现多文件夹嵌套模式。
  • 单分区建表语句
create table day_table (id int, content string) partitioned by (dt string);
单分区表,按天分区,在表结构中存在id,content,dt三列。
  • 双分区建表语句
create table day_hour_table (id int, content string) partitioned by (dt string, hour string);
双分区表,按天和小时分区,在表结构中新增加了dt和hour两列。
 导入数据
 load data local inpath '/root/hivedata/dat_table.txt' into table day_table partition(dt='2017-07-07');
 
 load data local inpath '/root/hivedata/dat_table.txt' into table day_hour_table partition(dt='2017-07-07', hour='08');
 
 基于分区的查询:

 SELECT day_table.* FROM day_table WHERE day_table.dt = '2017-07-07';

 查看分区
 show partitions day_hour_table;  

总的说来partition就是辅助查询,缩小查询范围,加快数据的检索速度和对数据按照一定的规格和条件进行管理。
  • 指定分隔符

    —指定分隔符创建分区表

    create table day_table (id int, content string) partitioned by (dt string) row format delimited fields terminated by ',';
    

    —复杂类型的数据表指定分隔符

    数据如下

    zhangsan	beijing,shanghai,tianjin,hangzhou
    wangwu	shanghai,chengdu,wuhan,haerbin
    

    建表语句

    create table
    complex_array(name string,work_locations array<string>) 
    row format delimited fields terminated by '\t' 
    collection items terminated by ',';
    
4.4、增删分区
  • 增加分区
alter table t_partition add partition (dt='2008-08-08') location 'hdfs://node-21:9000/t_parti/';

执行添加分区  /t_parti文件夹下的数据不会被移动。并且没有分区目录dt=2008-08-08 
  • 删除分区
alter table t_partition drop partition (dt='2008-08-08');

执行删除分区时/t_parti下的数据会被删除并且连同/t_parti文件夹也会被删除

注意区别于load data时候添加分区:会移动数据 会创建分区目录
4.5、hive中的join
准备数据
1,a
2,b
3,c
4,d
7,y
8,u

2,bb
3,cc
7,yy
9,pp



建表:
create table a(id int,name string)
row format delimited fields terminated by ',';

create table b(id int,name string)
row format delimited fields terminated by ',';

导入数据:
load data local inpath '/root/hivedata/a.txt' into table a;
load data local inpath '/root/hivedata/b.txt' into table b;


实验:
** inner join
select * from a inner join b on a.id=b.id;

+-------+---------+-------+---------+--+
| a.id  | a.name  | b.id  | b.name  |
+-------+---------+-------+---------+--+
| 2     | b       | 2     | bb      |
| 3     | c       | 3     | cc      |
| 7     | y       | 7     | yy      |
+-------+---------+-------+---------+--+





**left join   
select * from a left join b on a.id=b.id;
+-------+---------+-------+---------+--+
| a.id  | a.name  | b.id  | b.name  |
+-------+---------+-------+---------+--+
| 1     | a       | NULL  | NULL    |
| 2     | b       | 2     | bb      |
| 3     | c       | 3     | cc      |
| 4     | d       | NULL  | NULL    |
| 7     | y       | 7     | yy      |
| 8     | u       | NULL  | NULL    |
+-------+---------+-------+---------+--+





**right join
select * from a right join b on a.id=b.id;

select * from b right join a on b.id=a.id;
+-------+---------+-------+---------+--+
| a.id  | a.name  | b.id  | b.name  |
+-------+---------+-------+---------+--+
| 2     | b       | 2     | bb      |
| 3     | c       | 3     | cc      |
| 7     | y       | 7     | yy      |
| NULL  | NULL    | 9     | pp      |
+-------+---------+-------+---------+--+




**
select * from a full outer join b on a.id=b.id;
+-------+---------+-------+---------+--+
| a.id  | a.name  | b.id  | b.name  |
+-------+---------+-------+---------+--+
| 1     | a       | NULL  | NULL    |
| 2     | b       | 2     | bb      |
| 3     | c       | 3     | cc      |
| 4     | d       | NULL  | NULL    |
| 7     | y       | 7     | yy      |
| 8     | u       | NULL  | NULL    |
| NULL  | NULL    | 9     | pp      |
+-------+---------+-------+---------+--+


**hive中的特别join
select * from a left semi join b on a.id = b.id;

select a.* from a inner join b on a.id=b.id;
+-------+---------
| a.id  | a.name  
+-------+---------
| 2     | b       
| 3     | c       
| 7     | y       
+-------+---------
相当于
select a.id,a.name from a where a.id in (select b.id from b); 在hive中效率极低

select a.id,a.name from a join b on (a.id = b.id);

select * from a inner join b on a.id=b.id;


cross join##慎用)
返回两个表的笛卡尔积结果,不需要指定关联键。
select a.*,b.* from a cross join b;
4.6、json解析
1、先加载rating.json文件到hive的一个原始表 rat_json
样例:{"movie":"1193","rate":"5","timeStamp":"978300760","uid":"1"}

create table rat_json(line string) row format delimited;
load data local inpath '/root/hivedata/rating.json' into table rat_json;

2、需要解析json数据成四个字段,插入一张新的表 t_rating
drop table if exists t_rating;
create table t_rating(movieid string,rate int,timestring string,uid string)
row format delimited fields terminated by '\t';

3、json表数据解析到rating表中
insert overwrite table t_rating
select 
get_json_object(line,'$.movie') as moive,
get_json_object(line,'$.rate') as rate,
get_json_object(line,'$.timeStamp') as timestring, get_json_object(line,'$.uid') as uid 
from rat_json limit 10;

5、常用函数

5.1、数值函数
  • 指定精度取整函数 : round

    语法: round(double a, int d)

    返回值: DOUBLE

    说明: 返回指定精度d的double类型

    举例:

    hive> select round(3.1415926,4) from dual;
    
    3.1416
    
  • 向下取整函数 : floor

    语法: floor(double a)

    返回值: BIGINT

    说明: 返回等于或者小于该double变量的最大的整数

    举例:

    hive> select floor(3.1415926) from dual;
    3
    
    hive> select floor(25) from dual;
    25
    
  • 向上取整函数 : ceil

    语法: ceil(double a)

    返回值: BIGINT

    说明: 返回等于或者大于该double变量的最小的整数

    举例:

    hive> select ceil(3.1415926) from dual;
    4
    
    hive> select ceil(46) from dual;
    46
    
  • 取随机数函数 : rand

    语法: rand(),rand(int seed)

    返回值: double

    说明: 返回一个0到1范围内的随机数。如果指定种子seed,则会等到一个稳定的随机数序列

    举例:

    hive> select rand() from dual;
    
    0.5577432776034763
    
  • 绝对值函数 : abs

    语法: abs(double a) abs(int a)

    返回值: double int

    说明: 返回数值a的绝对值

    举例:

    hive> select abs(-3.9) from dual;
    3.9
    
    hive> select abs(10.9) from dual;
    10.9
    
5.2、日期函数
  • to_date(string timestamp):返回时间字符串中的日期部分,
    • 如to_date(‘1970-01-01 00:00:00’)=‘1970-01-01’
  • current_date:返回当前日期
  • year(date):返回日期date的年,类型为int
    • 如year(‘2019-01-01’)=2019
  • month(date):返回日期date的月,类型为int,
    • 如month(‘2019-01-01’)=1
  • day(date): 返回日期date的天,类型为int,
    • 如day(‘2019-01-01’)=1
  • weekofyear(date1):返回日期date1位于该年第几周。
    • 如weekofyear(‘2019-03-06’)=10
  • datediff(date1,date2):返回日期date1与date2相差的天数
    • 如datediff(‘2019-03-06’,‘2019-03-05’)=1
  • date_add(date1,int1):返回日期date1加上int1的日期
    • 如date_add(‘2019-03-06’,1)=‘2019-03-07’
  • date_sub(date1,int1):返回日期date1减去int1的日期
    • 如date_sub(‘2019-03-06’,1)=‘2019-03-05’
  • months_between(date1,date2):返回date1与date2相差月份
    • 如months_between(‘2019-03-06’,‘2019-01-01’)=2
  • add_months(date1,int1):返回date1加上int1个月的日期,int1可为负数
    • 如add_months(‘2019-02-11’,-1)=‘2019-01-11’
  • last_day(date1):返回date1所在月份最后一天
    • 如last_day(‘2019-02-01’)=‘2019-02-28’
  • next_day(date1,day1):返回日期date1的下个星期day1的日期。day1为星期X的英文前两字母
    • 如next_day(‘2019-03-06’,‘MO’) 返回’2019-03-11’
  • **trunc(date1,string1)😗*返回日期最开始年份或月份。string1可为年(YYYY/YY/YEAR)或月(MONTH/MON/MM)。
    • 如trunc(‘2019-03-06’,‘MM’)=‘2019-03-01’,trunc(‘2019-03-06’,‘YYYY’)=‘2019-01-01’
  • unix_timestamp():返回当前时间的unix时间戳,可指定日期格式。
    • 如unix_timestamp(‘2019-03-06’,‘yyyy-mm-dd’)=1546704180
  • from_unixtime():返回unix时间戳的日期,可指定格式。
    • 如select from_unixtime(unix_timestamp(‘2019-03-06’,‘yyyy-mm-dd’),‘yyyymmdd’)=‘20190306’
5.3、条件函数
  • if(boolean,t1,t2):若布尔值成立,则返回t1,反正返回t2。
    • 如if(1>2,100,200)返回200
  • case when boolean then t1 else t2 end:若布尔值成立,则t1,否则t2,可加多重判断
  • coalesce(v0,v1,v2):返回参数中的第一个非空值,若所有值均为null,则返回null。
    • 如coalesce(null,1,2)返回1
  • isnull(a):若a为null则返回true,否则返回false
5.4、字符串函数
  • length(string1):返回字符串长度
  • concat(string1,string2):返回拼接string1及string2后的字符串
  • concat_ws(sep,string1,string2):返回按指定分隔符拼接的字符串
  • lower(string1):返回小写字符串,同lcase(string1)。upper()/ucase():返回大写字符串
  • trim(string1):去字符串左右空格,ltrim(string1):去字符串左空格。rtrim(string1):去字符串右空
  • repeat(string1,int1):返回重复string1字符串int1次后的字符串
  • reverse(string1):返回string1反转后的字符串。
    • 如reverse(‘abc’)返回’cba’
  • rpad(string1,len1,pad1):以pad1字符右填充string1字符串,至len1长度。
    • 如rpad(‘abc’,5,‘1’)返回’abc11’。lpad():左填充
  • split(string1,pat1):以pat1正则分隔字符串string1,返回数组。
    • 如split(‘a,b,c’,‘,’)返回[“a”,“b”,“c”]
  • substr(string1,index1,int1):以index位置起截取int1个字符。
    • 如substr(‘abcde’,1,2)返回’ab’
5.5、类型转换

​ Hive的原子数据类型是可以进行隐式转换的,类似于Java的类型转换,例如某表达式使用INT类型,TINYINT会自动转换为INT类型,但是Hive不会进行反向转化,例如,某表达式使用TINYINT类型,INT不会自动转换为TINYINT类型,它会返回错误,除非使用CAST操作。

  • cast(value AS TYPE)
    • select cast(‘1’ as DOUBLE); 返回1.0

6、hive常用的优化

6.1、 Fetch抓取(Hive可以避免进行MapReduce)

​ Hive中对某些情况的查询可以不必使用MapReduce计算。例如:SELECT * FROM employees;在这种情况下,Hive可以简单地读取employee对应的存储目录下的文件,然后输出查询结果到控制台。

​ 在hive-default.xml.template文件中hive.fetch.task.conversion默认是more,老版本hive默认是minimal,该属性修改为more以后,在全局查找、字段查找、limit查找等都不走mapreduce。

案例实操

​ 1)把hive.fetch.task.conversion设置成none,然后执行查询语句,都会执行mapreduce程序。

hive (default)> set hive.fetch.task.conversion=none;

hive (default)> select * from score;

hive (default)> select s_score from score;

hive (default)> select s_score from score limit 3;

2)把hive.fetch.task.conversion设置成more,然后执行查询语句,如下查询方式都不会执行mapreduce程序。

hive (default)> set hive.fetch.task.conversion=more;

hive (default)> select * from score;

hive (default)> select s_score from score;

hive (default)> select s_score from score limit 3;
6.2、本地模式

​ 大多数的Hadoop Job是需要Hadoop提供的完整的可扩展性来处理大数据集的。不过,有时Hive的输入数据量是非常小的。在这种情况下,为查询触发执行任务时消耗可能会比实际job的执行时间要多的多。对于大多数这种情况,Hive可以通过本地模式在单台机器上处理所有的任务。对于小数据集,执行时间可以明显被缩短。

​ 用户可以通过设置hive.exec.mode.local.auto的值为true,来让Hive在适当的时候自动启动这个优化。

set hive.exec.mode.local.auto=true;  //开启本地mr
//设置local mr的最大输入数据量,当输入数据量小于这个值时采用local  mr的方式,默认为134217728,即128M
set hive.exec.mode.local.auto.inputbytes.max=51234560;
//设置local mr的最大输入文件个数,当输入文件个数小于这个值时采用local mr的方式,默认为4
set hive.exec.mode.local.auto.input.files.max=10;

案例实操:

1)开启本地模式,并执行查询语句
hive (default)> set hive.exec.mode.local.auto=true; 
hive (default)> select * from score cluster by s_id;
18 rows selected (1.568 seconds)
2)关闭本地模式,并执行查询语句
hive (default)> set hive.exec.mode.local.auto=false; 
hive (default)> select * from score cluster by s_id;
18 rows selected (11.865 seconds)
6.3、分区表分桶表
  • 分区表对sql过滤查询是一种优化
  • 分桶表对join操作时提升性能很大,桶为表加上了额外的结构,Hive 在处理有些查询时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接 (Map-side join)高效的实现。比如JOIN操作。对于JOIN操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量。
6.4、join优化
6.4.1、小表Join大表
  • (新的版本当中已经没有区别了,旧的版本当中需要使用小表)

1)将key相对分散,并且数据量小的表放在join的左边,这样可以有效减少内存溢出错误发生的几率;再进一步,可以使用Group让小的维度表(1000条以下的记录条数)先进内存。在map端完成reduce。

2)多个表关联时,最好分拆成小段,避免大sql(无法控制中间Job)

3)大表Join大表

(1)空KEY过滤

有时join超时是因为某些key对应的数据太多,而相同key对应的数据都会发送到相同的reducer上,从而导致内存不够。此时我们应该仔细分析这些异常的key,很多情况下,这些key对应的数据是异常数据,我们需要在SQL语句中进行过滤。例如key对应的字段为空。

对比如下:

不过滤

INSERT OVERWRITE TABLE jointable
SELECT a.* FROM nullidtable a JOIN ori b ON a.id = b.id;
结果:
No rows affected (152.135 seconds)

过滤

INSERT OVERWRITE TABLE jointable
SELECT a.* FROM (SELECT * FROM nullidtable WHERE id IS NOT NULL ) a JOIN ori b ON a.id = b.id;
结果:
No rows affected (141.585 seconds)
6.4.2、mapjoin

​ 如果不指定MapJoin或者不符合MapJoin的条件,那么Hive解析器会将Join操作转换成Common Join,即:在Reduce阶段完成join。容易发生数据倾斜。可以用MapJoin把小表全部加载到内存在map端进行join,避免reducer处理。

1)开启MapJoin参数设置:

(1)设置自动选择Mapjoin

set hive.auto.convert.join = true; 默认为true

(2)大表小表的阈值设置(默认25M以下认为是小表):

set hive.mapjoin.smalltable.filesize=25123456;

6.5、group by

默认情况下,Map阶段同一Key数据分发给一个reduce,当一个key数据过大时就倾斜了。

​ 并不是所有的聚合操作都需要在Reduce端完成,很多聚合操作都可以先在Map端进行部分聚合,最后在Reduce端得出最终结果。

1)开启Map端聚合参数设置

​ (1)是否在Map端进行聚合,默认为True

set hive.map.aggr = true;

(2)在Map端进行聚合操作的条目数目

set hive.groupby.mapaggr.checkinterval = 100000;

(3)有数据倾斜的时候进行负载均衡(默认是false)

set hive.groupby.skewindata = true;

当选项设定为 true,生成的查询计划会有两个MR Job。第一个MR Job中,Map的输出结果会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的Group By Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;第二个MR Job再根据预处理的数据结果按照Group By Key分布到Reduce中(这个过程可以保证相同的Group By Key被分布到同一个Reduce中),最后完成最终的聚合操作。
6.6、Map数
  1. 通常情况下,作业会通过input的目录产生一个或者多个map任务。

    主要的决定因素有:input的文件总个数,input的文件大小,集群设置的文件块大小(目前为128M,可在hive中通过set dfs.block.size;命令查看到,该参数不能自定义修改);

  2. 举例:

    a) 假设input目录下有1个文件a,大小为780M,那么hadoop会将该文件a分隔成7个块(6个128m的块和1个12m的块),从而产生7个map数。

    b) 假设input目录下有3个文件a,b,c大小分别为10m,20m,150m,那么hadoop会分隔成4个块(10m,20m,128m,22m),从而产生4个map数。即,如果文件大于块大小(128m),那么会拆分,如果小于块大小,则把该文件当成一个块。

  3. 是不是map数越多越好?

    答案是否定的。如果一个任务有很多小文件(远远小于块大小128m),则每个小文件也会被当做一个块,用一个map任务来完成,而一个map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的map数是受限的。

  4. 是不是保证每个map处理接近128m的文件块,就高枕无忧了?

    答案也是不一定。比如有一个127m的文件,正常会用一个map去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,如果map处理的逻辑比较复杂,用一个map任务去做,肯定也比较耗时。

    针对上面的问题3和4,我们需要采取两种方式来解决:即减少map数和增加map数;

  5. 如何增加map数

    如果表a只有一个文件,大小为120M,但包含几千万的记录,如果用1个map去完成这个任务,肯定是比较耗时的,这种情况下,我们要考虑将这一个文件合理的拆分成多个,这样就可以用多个map任务去完成。

    set mapreduce.job.reduces =10;
    create table a_1 as
    select * from a
    distribute by rand(123);
    

    这样会将a表的记录,随机的分散到包含10个文件的a_1表中,再用a_1代替上面sql中的a表,则会用10个map任务去完成。

6.7、reduce数
  1. 调整reduce个数方法一

(1)每个Reduce处理的数据量默认是256MB

​ hive.exec.reducers.bytes.per.reducer=256123456

(2)每个任务最大的reduce数,默认为1009

​ hive.exec.reducers.max=1009

  1. 调整reduce个数方法二

    在hadoop的mapred-default.xml文件中修改

    设置每个job的Reduce个数

    set mapreduce.job.reduces = 15;

  2. reduce个数并不是越多越好

    1)过多的启动和初始化reduce也会消耗时间和资源;

    2)另外,有多少个reduce,就会有多少个输出文件,如果生成了很多个小文件,那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题;

    在设置reduce个数的时候也需要考虑这两个原则:处理大数据量利用合适的reduce数;使单个reduce任务处理数据量大小要合适;

6.8、jvm重用

​ JVM重用是Hadoop调优参数的内容,其对Hive的性能具有非常大的影响,特别是对于很难避免小文件的场景或task特别多的场景,这类场景大多数执行时间都很短。

​ JVM重用可以使得JVM实例在同一个job中重新使用N次。N的值可以在Hadoop的mapred-site.xml文件中进行配置。通常在10-20之间,具体多少需要根据具体业务场景测试得出。

<property>
  <name>mapreduce.job.jvm.numtasks</name>
  <value>10</value>
  <description>How many tasks to run per jvm. If set to -1, there is
  no limit. 
  </description>
</property>

我们也可以在hive当中通过

set  mapred.job.reuse.jvm.num.tasks=10;

这个设置来设置我们的jvm重用

缺点

​ 开启JVM重用将一直占用使用到的task插槽,以便进行重用,直到任务完成后才能释放。如果某个“不平衡的”job中有某几个reduce task执行的时间要比其他Reduce task消耗的时间多的多的话,那么保留的插槽就会一直空闲着却无法被其他的job使用,直到所有的task都结束了才会释放。

6.9、数据压缩与存储格式
1)压缩方式
压缩可以节约磁盘的空间,基于文本的压缩率可达40%+; 压缩可以增加吞吐量和性能量(减小载入内存的数据量),但是在压缩和解压过程中会增加CPU的开销。所以针对IO密集型的jobs(非计算密集型)可以使用压缩的方式提高性能。 几种压缩算法:

在这里插入图片描述

2)存储格式
  • TextFile
Hive数据表的默认格式,存储方式:行存储。 可以使用Gzip压缩算法,但压缩后的文件不支持split 在反序列化过程中,必须逐个字符判断是不是分隔符和行结束符,因此反序列化开销会比SequenceFile高几十倍。

  • Sequence Files
	Hadoop中有些原生压缩文件的缺点之一就是不支持分割。支持分割的文件可以并行	的有多个mapper程序处理大数据文件,大多数文件不支持可分割是因为这些文件只能从头开始读。Sequence File是可分割的文件格式,支持Hadoop的block级压缩。 Hadoop API提供的一种二进制文件,以key-value的形式序列化到文件中。存储方式:行存储。 sequencefile支持三种压缩选择:NONE,RECORD,BLOCK。Record压缩率低,RECORD是默认选项,通常BLOCK会带来较RECORD更好的压缩性能。 优势是文件和hadoop api中的MapFile是相互兼容的

  • RCFile
存储方式:数据按行分块,每块按列存储。结合了行存储和列存储的优点:

首先,RCFile 保证同一行的数据位于同一节点,因此元组重构的开销很低 其次,像列存储一样,RCFile 能够利用列维度的数据压缩,并且能跳过不必要的列读取 数据追加:RCFile不支持任意方式的数据写操作,仅提供一种追加接口,这是因为底层的 HDFS当前仅仅支持数据追加写文件尾部。 行组大小:行组变大有助于提高数据压缩的效率,但是可能会损害数据的读取性能,因为这样增加了 Lazy 解压性能的消耗。而且行组变大会占用更多的内存,这会影响并发执行的其他MR作业。

  • ORCFile
	存储方式:数据按行分块,每块按照列存储。

	压缩快,快速列存取。效率比rcfile高,是rcfile的改良版本。


  • Parquet
	Parquet也是一种列式存储,同时具有很好的压缩性能;同时可以减少大量的表扫描和反序列化的时间
	

  • 自定义格式
可以自定义文件格式,用户可通过实现InputFormat和OutputFormat来自定义输入输出格式。

  • 一般选择orcfile/parquet + snappy 的方式
create table tablename (
 xxx,string
 xxx, bigint
)
ROW FORMAT DELTMITED FIELDS TERMINATED BY '\t'
STORED AS orc tblproperties("orc.compress" = "SNAPPY")
6.10、并行执行
  • 当一个sql中有多个job时候,且这多个job之间没有依赖,则可以让顺序执行变为并行执行(一般为用到union all )
// 开启任务并行执行
 set hive.exec.parallel=true;
 // 同一个sql允许并行任务的最大线程数 
set hive.exec.parallel.thread.number=8;
6.11、合并小文件

​ 小文件的产生有三个地方,map输入,map输出,reduce输出,小文件过多也会影响hive的分析效率:

设置map输入的小文件合并

set mapred.max.split.size=256000000;  
//一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并)
set mapred.min.split.size.per.node=100000000;
//一个交换机下split的至少的大小(这个值决定了多个交换机上的文件是否需要合并)  
set mapred.min.split.size.per.rack=100000000;
//执行Map前进行小文件合并
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

设置map输出和reduce输出进行合并的相关参数:

//设置map端输出进行合并,默认为true
set hive.merge.mapfiles = true
//设置reduce端输出进行合并,默认为false
set hive.merge.mapredfiles = true
//设置合并文件的大小
set hive.merge.size.per.task = 256*1000*1000
//当输出文件的平均大小小于该值时,启动一个独立的MapReduce任务进行文件merge。
set hive.merge.smallfiles.avgsize=16000000

7、hive的数据倾斜

表现:任务进度长时间维持在99%(或100%),查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成。因为其处理的数据量和其他reduce差异过大。

原因:某个reduce的数据输入量远远大于其他reduce数据的输入量

1)、key分布不均匀

2)、业务数据本身的特性

3)、建表时考虑不周

4)、某些SQL语句本身就有数据倾斜

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

百度大脑 使用

百度大脑&#xff1a; 官方网址&#xff1a;https://ai.baidu.com/ 文档中心&#xff1a;https://ai.baidu.com/ai-doc 体验中心&#xff1a;https://ai.baidu.com/experience 百度大脑则是百度AI核心技术引擎&#xff0c;它包括基础层、感知层、认知层和安全&#xff0c;是百…

Codeforces Round 803 (Div. 2) E. PermutationForces II(思维题 位置序列)

题目 给定长为n(n<2e5)的两个序列a和b&#xff0c; a为n的一个排列&#xff0c; b也为n的一个排列&#xff0c;但有一些位置被-1替换了&#xff0c;保证没被替换的位置在[1,n]之间且两两不同 你有一个距离最大限制s&#xff0c;你可以执行n次操作&#xff0c; 第i次操作…

【爬虫实战】2024知乎热榜可视化爬取

项目功能简介&#xff1a; 1.支持配置&#xff1b; 2.单次爬取&#xff1b; 3.循环爬取&#xff1b; 4.爬虫暂停&#xff1b; 5.数据清除&#xff1b; 6.数据保存到csv文件&#xff1b; 7.程序支持打包成exe文件&#xff1b; 8.项目操作说明文档&#xff1b; 9.模块封装到类&a…

全自动网页制作系统流星全自动网页生成系统重构版输入网页信息即可制作

源码优点: 所有模板经过精心审核与修改&#xff0c;完美兼容小屏手机大屏手机&#xff0c;以及各种平板端、电脑端和360浏览器、谷歌浏览器、火狐浏览器等等各大浏览器显示。 免费制作 为用户使用方便考虑&#xff0c;全自动网页制作系统无需繁琐的注册与登入&#xff0c;直接…

大创项目推荐 疫情数据分析与3D可视化 - python 大数据

文章目录 0 前言1 课题背景2 实现效果3 设计原理4 部分代码5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 大数据全国疫情数据分析与3D可视化 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff0…

AWS CI/CD之二:配置CodeDeploy

问题 前面一篇文章介绍了CodeBuild中构建一个Java的Maven项目。在这个基础上面&#xff0c;我们继续AWS CI/CD工作流构建之路。 1.配置CodePipeline简配版 这里主要是利用CodePipeline配置之前的CodeBuild项目&#xff0c;以便生产出需要部署的jar文件和CodeDeploy需要用到相…

手把手教你薅熊链Berachain测试网空投

Berachain&#xff0c;这名字响当当&#xff01;是基于流动性证明的高性能区块链&#xff0c;结合了Tendermint和流动性共识证明&#xff0c;还采用了Celestia作为DA层。这速度快、成本低、确定性高&#xff0c;简直就是未来的大热门&#xff01;你知道吗&#xff1f;这家公司可…

异步编程Completablefuture使用详解----入门篇

JDK版本&#xff1a;jdk17 IDEA版本&#xff1a;IntelliJ IDEA 2022.1.3 文章目录 一、CompletableFuture是什么&#xff1f;二、为什么要使用CompletableFuture&#xff1f;2.1 工具类准备2.2 Future的局限性2.3 CompletableFuture的优势 三、如何使用CompletableFuture?3.1 …

Web3艺术市场:NFT与数字创作的结合

在数字时代&#xff0c;随着区块链技术的崛起&#xff0c;一种新型数字资产&#xff0c;非同质化代币&#xff08;NFT&#xff09;&#xff0c;正逐渐改变传统艺术市场的格局。这种数字化的艺术品售卖方式成为了Web3艺术市场的代表&#xff0c;推动着数字创作与艺术市场的结合。…

day05_java中的流程控制

概述 在一个程序执行的过程中&#xff0c;各条语句的执行顺序对程序的结果是有直接影响的。所以&#xff0c;我们必须清楚每条语句的执 行流程。而且&#xff0c;很多时候要通过控制语句的执行顺序来实现我们想要的功能。 流程控制语句又分为&#xff1a; 顺序结构 丶分支结构丶…

性能优化-HVX架构简介

来自 「发表于知乎专栏《移动端算法优化》」 本文主要介绍Hexagon DSP的HVX技术&#xff0c;旨在通过简单的语言讲清HVX技术。 &#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;高性能&#xff08;HPC&#xff09;开…

vue3 + antd 封装动态表单组件(一)

前置条件&#xff1a; vue版本 v3.3.11 ant-design-vue版本 v4.1.1 创建动态组件配置文件config.js import { Input, Textarea, InputNumber, Select, RadioGroup, CheckboxGroup, DatePicker } from ant-design-vue;// 表单域组件类型 export const componentsMap {Text: …

编译poco库出现的问题及其解决办法

作者&#xff1a;朱金灿 来源&#xff1a;clever101的专栏 为什么大多数人学不会人工智能编程&#xff1f;>>> 使用vs2015编译poco库出现问题&#xff1a;error C3688: invalid literal suffix ‘I64_FMT’; literal operator or literal operator template ‘opera…

大模型:我也会自监督学习~

前言 当下大模型的能力已经很强了&#xff0c;但是将来我们想要的是能力更强的大模型&#xff0c;其最好能够处理各种复杂问题也即强对齐模型。 之前大模型训练的监督信号主要来源于人类反馈&#xff0c;但是如果想要训练一个强对齐模型必然就需要一个对应的强监督信号&#…

第二篇【传奇开心果系列】Vant 开发移动应用:开发常见页面

传奇开心果博文系列 Vant of Vue 开发移动应用示例系列博文博文目录一、常见页面的重要作用二、常见页面介绍三、分别示例代码四、常见页面样式示例代码五、主要知识点总结 Vant of Vue 开发移动应用示例系列博文 博文目录 一、常见页面的重要作用 常见页面在移动应用中扮演…

手把手教你如何快速定位bug,如何编写测试用例,快来观摩......

手把手教你如何快速定位bug,如何编写测试用例,快来观摩......手把手教你如何快速定位bug,如何编写测试用例,快来观摩......作为一名测试人员如果连常见的系统问题都不知道如何分析&#xff0c;频繁将前端人员问题指派给后端人员&#xff0c;后端人员问题指派给前端人员&#xf…

算法第二十一天-丑数

丑数 题目要求 解题思路 首先判断数字是不是为0或者负数&#xff0c;两者均不可能成为丑数&#xff1b; 之后对n进行不断整除&#xff0c;直到无法除尽为止。 简单判断最后的数是不是1即可。 代码 class Solution:def isUgly(self, n: int) -> bool:if n<0:return Fa…

linux perf工具使用

参考文章Linux性能调优之perf使用方法_perf交叉编译-CSDN博客 perf是一款Linux性能分析工具。比如打流性能优化的时候&#xff0c;就能够看到是哪些函数消耗的cpu高 那么linux如何编译perf工具呢&#xff1f; perf工具编译 进入perf目录下linux-3.16/tools/perf make ARCH…

线程状态转换

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;并发编程⛺️稳中求进&#xff0c;晒太阳 程状态转换 假设有线程Thread t 情况1 new-->RUNNABLE 当调用t.start()方法时&#xff0c;由new ->RUNNABLE 情况2 RUNNABLE WAITING t…

Spark On Hive配置测试及分布式SQL ThriftServer配置

文章目录 Spark On Hive的原理及配置配置步骤在代码中集成Spark On Hive Spark分布式SQL执行原理及配置配置步骤在代码中集成Spark JDBC ThriftServer 总结 Spark On Hive的原理及配置 Spark本身是一个执行引擎&#xff0c;而没有管理metadate的能力&#xff0c;当我们在执行S…