一、测试环境搭建
1、建表(一个文件一张表)
二、分析
1、※※※※※业务※※※※※
2、根据业务找数据
3、数据分析(数据规模,特性,分布,关系)
4、技术选型
5、建模
6、在测试环境中模拟+验证解决方案
explain select …
select …检查数据分布,规模,倾斜(group count的方法检查)…
三、生产环境搭建(数仓)
1、设备采购
2、装机
- ha hadoop cluster
- NameNode
- SecondaryNameNode
- DataNode
- ResourceManager
- NodeManager
- Zookeeper
- Hive
- Hbase Cluster
3、环境配置
(1)常规配置:根据执行方案,做软配置。
(2)存储引擎:
set hive.execution.engine=mr/tez/impala;
Tez,job合并:多个job整合为一个DAG job;支持orc存储类型,orc是支持分割的
(3)确定数据源(HDFS | HBase | RDBMS)
(4)表类型:分区、分桶表
(5)建表并且导入数据
四、执行业务
生产环境执行计划
1、调优设置
- 少量小文件:本地化
set hive.exec.mode.local.auto=true;开启本地摩米士,默认false
set hive.exec.mode.local.auto.inputbytes.max=500000;设计文件最大字节数
set hive.exec.mode.local.auto.input.files.max=5;最大文件数:default 4
set mapred.reduce.tasks=1
- JVM重用:串行化(Map或Reduce)
set mapred.jb.reuse.jvm.num.tasks=5;默认为1
- 并行执行:非依赖关系的子查询可以并发执行:不需要并发时关闭
set hive.exec.parallel=true;默认false
set hive.exec.parallel.tread.number=16;默认为8
- 开启小文件合并(HiveInputFormat )
set hive.merge.mapfiles=true;在maponly的任务结束时合并小文件
set hive.merge.mapred.files=true;在true时MR的任务结束时合并小文件
set hive.merge.size.per.task=250*1000*1000;合并文件的大小设置
set mapred.max.split.size=256*1024*1024;最大切片值
set mapred.min.split.size=128*1024*1024;最小切片值
set mapred.min.split.size.per.node=1;一个节点上split的最少值
set hive.input.formatorg.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
-
LLAP:内存中读取缓存(I/O,cacheing,query中部分片段的执行),辅助增强当前引擎的性能,不代替引擎,目前只支持Tez
- 在每个DataNode增加常驻进程LLAP,大部分small/short queries被此进程直接处理
- 大型任务(比如在reduce阶段中的大型shuffle)则仍然被标准的yarn containers处理
- LLAP进程也可以被其他应用访问,特别是在以文件为中心(file-centric)的关系型数据处理(如join,多表查询)中
-
合理控制maptask reducetask的数量
- MapTask的数量由以下因素决定
-
mapred-site.xml 切片的大小配置 :
- minSplitSize = mapred.min,split.size
- maxSplitSize = mapred.max.split.size
-
hdfs-site.xml 块的大小配置,默认是128Mb
- blockSize=dfs.blocksize
-
公式:
- InputSplitSize = Math.max(minSplitSize,Math.min(maxSplitSize,blockSize))
- maptaskCount = Math.ceil(fileSize/inputSplitSize)
-
- MapTask的数量由以下因素决定
-
reducetask的数量配置
- reducetask的数量一般在job中设置
- job.setNumReduceTasks(int N);
- set mapred.reduce.tasks=15;
如果未在job中设置,默认情况
- reducetask的数量一般在job中设置
默认:
set hive.exec.reduces.bytes.per.reducer=1G;默认
set hive.exec.reduces.max=999;默认999
reducetaskCount=Math.min(maxReduceCount,fileSize/bytePerReduce);
- FETCH:默认开启
- 简单查询(没有函数,order by等)、tablesample等,不走MapReduce
set hive.fetch.task.conversion=minimal/more;
2、数据倾斜
(1)大表+小表倾斜
采用mapjoin把小文件放在缓存中在map端进行join操作,避免shuffle过程reduce端的join
set hive.auto.convert.join=true
(2)内容倾斜
有数据倾斜的时候进行负载均衡(默认是false): hive.groupby.skewindata = true,生成的查询计划会有两个MR,第一个MR将key随机分发到不同的reduce达到负载均衡;第二个MR将相同的key发到对应的reduce中完成数据聚合。防止数据倾斜:
set hive.optmize.skewjoin=true;
set hive.skewjoin.key=500000;
set hive.skewjoin.mapjoin.map.tasks=10000;
set hive.skewjoin.mapjoin.min.split=335544332;
select a.*,b.* from a join b on a.userId=b.userId;
(a)join关联时有null值
select a.*,b.* from a join b on case when a.userId is null then concat("rand",rand()) else a.userId end=b.userId;
- 也可以把null单独写一个查询,写两个查询union
(b)关联时数据类型不同
- a中userId为int,b中userId字段既有string类型也int类型
- 默认的Hash操作会按int型的id来进行分配,这样会导致所有string类型id的记录都分配到一个Reducer中
select a.*,b.* from a join b on cast(a.userId as string)=cast(b.userId as string);
(c)map端缓慢,输入数据文件多,大小不均匀
set hive.merge.mapfiles=true;
set hive.map.aggr=true;#Combiner
- group by优化
set hive.groupby.skewindata=true;
set hive.groupby.mapaggr.checkinterval=100000;#Map端进行聚合操作的条目数
set mapred.map.task=n;#单个文件稍大于配置的block块的大小,或者map端的计算复杂/计算量大
(d)cout(distinct FIELD)如果FIELD数量特别大
select a,count(distinct b) from t group by a;
select a,sum(1) from (select a,b from t group by a,b)T group by a;
3、计划检查
explain select …
select …