Hive性能优化(全面)

  • 时间:
  • 浏览:1

肯能子查询里头有 COUNT(DISTINCT)操作,直接去 GROUP BY 将达不到业务目标。这时采用 临时表消灭 COUNT(DISTINCT)作业不但能出理 倾斜问题报告 ,还能有效减少 jobs。

调优结果显示:针对千万级别的广告位表,由原先 5 个 Job 共 15 分钟,分解为 2 个 job 另另1个 8-10 分钟,另另1个3分钟。

问题报告 :比如推广效果表要和商品表关联,效果表中的 auction_id 列既有 32 为字符串商 品 id,也有数字 id,和商品表关联得到商品的信息。

在实施此项查询中,Q 表有 5 列(a,b,c,d,e),Hive 只读取查询逻辑中真实需用 的 3 列 a、b、e,而忽略列 c,d;原先做节省了读取开销,后面 表存储开销和数据整合开销。

阿里巴巴开源大数据技术团队成立Apache Spark中国技术社区,定期推送精彩案例,技术专家直播,问答区近万人Spark技术同学在线提问答疑,只为营造纯粹的Spark氛围,欢迎钉钉扫码加入!

统计每日IP(改造)

作者:浪尖

原文链接本文转载自公众号:Spark学习技巧

而接下来,亲戚亲戚亲们 心中应该会有或多或少问题报告 ,影响性能的根源是哪几种?

原先写的好处:1 个 MapReduce 作业,商品表只读一次,推广效果表只读取一次。把 你你你什儿 SQL 换成 Map/Reduce 代码话语,Map 的随后,把 a 表的记录打上标签 a,商品表记录 每读取三根,打上标签 b,变成另另1个对,<(b,数字 id),value>,<(b,字符串 id),value>。

INSERT OVERWRITE TABLE s_dw_tanx_adzone_uv PARTITION (ds=20120329)SELECT 20120329 AS thedate,adzoneid,COUNT(DISTINCT acookie) AS uv FROM s_ods_log_tanx_pv t WHERE t.ds=20120329 GROUP BY adzoneid

观察Hadoop出理 数据的过程,多少显著的形态:

对开源大数据和感兴趣的同学需用加小编微信(下图二维码,备注“进群”)进入技术交流微信群。

hive.mapjoin.size.key = 1000

用于设置合并属性的参数有:

Hive 对 union all 的优化的形态:对 union all 优化只局限于非嵌套查询。

SQL 具有普适性,随后 SQL 通用的优化方案在 Hadoop 分布式计算措施中也需用达到效果。

随后商品表的 HDFS 读取只会是一次。

调优结果:经过测试,并未老是出现 union all 的 Hive Bug,数据是一致的。MapReduce 的 作业数由 3 减少到 1。

问题报告 :不同数据类型 id 的关联会产生数据倾斜问题报告 。

面对哪几种问题报告 ,亲戚亲戚亲们 能有哪几种有效的优化手段呢?下面列出或多或少在工作有效可行的优化手段:

亲戚亲戚亲们 知道文件数目小,容易在文件存储端造成瓶颈,给 HDFS 带来压力,影响出理 效率。对此,需用通过合并Map和Reduce的结果文件来消除原先的影响。

测试数据:169857条

Join 操作在 Map 阶段完成,不再需用Reduce,前提条件是需用的数据在 Map 的过程中需用访问到。比如查询:

hive性能优化时,把HiveQL当做M/R程序来读,即从M/R的运行宽度来考虑优化性能,从更底层思考如保优化运算性能,而不仅仅局限于逻辑代码的替换层面。

CREATE TABLE ip_2014_12_29 AS SELECT COUNT(1) AS IP FROM (SELECT DISTINCT ip from logdfs WHERE logdate=’2014_12_29′) tmp;

查询话语若将“subq.prtn=100”条件放满子查询中更为高效,需用减少读入的分区 数目。Hive 自动执行你你你什儿 裁剪优化。

需用在查询的过程中减少并并不的分区。累似 ,若有以下查询:

出理 措施:Hive SQL 性能会比较好

t1 要花费 另另1个目录,t2 要花费 另另1个目录,对 Map/Reduce 程序来说,t1,t2 需用作为 Map/Reduce 作业的 mutli inputs。这需用通过另另1个 Map/Reduce 来出理 你你你什儿 问题报告 。Hadoop 的 计算框架,不怕数据多,就怕作业数多。

但肯能换成是或多或少计算平台如 Oracle,那就不一定了,肯能把大的输入拆成另另1个输入, 分别排序汇总后 merge(若果另另1个子排序是并行话语),是有肯能性能更优的(比如希尔排 序比冒泡排序的性能更优)。

如下所示:常用措施

出理 措施:把数据类型转换成字符串类型

出理 措施 2 如下所示:函数过滤 null

Hive 在读数据的随后,需用只读取查询中所需用用到的列,而忽略其它列。累似 ,若有以下查询:

耗时:46.833 seconds

调优结果显示:数据表出理 由 1 小时 100 分钟经代码调整后需用在 20 分钟内完成。

出理 措施 2

RAC(Real Application Cluster)真正应用集群就像百公里机动灵活的小货车,响应快;Hadoop就像吞吐量巨大的轮船,启动开销大,肯能每次只做小数量的输入输出,利用率肯能很低。随后用好Hadoop的首要任务是增大每次任务所搭载的数据量。

优化时,把hive sql当做mapreduce程序来读,会有意想不到的惊喜。理解hadoop的核心能力,是hive优化的根本。这是你你你什儿 年来,项目组所有成员宝贵的经验总结。

出理 措施 1

比分别过滤数字 id,字符串 id 若果分别和商品表关联性能要好。

下面给出措施1的思路,实现步骤如下:

job 数是 2,减少一半,若果两次 Map/Reduce 比 COUNT(DISTINCT)效率更高。

肯能 Join 的条件不相同,比如:

首先,亲戚亲戚亲们 来看看Hadoop的计算框架形态,在此形态下会衍生哪几种问题报告 ?

从业务逻辑上说,子查询内的 GROUP BY 为什么在么在会么会就看显得多余(功能上的多余,除非有 COUNT(DISTINCT)),肯能也有肯能 Hive Bug 肯能性能上的考量(原先老是出现肯能不执行子查询 GROUP BY,数据得不到正确的结果的 Hive Bug)。随后你你你什儿 Hive 按经验转换成如下所示:

亲戚亲戚亲们 知道了性能低下的根源,同样,亲戚亲戚亲们 也需用从Hive的配置解读去优化。Hive系统内控 已针对不同的查询预设定了优化措施,用户需用通过调整配置进行控制, 以下举例介绍偏离 优化的策略以及优化控制选项。

此处需用设定 hive.groupby.skewindata,当选项设定为 true 是,生成的查询计划有两 个 MapReduce 任务。在第另另1个 MapReduce 中,map 的输出结果集合会随机分布到 reduce 中, 每个 reduce 做偏离 聚合操作,并输出结果。原先出理 的结果是,相同的 Group By Key 有可 能下发到不同的 reduce 中,从而达到负载均衡的目的;第十个 MapReduce 任务再根据预处 理的数据结果按照 Group By Key 分布到 reduce 中(你你你什儿 过程需用保证相同的 Group By Key 分布到同另另1个 reduce 中),最后完成最终的聚合操作。

优化时把握整体,单个作业最优不如整体最优。

统计每日IP

后面 代码运行会有 5 个 jobs。加入先 JOIN 生存临时表话语 t5,若果 UNION ALL,会变成 2 个 jobs。

裁剪所对应的参数项为:hive.optimize.cp=true(默认值为真)

在编写蕴藏 join 操作的代码话语时,应该将条目少的表/子查询放满 Join 操作符的左边。肯能在 Reduce 阶段,处在 Join 操作符左边的表的内容会被加载进内存,载入条目较少的表 需用有效减少 OOM(out of memory)即内存溢出。随后对于同另另1个 key 来说,对应的 value 值小的放前,大的放后,这便是“小表放前”原则。若三根话语蕴藏多个 Join,措施 Join 的条件相同是与否,有不同的出理 措施。

场景:有一张 user 表,为卖家每天收到表,user_id,ds(日期)为 key,属性有主营类目,指标有交易金额,交易笔数。每天要取前10天的总收入,总笔数,和最近一天的主营类目。

一张表 s8 的日志,每个商品三根记录,要和商品表关联。但关联却碰到倾斜的问题报告 。s8 的日志蕴藏 32 为字符串商品 id,也有数值商品 id,日志中类型是 string 的,但商品中的 数值 id 是 bigint 的。猜想问题报告 的是因为 是把 s8 的商品 id 转成数值 id 做 hash 来分配 Reduce, 随后字符串 id 的 s8 日志,都到另另1个 Reduce 上了,出理 的措施验证了你你你什儿 猜测。

需用在 Map 阶段完成 Join.

SELECT a,b FROM q WHERE e<10;

如下所示:优化措施

这里需用修改的参数为:

相关的参数为:

第二步:汇总 10 天的总交易金额,交易笔数,存入临时表 t2。

主要由另另1个属性来决定:

测试结果表名:明显改造后的话语比随后耗时,这是肯能改造后的话语有另另1个SELECT,多了另另1个job,原先在数据量小的随后,数据越多再处在倾斜问题报告 。

第三步:关联 t1,t2,得到最终的结果。

关于COUNT(DISTINCT)的数据倾斜问题报告 不到一概而论,要依情况报告而定,下面是我测试的一组数据:

调优结果:原先肯能数据倾斜是因为 运行时长超过 1 小时,出理 措施 1 运行每日平均时长 25 分钟,出理 措施 2 运行的每日平均时长在 20 分钟左右。优化效果很明显。

问题报告 :日志中常会老是出现信息丢失,比如每日约为 20 亿的全网日志,其中的 user_id 为主 键,在日志下发过程中会丢失,老是出现主键为 null 的情况报告,肯能取其中的 user_id 和 bmw_users 关联,就会碰到数据倾斜的问题报告 。是因为 是 Hive 中,主键为 null 值的项会被当做相同的 Key 而分配进同另另1个计算 Map。

进行GROUP BY操作需用用注意一下几点:

多表 union all 会优化成另另1个 job。

hive.map.aggr=true(用于设定是与否在 map 端进行聚合,默认值为真) hive.groupby.mapaggr.checkinterval=10000(用于设定 map 端进行聚合操作的条目数)

SELECT FROM (SELECTT 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;

计算 uv 的随后,老是会用到 COUNT(DISTINCT),但在数据比较倾斜的随后 COUNT(DISTINCT) 会先要。这需用用尝试用 GROUP BY 改写代码计算 uv。

熟练地使用 SQL,能写出高效率的查询话语。

出理 措施 1:user_id 为空的不参与关联,子查询过滤 null

在使用写有 Join 操作的查询话语时有三根原则:应该将条目少的表/子查询放满 Join 操作符的左边。是因为 是在 Join 操作的 Reduce 阶段,处在 Join 操作符左边的表的内容会被加载进内存,将条目少的表放满左边,需用有效减少处在 OOM 错误的几率。对于三根话语蕴藏多个 Join 的情况报告,肯能 Join 的条件相同,比如查询:

hive.mapjoin.cache.numrows = 1000

CREATE TABLE ip_2014_12_29 AS SELECT COUNT(DISTINCT ip) AS IP FROM logdfs WHERE logdate=’2014_12_29′;

Hadoop的核心能力是parition和sort,因而这也是优化的根本。

事实上并也有所有的聚合操作都需用在reduce偏离 进行,随后聚合操作需用先在Map端进行偏离 聚合,若果reduce端得出最终结果。

在工作中亲戚亲戚亲们 总结出:方案 2 的开销等于方案 1 的第二步的开销,性能提升,由原有的 25 分钟完成,缩短为 10 分钟以内完成。节省了另另1个临时表的读写是另另1个关键是因为 ,你你你什儿 措施也适用于 Oracle 中的数据查找工作。

示例 1:子查询内有 group by

亲戚亲戚亲们 在工作中总结出:出理 措施2比出理 措施1效果更好,不但IO少了,若果作业数也少了。出理 措施1中log读取两次,job 数为2。出理 措施2中 job 数是1。你你你什儿 优化适合无效 id(比如-99、 ‘’,null 等)产生的倾斜问题报告 。把空值的 key 变成另另1个字符串换成随机数,就能把倾斜的 数据分到不同的Reduce上,从而出理 数据倾斜问题报告 。肯能空值不参与关联,即使分到不同 的 Reduce 上,若果会影响最终的结果。附上 Hadoop 通用关联的实现措施是:关联通过二次排序实现的,关联的列为 partion key,关联的列和表的 tag 组成排序的 group key,根据 pariton key分配Reduce。同一Reduce内根据group key排序。

hive.join.emit.interval = 100

肯能reduce越多再 :肯能数据量很大,会是因为 你你你什儿 reduce异常的慢,从而是因为 你你你什儿 任务不到开始英文,也有肯能会OOM 2、肯能reduce越多再 : 产生的小文件越多再 ,合并起来代价太高,namenode的内存占用也会增大。肯能亲戚亲戚亲们 不指定mapred.reduce.tasks, hive会自动计算需用多少个reducer。

第一步:利用分析函数,取每个 user_id 最近一天的主营类目,存入临时表 t1。

分区参数为:hive.optimize.pruner=true(默认值为真)

耗时:24.1005 seconds

调优结果:千万级别的类目表,member 表,与 10 亿级得商品表关联。原先 1963s 的任务经过调整,1152s 即完成。

最后得出的结论是:避实就虚,用 job 数的增加,输入量的增加,占用更多存储空间,充分利用空闲 CPU 等各种措施,分解数据倾斜造成的负担。

Map-Reduce 的任务数目和 Join 操作的数目是对应的,上述查询和以下查询是等价的: