谁来跟我聊6毛钱的数据仓库——hive

在这里插入图片描述

数据仓库——hive

一、数据仓库的概念

数据仓库(Data Warehouse)是一个面向主题的,数据集成的,相对稳定、时变的数据集合,用于支持管理和决策。

1.1 数据仓库与数据库的区别

数据库数据仓库
面向事务主题
存储数据存储在线交易数据存储历史数据
设计规则尽量避免冗余,一般采用符合范式的规则来设计有意引入冗余(维度退化),采用反范式的方式来设计
数据设计捕获数据分析数据

注:三范式:
第一范式(1NF):确保每一列的原子性
第二范式:非键字段必须依赖于主键字段
第三范式:在1NF基础上,除了主键以外的其它列都不传递依赖于主键列,或者说: 任何非主属性不依赖于其它非主属性

1.2 OLTP与OLAP的区别

OLTP(On-Line Transaction Processing) 联机事务处理。其基本特征是前台接收的用户数据可以立即传送到计算机中心进行处理,并在很短的时间内给出处理结果,是对用户操作快速响应的方式之一。这类系统的特点是事务操作频繁,数据量小。
OLAP(On-Line Analytical Processing)即联机分析处理。支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。这类系统的特点是没有事务性操作,主要是查询操作,数据量大。
在这里插入图片描述

1.3 数据仓库建模

1.3.1 事实表

事实表记录了特定事件的数字化信息,一般由数值型数字和指向维度表的外键组成。
事实表的设计依赖于业务系统,事实表的数据就是业务系统的指标数据。数据分析的实质就是基于事实表开展的计算操作。

1.3.2 维度表

维度是指观察数据的角度,一般是一个名词,比如对于销售金额这个事实,我们可以从销售时间、销售产品、销售店铺、购买顾客等多个维度来观察分析。
维度表的记录数比事实表少,但是每条记录可能会包含很多字段。

1.4 常用的建模方法

1.4.1 星型模型

特点: 只有一个事实表, 也就是说只有一个分析的主题, 有多个维度表, 维度表与维度表没有任何的关联。数仓发展的初期最容易产生的模型。

1.4.2 雪花模型

特点: 只有一个事实表, 也就是说只有一个分析的主题, 有多个维度表, 维度表可以接着关联其他的维度表。在数仓发展的过程中, 要尽可能避免出现此种模型, 在这种模型, 提升SQL的难度, 提升维护难度。

1.4.3 星座模型

特点: 有多张事实表, 也就说有多个分析的主题, 有多个维度表, 维度表和维度表在一定的条件下是可以共用的。数仓发展的中 后期应该产生的模型。

二、数据仓库的分层架构

通常将数据模型分为三层:数据运营层( ODS )、数据仓库层(DW)和数据应用层(APP)。ODS层存放的是接入的原始数据,DW层是存放我们要重点设计的数据仓库中间层数据,APP是面向业务定制的应用数据。

2.1 源数据层(ODS)

此层数据无任何更改,直接沿用外围系统数据结构和数据,不对外开放;为临时存储层,是接口数据的临时存储区域,为后一步的数据处理做准备。

2.2 数据仓库层(DW)

2.2.1 数据明细层(DWD)

明细层DWD(Data Warehouse Detail):存储明细数据,此数据是最细粒度的事实数据。该层一般保持和ODS层一样的数据粒度,并且提供一定的数据质量保证。同时,为了提高数据明细层的易用性,该层会采用一些维度退化手法,将维度退化至事实表中,减少事实表和维表的关联。

2.2.2 数据中间层(DWM)

中间层DWM(Data WareHouse Middle):存储中间数据,为数据统计需要创建的中间表数据,此数据一般是对多个维度的聚合数据,此层数据通常来源于DWD层的数据。

2.2.3 数据服务层(DWS)

业务层DWS(Data WareHouse Service):存储宽表数据,此层数据是针对某个业务领域的聚合数据,应用层的数据通常来源于此层,为什么叫宽表,主要是为了应用层的需要在这一层将业务相关的所有数据统一汇集起来进行存储,方便业务层获取。此层数据通常来源与DWD和DWM层的数据。

2.3 数据应用层(APP)

前端应用直接读取的数据源;根据报表、专题分析的需求而计算生成的数据。

2.4 维表层(DIM)

1.高基数维度数据:一般是用户资料表、商品资料表类似的资料表。数据量可能是千万级或者上亿级别。
2.低基数维度数据:一般是配置表,比如枚举值对应的中文含义,或者日期维表。数据量可能是个位数或者几千几万。
在这里插入图片描述

三、hive工作流程

3.1 将sql解析为MapReduce

(1)用户提交查询等任务给Driver
(2)解析器(SQL Parser):将SQL字符转换成抽象语法树AST
(2)编译器(Physical Plan):将AST编译生成逻辑执行计划
(3)优化器(Query Optimizer):对逻辑执行计划进行优化
(4)执行器(Execution):把逻辑执行计划转换成可以运行的物理计划,对于Hive来说,就是MR/Spark

四、hive表的类型

4.1 管理表(内部表)

内部表是默认的表的类型,在创建表时,什么都不加,就是管理表。
内部表的特点:如果不手动删除就永久存在,类似于zookeeper的永久性结点。
如果手动删除,删除时,既删除元数据,也删除数据。
建表语句: create table table_name;

4.2 临时表

建表语句:create tempoary table
特点: 临时表会随着会话的结束,而自动删除,类似于ZK中的临时结点。
应用: 用于临时存储数据,这个数据一旦被使用后,下次就不需要了。

4.3 外部表

建表语句: create external table
特点: 如果手动删除,删除时,只删除元数据,不删除数据。
应用: 应用多张表共享一份数据,如果一张表删除,不影响其他表的使用

五、hive表的结构

5.1 分区表

设计: 将数据按照一定的分类规则,按照分类存储到不同的目录中
功能: 优化底层mapreduce输入,避免读取所有数据,进行过滤。
有一下两种方式创建分区表:
方式一:静态分区
应用场景: 数据本身就是按照分区规则分好的。
例如:hive 日志一天一个文件

  • 创建分区表
create table tb_emp_part1(
 empno string,
 ename string,
 job string,
 managerno string,
 hiredate string,
 salary double,
 jiangjin double,
 deptno string
) 
partitioned by (department int)
row format delimited fields terminated by '\t';


  • 加载分区数据
load data local inpath '/export/data/emp10.txt' into table tb_emp_part1 partition(department = 10);
load data local inpath '/export/data/emp20.txt' into table tb_emp_part1 partition(department = 20);
load data local inpath '/export/data/emp30.txt' into table tb_emp_part1 partition(department = 30);
  • 查看结果
show partitions  tb_emp_part1;

方式二:动态分区
应用场景: 数据本身没有做分区来拆分不同的文件

1、开启自动分区:set hive.exec.dynamic.partition.mode=nonstrict;
2、创建分区表

  • 先创建一张普通的表结构1,将没有分区的数据加载到普通的表结构中
  • 再构建一张分区结构表2,从普通表1中查询将数据分区写入到分区表2
create table tb_emp_part2(
  empno string,
  ename string,
  job string,
  managerno string,
  hiredate string,
  salary double,
  bonus double
) 
partitioned by (dept string)
row format delimited fields terminated by '\t';

3、从原始数据表加载到分区表

insert into table tb_emp_part2 partition(dept)
select * from tb_emp ;

注意:自动分区会自动按照查询语句最后的字段进行分区。
例:上述想要按照job分区。

create table tb_emp_part2(
  empno string,
  ename string,
  managerno string,
  hiredate string,
  salary double,
  jiangjin double,
  dept string
) 
partitioned by (job string)
row format delimited fields terminated by '\t';
            
insert into table tb_emp_part2 partition(job)
select empno,ename,managerno,hiredate,salary,jiangjin,deptno,job from tb_emp ;

5.2 分桶表

功能: 对hive表中的数据进行存储优化,细化了数据存储。
特点:
1、分桶表结构与普通表结构一样,表的文件都是最后一级目录
2、表中的数据是按照一定规则存放的。hive中的分桶本质就是mapreduce中的分区。
应用: 主要有两点,一个是用于分桶join,一个是抽样。
分桶表的创建:

  • 开启分桶
set hive.enforce.bucketing=true;
set hive.optimize.bucketmapjoin = true;
set hive.optimize.bucketmapjoin.sortedmerge = true;
  • 创建分桶表
create table tb_emp_bucket(
empno string,
ename string,
job string,
managerno string,
hiredate string,
salary double,
jiangjin double,
deptno string
) 
clustered by (deptno) into 3 BUCKETS
row format delimited fields terminated by '\t';
  • 从原始数据表加载到分桶表
insert overwrite table tb_emp_bucket
select * from tb_emp cluster by (deptno);

抽样查询语句:select * from table tablesample(bucket x out of y on column)
x表示从哪个bucket开始抽取,如果需要取多个分区,以后的分区号为当前分区号加上y。
例如,table总bucket数为6,tablesample(bucket 1 out of 2),表示总共抽取(6/2=)3个bucket的数据,从第1个bucket开始,抽取第1(x)个和第3(x+y)个和第5(x+y)个bucket的数据。
注意: x的值必须小于等于y的值。否则会抛出异常:FAILED: SemanticException [Error 10061]: Numerator should not be bigger than denominator in sample clause for table stu_buck。

六、hive表的存储格式

存储方式压缩方式特点
textfile行存储使用Gzip,Bzip2等压缩算法压缩,压缩后的文件不支持split空间利用率低
SequenceFile行存储ONE,RECORD,BLOCK。Record压缩率低,一般建议使用BLOCK压缩。Hadoop API提供的一种二进制文件,以<key,value>的形式序列化到文件中
orcfile数据按行分组,每块按照列存储,默认行组大小为250MBZLIB和SNAPPY,默认ZLIB。压缩速度快 快速列存取运用ORC File可以提高Hive的读、写以及处理数据的性能。
Parquet数据按行分组,每块按照列存储gzip、snappy、 lzo等Parquet和ORC有很多相似之处, 但是Parquet更有意成为hadoop上通用的存储格式. 它可以与impala, Spark, Pig等引擎结合使用. 它可以指定每一列的压缩方式, 从而实现更高效的压缩. Parquet旨在设计为支持复杂嵌套数据的存储, 比如json

数据仓库的特点:一次写入、多次读取、并行执行,因此,整体来看,ORCFile相比其他格式具有较明显的优势。

七、hive表的压缩格式

在这里插入图片描述
对于数据仓库架构中,ODS数据源层,因为数据量较大,可以采用orcfile+ZLIB的方式,以节省磁盘空间;而在计算的过程中(DWD、DWM、DWS、APP),为了不影响执行的速度,可以浪费一点磁盘空间,采用orcfile+SNAPPY的方式,提升hive的执行速度。
存储空间足够的情况下,推荐采用SNAPPY压缩。

八、hive索引

8.1 原始索引

Hive3.0已被删除。在每次建立、更新数据后,Hive索引不会自动更新,需要手动进行更新(重建索引以构建索引表),会触发一个mr job。Hive索引使用过程繁杂,而且性能一般。

8.2 Row Group Index

一个ORC文件包含一个或多个stripes(groups of row data),每个stripe中包含了每个column的min/max值的索引数据,当查询中有<,>,=的操作时,会根据min/max值,跳过扫描不包含的stripes。而其中为每个stripe建立的包含min/max值的索引,就称为Row Group Index行组索引,也叫min-max Index大小对比索引,或者Storage Index。
在建立ORC格式表时,指定表参数 orc.create.index=true 之后,便会建立Row Group Index,需要注意的是,为了使Row Group Index有效利用,向表中加载数据时,必须对需要使用索引的字段进行排序,否则,min/max会失去意义。另外,这种索引主要用于数值型字段的查询过滤优化上。

8.3 Bloom Filter Index

在建表时候,通过表参数”orc.bloom.filter.columns”=”pcid”来指定为那些字段建立BloomFilter索引,这样,在生成数据的时候,会在每个stripe中,为该字段建立BloomFilter的数据结构,当查询条件中包含对该字段的=号过滤时候,先从BloomFilter中获取以下是否包含该值,如果不包含,则跳过该stripe。
hive.optimize.index.filter 自动开启索引。

海量数据处理算法—Bloom Filter

九、hive中的map join与排序

9.1 hive中的map join

9.1.1 map join

作用: 在Map阶段就进行表之间的连接。MAPJION会把小表全部读入内存中,在map阶段直接拿另外一个表的数据和内存中表数据做匹配,由于在map时进行了join操作,省去了reduce运行的效率会高很多。而不需要进入到Reduce阶段才进行连接。节省了在shuffle阶段时要进行大量数据传输,排序的过程,从而优化作业的作用。
使用条件:
1) set hive.auto.convert.join=true;
2) 两个表一个很大一个很小。

9.1.2 Bucket-MapJoin

作用: 两个表join的时候,小表不足以放到内存中,但是又想用map side join这个时候就要用到bucket Map join。其方法是两个join表在join key上都做hash bucket,并且把你打算复制的那个(相对)小表的bucket数设置为大表的倍数。这样数据就会按照key join,做hash bucket。小表依然复制到所有节点,Map join的时候,小表的每一组bucket加载成hashtable,与对应的一个大表bucket做局部join,这样每次只需要加载部分hashtable就可以了。
使用条件:
1) set hive.optimize.bucketmapjoin = true;
2) 一个表的bucket数是另一个表bucket数的整数倍
3) bucket列 == join列
4) 必须是应用在map join的场景中

9.1.3 SMB Join

作用: 大表对小表应该使用MapJoin来进行优化,但是如果是大表对大表,如果进行shuffle,那就非常可怕,第一个慢不用说,第二个容易出异常,此时就可以使用SMB Join来提高性能。SMB Join基于bucket-mapjoin的有序bucket,可实现在map端完成join操作,可以有效地减少或避免shuffle的数据量。SMB join的条件和Map join类似但又不同。
使用条件:
1) set hive.optimize.bucketmapjoin = true;
set hive.auto.convert.sortmerge.join=true;
set hive.optimize.bucketmapjoin.sortedmerge = true;
set hive.auto.convert.sortmerge.join.noconditionaltask=true;
2) 小表的bucket数=大表bucket数
3) Bucket 列 = Join 列 = sort 列
4) 必须是应用在bucket mapjoin 的场景中

9.2 hive中的排序

9.2.1 Sort by

sort by 只会在每个reducer中对数据进行排序,也就是执行一个局部排序的过程。这样就可以保证每个reducer的输出都是局部有序的。这样可以提高后面进行的全局排序的效率。

9.2.2 Order by

会对查询结果进行一个全局排序。也就是说会有一个所有的数据都会通过一个reducer进行处理的过程。对于大数据集来说,这个过程可能会消耗太过漫长的时间来执行。

9.2.3 Distribute By

distribute by 控制map的输出再reducer中是如何划分的。默认情况下,mapreduce计算框架会依据map输入的键计算相应的hash值,然后按照得到的hash值将键-值对均匀分发到多个reducer中去。

9.2.4 Cluster By

如果distribute by和sort by指定的是同一个字段,就可以直接使用cluster by代替。

十、hive的优化

找到一篇讲解hive优化还比较不错的文章,附上链接:
hive优化(整理版)
个人总结:hive的优化主要是从SQL语句、MR优化、配置优化三个方面去进行,主要以MR优化为主,当然MR的优化也是从配置出发的。注意:红色部分为常用的优化

10.1 SQL优化

SQL优化的原则是:尽量减少不必要的数据参与计算。
实现:

  • 1、能在where中过滤的,就提前在where中过滤,避免不需要计算的数据进行分组。

  • 2、尽量减少不必要的数据参加join。

10.1.1 列裁剪

在表字段很多时,查询数据时禁止使用select * from table;可以只读取查询逻辑中需要的列,这样可以节省读取开销,中间表存储开销和数据整合开销。

10.1.2 分区裁剪

在查询过程中减少不必要的分区。如一下查询:

SELECT * FROM (SELECT a1, COUNT(1) FROM T GROUP BY a1) subq WHERE subq.prtn=100; # (多余分区)
SELECT * FROM T1 JOIN (SELECT * FROM T2) subq ON (T1.a1=subq.a2) WHERE subq.prtn=100;

查询语句若将"subq.prtn=100"条件放入子查询中更为高效,可以减少读入的分区数目。Hive自动执行这种裁剪优化。

10.1.3 COUNT(DISTINCT)

数据量大的情况下,由于COUNT DISTINCT操作需要用一个Reduce Task来完成,这一个Reduce需要处理的数据量太大,就会导致整个Job很难完成,一般COUNT DISTINCT使用先GROUP BY再COUNT的方式替换。

10.2 hive资源配置优化

10.2.1 yarn配置

CPU配置:

yarn.nodemanager.resource.cpu-vcores 容器虚拟CPU内核

内存配置:

yarn.nodemanager.resource.memory-mb 容器分配的总内存,默认为8G

一般按照服务器剩余可用内存资源进行配置。生产上根据经验一般要预留15-20%的内存,那么可用内存就是实际内存0.8,比如实际内存是64G,那么640.8=51.2G,我们设置成50G就可以了(固定经验值)。

10.2.2 mapreduce内存配置

mapreduce.map.memory.mb 为作业的每个 Map 任务分配的物理内存量(MiB),默认为0,自动判断大小。
mapreduce.reduce.memory.mb 为作业的每个 Reduce 任务分配的物理内存量(MiB),默认为0,自动判断大小。
mapreduce.map.java.opts、mapreduce.reduce.java.opts。Map和Reduce的JVM配置选项。

注意:
mapreduce.map.java.opts一定要小于mapreduce.map.memory.mb;
mapreduce.reduce.java.opts一定要小于mapreduce.reduce.memory.mb,格式-Xmx4096m。
注意:
此部分所有配置均不能大于Yarn的NodeManager内存配置。

10.3 MR优化

10.3.1 Input阶段:将输入小文件合并成为大文件

小文件是如何产生的:

  • 数据源本身就包含大量的小文件。

小文件问题的影响:

  • 从Hive的角度看,小文件会开很多map,一个map开一个JVM去执行,所以这些任务的初始化,启动,执行会浪费大量的资源,严重影响性能。
  • 在HDFS中,每个小文件对象约占150byte,如果小文件过多会占用大量内存。这样NameNode内存容量严重制约了集群的扩展。
将输入小文件合并成为大文件

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

10.3.2 map阶段优化

设置适当map个数:
1、适当减少map个数:map执行前合并小文件,减少map数。
2、适当增加map个数:假如input输入文件很大,任务逻辑复杂,map执行的速度很慢,可考虑增加map的个数。

10.3.3 Shuffle阶段优化

Map端聚合:

hive.map.aggr=true; //Map端聚合,相当于combine操作

map阶段输出文件进行压缩:

mapreduce.map.output.compress:设置是否启动map输出压缩,默认为false。在需要减少网络传输的时候,可以设置为true。
mapreduce.map.output.compress.codec:设置map输出压缩编码解码器,默认为org.apache.hadoop.io.compress.DefaultCodec,推荐使用SnappyCodec:org.apache.hadoop.io.compress.SnappyCodec。

map阶段输出文件进行合并:

设置map输出和reduce输出进行合并的相关参数:
set hive.merge.mapfiles = true //在Map-only的任务结束时合并小文件
下面有关reduce阶段文件合并在此也一并给出:
set hive.merge.mapredfiles = true //在Map-Reduce的任务结束时合并小文件,默认为false
set hive.merge.size.per.task = 25610001000 //设置合并文件的大小
set hive.merge.smallfiles.avgsize=16000000 //当输出文件的平均大小小于该值时,启动一个独立的MapReduce任务进行文件merge。

10.3.4 Reduce阶段优化

适当设置reduce个数:
如果Reduce设置的过大,那么将会产生很多小文件,对NameNode会产生一定的影响,而且整个作业的运行时间未必会减少;如果Reduce设置的过小,那么单个Reduce处理的数据将会加大,很可能会引起OOM异常。

set mapred.reduce.tasks = 20; //手动设置reduce个数
set hive.exec.reducers.max =2000; //每个任务最大的reduce数
set mapreduce.job.running.reduce.limit=80; // 规定reduce同时并行的个数
set hive.exec.reducers.bytes.per.reducer=102410001000; //设置每个reduce可处理的数据大小

10.3.5 output阶段优化

输出结果压缩:

mapreduce.output.fileoutputformat.compress //是否启用 MapReduce 作业输出压缩。
mapreduce.output.fileoutputformat.compress.codec //指定要使用的压缩编码解码器,推荐SnappyCodec。
mapreduce.output.fileoutputformat.compress.type //指定MapReduce作业输出的压缩方式,默认值RECORD,可配置值有:NONE、RECORD、BLOCK。推荐使用BLOCK,即针对一组记录进行批量压缩,压缩效率更高。

10.4 其他优化

10.4.1 job之间优化

控制是否压缩查询的最终输出(到 local/hdfs 文件或 Hive table)。压缩编解码器和其他选项由 上面Hive通用压缩mapreduce.output.fileoutputformat.compress.*确定。

Hive最终结果压缩:

hive.exec.compress.output=true;

Hive多个Map-Reduce中间数据压缩:

hive.exec.compress.intermediate=true;

10.4.2 分区优化

hive有桶表和分区表,可开启动态分区(其实就是不同文件夹)

set hive.exec.dynamic.partition=true
set hive.exec.dynamic.partition.mode=nonstrict(分区表分为严格模式和非严格模式)

10.4.3 数据倾斜优化

可进行key值个数的判断,判断时候发生数据倾斜

set hive.optimize.skewjoin=true;
set hive.skewjoin.key=100000;(超过10000个相同的key就认为是数据倾斜,需要进行打散处理)

10.4.4 并行执行

Hive会将一个查询转化成一个或多个阶段。这样的阶段可以是MapReduce阶段、抽样阶段、合并阶段、limit阶段。默认情况下,Hive一次只会执行一个阶段,由于job包含多个阶段,而这些阶段并非完全相互依赖,即:这些阶段可以并行执行,可以缩短整个job的执行时间。

set hive.exec.parallel=true; //打开任务并行执行
set hive.exec.parallel.thread.number=16; //同一个sql允许最大并行度,默认为8。

10.4.5 推测执行

  • 现象:运行程序时,发现有一个程序中的某个Task迟迟不能结束

  • 解决:如果开启了推测执行,这个task运行过慢,程序会重新启动一个相同的Task,分配到机器运行,谁先运行结束,另外一个Task会被终止。

mapreduce.map.speculative=true
mapreduce.reduce.speculative=true

十一、hive中的数据倾斜

11.1 什么是数据倾斜

数据倾斜就是数据的分布不平衡,某些地方特别多,某些地方又特别少,导致的在处理数据的时候,有些很快就处理完了,而有些又迟迟未能处理完,导致整体任务最终迟迟无法完成,这种现象就是数据倾斜。
针对mapreduce的过程来说就是,有多个reduce,其中有一个或者若干个reduce要处理的数据量特别大,而其他的reduce处理的数据量则比较小,那么这些数据量小的reduce很快就可以完成,而数据量大的则需要很多时间,导致整个任务一直在等它而迟迟无法完成。跑mr任务时常见的reduce的进度总是卡在99%,这种现象很大可能就是数据倾斜造成的。

11.2 数据倾斜产生的情况与原因

关键词情形后果
join其中一个表较小,但key集中分发都某一个或几个reduce上的数据远远高于平均值
group bygroup by 维度过小,某值的数量过多处理某值的reduce非常耗时
Count distinct某特殊值过多处理此特殊值的reduce耗时

产生数据倾斜的原因:
1、key分布不均匀
2、数据本身就不均匀
3、建表考虑不周全
4、某些SQL语句本身就有数据倾斜

11.3 数据倾斜解决方案

11.3.1 join

普通join与map join 的区别

11.3.1.1 运行时解决方案

set hive.auto.convert.join=true; //自动将common join转换为map join
set hive.mapjoin.smalltable.filesize=25000000 //设置小表不超过多大时开启 mapjoin 优化

set hive.optimize.skewjoin=true; //如果大表和大表进行join操作,则可采用skewjoin
set hive.skewjoin.key=100000; //当记录条数超过100000时采用skewjoin操作

对于skewjoin.key,在执行job时,将它们存入临时的HDFS目录。其它数据正常执行,对倾斜数据开启map join操作,对非倾斜值采取普通join操作,将倾斜数据集和非倾斜数据及进行合并操作。

11.3.1.2 编译期解决方案

hive.optimize.skewjoin.compiletime //如果建表语句元数据中指定了skew key,则使用set hive.optimize.skewjoin.compiletime=true开启skew join。

思路:
在建表的时候就需要告知给 hive,那个字段那个数据会发生数据倾斜的问题。hive在编译优化器, 直接设置对相对字段的相应值的优化方案–效率会更高效。
适用于: 明确知道表中有那些字段会出现数据倾斜的问题, 可以使用此优化。
可以通过如下建表语句指定SKEWED key:

  CREATE TABLE list_bucket_single (key STRING, value STRING)
    SKEWED BY (key) ON (1,5,6) [STORED AS DIRECTORIES];

11.3.2 group by

方案一:通过局部合并combiner解决

hive.map.aggr=true; //开启map端combiner

方案二:通过两个MRJob。

hive.groupby.skewindata=true; // group by 操作是否支持倾斜的数据

参考文章:hive.groupby.skewindata详解

11.3.3 Count Distinct

使用group by 代替。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值