大数据性能优化

上传人:ta****u 文档编号:182792612 上传时间:2023-01-28 格式:DOCX 页数:19 大小:35.88KB
收藏 版权申诉 举报 下载
大数据性能优化_第1页
第1页 / 共19页
大数据性能优化_第2页
第2页 / 共19页
大数据性能优化_第3页
第3页 / 共19页
资源描述:

《大数据性能优化》由会员分享,可在线阅读,更多相关《大数据性能优化(19页珍藏版)》请在装配图网上搜索。

1、Hive 性能优化1. 概述本人在工作中总结Hive的常用优化手段和在工作中使用Hive出现 的问题。下面开始本篇文章的优化介绍。2. 介绍首先,我们来看看hadoop的计算框架特性,在此特性下会衍生哪些问题?数据量大不是问题,数据倾斜是个问题。jobs 数比较多的作业运行效率相对比较低,比如即使有几百行 的表,如果多次关联多次汇总,产生十几个jobs,耗时很长。原因是 map reduce 作业初始化的时间是比较长的。sum,count,max,min等 UDAF,不怕数据倾斜问题,hadoop 在 map 端的汇总合并优化,使数据倾斜不成问题。count(distinct ),在数据量大的

2、情况下,效率较低,如果是多count(distinet )效率更低,因为 count(distinct)是按 group by 字段分组, 按 distinct 字段排序,一般这种分布方式是很倾斜的。举个例子:比如 男uv,女uv,像淘宝一天30亿的pv,如果按性别分组,分配2个reduce, 每个 reduce 处理 15亿数据。面对这些问题,我们能有哪些有效的优化手段呢?下面列出一些在 工作有效可行的优化手段:好的模型设计事半功倍。解决数据倾斜问题。减少 job 数。设置合理的 map reduce 的 task 数,能有效提升性能。(比如,10w+级别的计算,用160个reduce,那是

3、相当的浪费,1个足够)。了解数据分布,自己动手解决数据倾斜问题是个不错的选择。 set hive.groupby.skewi ndata二true这是通用的算法优化,但算法优化有时 不能适应特定业务背景,开发人员了解业务,了解数据,可以通过业务 逻辑精确有效的解决数据倾斜问题。数据量较大的情况下,慎用count(distinct), count(distinct)容易 产生倾斜问题。对小文件进行合并,是行至有效的提高调度效率的方法,假如 所有的作业设置合理的文件数,对云梯的整体调度效率也会产生积极的 正向影响。优化时把握整体,单个作业最优不如整体最优。而接下来,我们心中应该会有一些疑问,影响性

4、能的根源是什么?3. 性能低下的根源hive 性能优化时,把 HiveQL 当做 M/R 程序来读,即从 M/R 的运行 角度来考虑优化性能,从更底层思考如何优化运算性能,而不仅仅局限 于逻辑代码的替换层面。RAC (Real Application Cluster)真正应用集群就像一辆机动灵活的小 货车,响应快;Hadoop就像吞吐量巨大的轮船,启动开销大,如果每 次只做小数量的输入输出,利用率 将会很低。所以用好Hadoop的首要 任务是增大每次任务所搭载的数据量。Hadoop的核心能力是parition和sort,因而这也是优化的根本。观察Hadoop处理数据的过程,有几个显著的特征:数

5、据的大规模并不是负载重点,造成运行压力过大是因为运行 数据的倾斜。jobs 数比较多的作业运行效率相对比较低,比如即使有几百行 的表,如果多次关联对此汇总,产生几十个jobs,将会需要30分钟以 上的时间且大部分时间被用于作业分配,初始化和数据输出。M/R作业 初始化的时间是比较耗时间资源的一个部分。在使用SUM, COUNT,MAX,MIN等UDAF函数时,不怕数据 倾斜问题, Hadoop 在 Map 端的汇总合并优化过,使数据倾斜不成问题。COUNT(DISTINCT)在数据量大的情况下,效率较低,如果多COUNT(DISTINCT)效率更低,因为 COUNT(DISTINCT)是按 G

6、ROUP BY字段 分组,按DISTINCT字段排序,一般这种分布式方式是很倾斜的;比如: 男UV,女UV,淘宝一天30亿的PV,如果按性别分组,分配2个reduce, 每个 reduce 处理 15 亿数据。数据倾斜是导致效率大幅降低的主要原因,可以采用多一次 Map/Reduce 的方法, 避免倾斜。最后得出的结论是:避实就虚,用 job 数的增加,输入量的增加, 占用更多存储空间,充分利用空闲 CPU 等各种方法,分解数据倾斜造 成的负担。4. 配置角度优化我们知道了性能低下的根源,同样,我们也可以从Hive的配置解读 去优化。Hive系统内部已针对不同的查询预设定了优化方法,用户可以

7、通过调整配置进行控制, 以下举例介绍部分优化的策略以及优化控制 选项。4.1 列裁剪Hive 在读数据的时候,可以只读取查询中所需要用到的列,而忽略 其它列。 例如,若有以下查询:SELECT a,b FROM q WHERE e10;在实施此项查询中,Q表有5列(a,b, c, d, e), Hive只读取 查询逻辑中真实需要的3列a、b、e,而忽略列c,d;这样做节省 了读取开销,中间表存储开销和数据整合开销。裁剪所对应的参数项为:hive.optimize.cp二true (默认值为真)4.2 分区裁剪可以在查询的过程中减少不必要的分区。 例如,若有以下查询:SELECT*FROM (S

8、ELECTT a1,COUNT(1) FROM T GROUPBY a1) subqWHERE subq.prtn=100; #(多余分区) SELECT*FROM T1 JOIN(SELECT*FROM T2) subq ON (T1.a1=subq.a2) WHERE subq.prtn=100;查询语句若将“ subq.prt n=100条件放入子查询中更为高效,可以减少读入的分区 数目。 Hive 自动执行这种裁剪优化。分区参数为:hive.optimize.pruner二true (默认值为真)4.3JOIN 操作在编写带有 join 操作的代码语句时,应该将条目少的表/子查询放 在

9、 Join 操作符的左边。 因为在 Reduce 阶段,位于 Join 操作符左边 的表的内容会被加载进内存,载入条目较少的表 可以有效减少 OOM(out of memory)即内存溢出。所以对于同一个key来说,对应的value 值小的放前,大的放后,这便是“小表放前”原则。 若一条语句中有多 个Join,依据Join的条件相同与否,有不同的处理方法。4.3.1JOIN 原则在使用写有 Join 操作的查询语句时有一条原则:应该将条目少的表 /子查询放在 Join 操作符的左边。原因是在 Join 操作的 Reduce 阶段, 位于 Join 操作符左边的表的内容会被加载进内存,将条目少的

10、表放在 左边,可以有效减少发生 OOM 错误的几率。对于一条语句中有多个 Join 的情况,如果 Join 的条件相同,比如查询:INSERT OVERWRITE TABLE pv_users SELECT pv.pageid, u.age FROM page_view p JOINuser u ON (pv.userid = u.userid) JOIN newuser x ON (u.userid = x.userid);如果 Join 的 key 相同,不管有多少个表,都会则会合并为一 个 Map-Reduce一个 Map-Reduce 任务,而不是 n 个在做 OUTER JOIN 的

11、时候也是一样如果 Join 的条件不相同,比如:INSERT OVERWRITE TABLE pv_users SELECT pv.pageid, u.age FROM page_view p JOINuser u ON (pv.userid = u.userid) JOIN newuser x on (u.age = x.age);Map-Reduce 的任务数目和 Join 操作的数目是对应的,上述查询和 以下查询是等价的:INSERT OVERWRITE TABLE tmptable SELECT*FROM page_view pJOINuser u ON (pv.userid = u.

12、userid); INSERT OVERWRITE TABLE pv_usersSELECT x.pageid, x.age FROM tmptable x JOIN newuser y ON (x.age = y.age);Join操作在Map阶段完成,不再需要Reduce,前提条件是需要的数据在 Map 的过程中可以访问到。比如查询:INSERT OVERWRITE TABLE pv_users SELECT/*+ MAPJOIN(pv) */pv.pageid, u.age FROM page_view pv JOINuser u ON (pv.userid = u.userid);可以

13、在Map阶段完成Join,如图所示:page_viewfitie“1007*1 11Hash Tablevalue100200E FOOI 12100-2 -i i3相关的参数为:PVUSSLSpagr?ci_id122-SI25ummhive.join.emit.interval = 1000hive.mapjoin.size.key = 10000hive.mapjoin.cache.numrows = 100004.5GROUP BY 操作进行GROUP BY操作时需要注意一下几点:事实上并不是所有的聚合操作都需要在reduce部分进行,很多聚合 操作都可以先在Map端进行部分聚合,然后

14、reduce端得出最终结果。这里需要修改的参数为:hive.map.aggr二true(用于设定是否在map端进行聚合,默认值为真) hive.groupby.mapaggr.checkinterval=100000(用于设定 map 端进行聚合 操作的条目数)有数据倾斜时进行负载均衡此处需要设定hive.groupby.skew in data,当选项设定为true是,生 成的查询计划有两 个 MapReduce 任务。在第一个 MapReduce 中, map 的输出结果集合会随机分布到 reduce 中, 每个 reduce 做部分 聚合操作,并输出结果。这样处理的结果是,相同的 Gro

15、up By Key 有 可 能分发到不同的 reduce 中,从而达到负载均衡的目的;第二个 MapReduce 任务再根据预处 理的数据结果按照 Group By Key 分布到 reduce 中(这个过程可以保证相同的 Group By Key 分布到同一个 reduce 中),最后完成最终的聚合操作。4.6 合并小文件我们知道文件数目小,容易在文件存储端造成瓶颈,给 HDFS 带来 压力,影响处理效率。对此,可以通过合并Map和Reduce的结果文件 来消除这样的影响。用于设置合并属性的参数有:是否合并Map输出文件:hive.merge.mapfiles二tr(默认值为真)是否合并 R

16、educe 端输出文件:hive.merge.mapredfiles=faBSe 认值为假)合并文件的大小:hive.merge.size.per.task=256*1000*(默0认值为 256000000)5.程序角度优化5.1熟练使用SQL提高查询熟练地使用SQL,能写出高效率的查询语句。场景:有一张user表,为卖家每天收到表,user_id ds (日期)为 key,属性有主营类目,指标有交易金额,交易笔数。每天要取前10天 的总收入,总笔数,和最近一天的主营类目。 解决方法1如下所示:常用方法INSERT OVERWRITE TABLE t1SELECTuser_id,substr

17、(MAX(CONCAT(ds,cat),9) AS main_cat) FROM users WHERE ds=20120329/20120329 为日期列的值,实际代码中可以用函数 表示出当天日期 GROUPBYuser_id; INSERT OVERWRITE TABLE t2 SELECTuser_id,sum(qty) AS qty,SUM(amt) AS amt FROM users WHERE dsBETWEEN20120301AND20120329GROUPBYuser_idSELECT t1.user_id,t1.main_cat,t2.qty,t2.amt FROM t1 J

18、OIN t2 ON t1.user_id=t2.user_id下面给出方法1 的思路,实现步骤如下:第一步:利用分析函数,取每个 user_id 最近一天的主营类目,存 入临时表 t1。第二步:汇总 10 天的总交易金额,交易笔数,存入临时表 t2。第三步:关联tl, t2,得到最终的结果。解决方法 2如下所示:优化方法SELECTuser_id,substr(MAX(CONCAT(ds,cat),9) AS main_cat,SUM(qty),SUM(amt) FROM users WHERE ds BETWEEN20120301AND20120329GROUPBYuser_id在工作中我们

19、总结出:方案 2 的开销等于方案 1 的第二步的开销, 性能提升,由原有的 25 分钟完成,缩短为 10 分钟以内完成。节省了 两个临时表的读写是一个关键原因,这种方式也适用于Oracle中的数 据查找工作。SQL 具有普适性,很多 SQL 通用的优化方案在 Hadoop 分布式计算 方式中也可以达到效果。问题:日志中常会出现信息丢失,比如每日约为 20 亿的全网日志, 其中的 user_id 为主 键,在日志收集过程中会丢失,出现主键为 null 的情况,如果取其中的 user_id 和 bmw_users 关联,就会碰到数据倾 斜的问题。原因是 Hive 中,主键为 null 值的项会被当

20、做相同的 Key 而分配进同一个计算 Map。解决方法 1:user_id 为空的不参与关联,子查询过滤 nullSELECT*FROMlog a JOIN bmw_users b ON a.user_idISNOTNULLAND a.user_id=b.user_idUNIONAllSELECT*FROMlog a WHERE a.user_idISNULL解决方法 2 如下所示:函数过滤 nullSELECT*FROMlog a LEFTOUTERJOIN bmw_users b ONCASEWHEN a.user_idISNULLTHEN CONCAT(dp_hive,RAND() EL

21、SE a.user_idEND=b.user_id;调优结果:原先由于数据倾斜导致运行时长超过 1 小时,解决方法 1 运行每日平均时长 25 分钟,解决方法 2 运行的每日平均时长在 20 分钟左右。优化效果很明显。我们在工作中总结出:解决方法2比解决方法1效果更好,不但10 少了,而且作业数也少了。解决方法1中log读取两次,job数为2。 解决方法2中job数是1。这个优化适合无效id (比如-99、,null等) 产生的倾斜问题。把空值的 key 变成一个字符串加上随机数,就能把倾斜的数据分到不同的Reduce上,从而解决数据倾斜问题。因为空值 不参与关联,即使分到不同的Reduce上

22、,也不会影响最终的结果。 附上Hadoop通用关联的实现方法是:关联通过二次排序实现的,关联 的列为partion key关联的列和表的tag组成排序的group key根据 pari ton ke分配 Reduce。同一 Reduce 内根据 group keyf排 序。5.3不同数据类型关联产生的倾斜问题问题:不同数据类型id的关联会产生数据倾斜问题。张表s8的日志,每个商品一条记录,要和商品表关联。但关联却 碰到倾斜的问题。s8的日志中有32为字符串商品id也有数值商品 id日志中类型是st ring的,但商品中的数值id是bigint的。猜想 问题的原因是把s8的商品id转成数值id做

23、hash来分配Reduce, 所以字符串id的s8日志,都到一个Reduce上了,解决的方法验证 了这个猜测。解决方法:把数据类型转换成字符串类型SELECT*FROM s8_log a LEFTOUTERJOIN r_auction_auctions b ONa.auction_id=CASE(b.auction_id AS STRING)调优结果显示:数据表处理由1 小时30 分钟经代码调整后可以在 20 分钟内完成。5.4利用Hive对UNION ALL优化的特性多表 union all 会优化成一个 job。问题:比如推广效果表要和商品表关联,效果表中的 auction_id 列 既有

24、32为字符串商品id,也有数字id,和商品表关联得到商品的信 息。解决方法:Hive SQL性能会比较好SELECT*FROM effect a JOIN (SELECT auction_id AS auction_id FROM auctions UNIONAllSELECT auction_string_id AS auction_id FROM auctions) b ON a.auction_id=b.auction_id比分别过滤数字id,字符串id然后分别和商品表关联性能要好。这样写的好处:1 个 MapReduce 作业,商品表只读一次,推广效果 表只读取一次。把这个SQL换成M

25、ap/Reduce代码的话,Map的时 候,把a表的记录打上标签a,商品表记录 每读取一条,打上标签b, 变成两个vkey,value对,v(b,数字 id),value, (b,字符串 id),value。所以商品表的 HDFS 读取只会是一次。5.5解决Hive对UNION ALL优化的短板Hive 对 union all 的优化的特性:对 union all 优化只局限于非嵌套 查询。消灭子查询内的 group by示例 1:子查询内有 group bySELECT*FROM (SELECT*FROM t1 GROUPBY c1,c2,c3UNIONALLSELECT*FROM t2 G

26、ROUPBY c1,c2,c3)t3 GROUPBY c1,c2,c3从业务逻辑上说,子查询内的 GROUP BY 怎么都看显得多余(功能 上的多余,除非有COUNT(DISTINCT),如果不是因为Hive Bug或者 性能上的考量(曾经出现如果不执行子查询GROUP BY,数据得不到正 确的结果的Hive Bug)。所以这个Hive按经验转换成如下所示:SELECT*FROM (SELECT*FROM t1 UNIONALLSELECT*FROM t2)t3GROUPBY c1,c2,c3调优结果:经过测试,并未出现union all的Hive Bug,数据是一致 的。 MapReduce

27、 的 作业数由 3 减少到 1。t1 相当于一个目录, t2 相当于一个目录,对 Map/Reduce 程序来 说,t1,t2可以作为Map/Reduce作业的mutli in puts。这可以通过一 个 Map/Reduce 来解决这个问题。 Hadoop 的 计算框架,不怕数据多 就怕作业数多。但如果换成是其他计算平台如Oracle,那就不一定了,因为把大的 输入拆成两个输入,分别排序汇总后merge (假如两个子排序是并行 的话),是有可能性能更优的(比如希尔排 序比冒泡排序的性能更优)。消灭子查询内的 COUNT(DISTINCT), MAX, MIN。SELECT*FROM (SEL

28、ECT*FROM t1 UNIONALLSELECT c1,c2,c3 COUNT(DISTINCT c4) FROM t2 GROUPBY c1,c2,c3) t3 GROUPBY c1,c2,c3;由于子查询里头有COUNT(DISTINCT臊作,直接去GROUP BY将达 不到业务目标。这时采用临时表消灭COUNT(DISTINCT)作业不但能解 决倾斜问题,还能有效减少 jobs。INSERT t4 SELECT c1,c2,c3,c4 FROM t2 GROUPBY c1,c2,c3; SELECT c1,c2,c3,SUM(income),SUM(uv) FROM (SELECT

29、c1,c2,c3,income,0AS uv FROM t1 UNIONALLSELECT c1,c2,c3,0AS income,1AS uv FROM t2) t3 GROUPBY c1,c2,c3;job 数是 2,减少一半,而且两次 Map/Reduce 比 COUNT(DISTINCT) 效率更高。调优结果:千万级别的类目表, member 表,与 10 亿级得商品表 关联。原先 1963s 的任务经过调整, 1152s 即完成。消灭子查询内的 JOINSELECT*FROM (SELECT*FROM t1 UNIONALLSELECT*FROM t4 UNIONALLSELECT*

30、FROM t2 JOIN t3 ON t2.id=t3.id) x GROUPBY c1,c2;上面代码运行会有5个jobs。加入先JOIN生存临时表的话t5, 然后UNION ALL,会变成2个jobs。INSERT OVERWRITE TABLE t5 SELECT*FROM t2 JOIN t3 ON t2.id=t3.id; SELECT*FROM (t1 UNIONALL t4 UNIONALL t5);调优结果显示:针对千万级别的广告位表,由原先 5 个 Job 共 15 分钟,分解为 2 个 job 一个 8-10 分钟,一个 3 分钟。5.6GR0UP BY 替代 COUNT(

31、DISTINCT)达到优化效果计算uv的时候,经常会用到COUNT(DISTINCT),但在数据比较倾斜 的时候COUNT(DISTINCT)会比较慢。这时可以尝试用GROUP BY改写 代码计算 uv。原有代码INSERT OVERWRITE TABLE s_dw_tanx_adzone_uv PARTITION (ds=20120329) SELECT20120329AS thedate,adzoneid,COUNT(DISTINCT acookie) AS uv FROM s_ods_log_tanx_pv t WHERE t.ds=20120329GROUPBY adzoneid关于C

32、OUNT(DISTINCT)的数据倾斜问题不能一概而论,要依情况而定,下面是我测试的一组数据:测试数据:169857条#统计每日 IP CREATETABLE ip_2014_12_29 ASSELECTCOUNT(DISTINCT ip) AS IP FROM logdfs WHERE logdate=2014_12_29; 耗时:24.805 seco nds #统计每日 IP (改造)CREATETABLE ip_2014_12_29ASSELECTCOUNT(1) AS IP FROM (SELECTDISTINCT ip from logdfs WHERE logdate=2014_

33、12_29) tmp; 耗时:46.833 seconds测试结果表名:明显改造后的语句比之前耗时,这是因为改造后的 语句有2个SELECT,多了一个job,这样在数据量小的时候,数据不会 存在倾斜问题。6.优化总结优化时,把hive sql当做mapreduce程序来读,会有意想不到的惊喜。 理解 hadoop 的核心能力,是 hive 优化的根本。这是这一年来,项目组 所有成员宝贵的经验总结。长期观察hadoop处理数据的过程,有几个显著的特征:不怕数据多,就怕数据倾斜。对 jobs 数比较多的作业运行效率相对比较低,比如即使有几百行的表,如果多次 关联多次汇总,产生十几个jobs,没半小

34、时是跑不完的。map reduce作业初始化的时间是比 较长的。对 sum, count 来说,不存在数据倾斜问题。对 count(distinct ),效率较低,数据量一多,准出问题,如果是多 count(distinct ) 效率更低。优化可以从几个方面着手:好的模型设计事半功倍。解决数据倾斜问题。 减少 job 数。设置合理的map reduce的task数,能有效提升性能。(比如,10w+级别的计算, 用160个reduce,那是相当的浪费,1个足够)。自 己 动 手 写 sql 解 决 数 据 倾 斜 问 题 是 个 不 错 的 选 择 。 set hive.groupby.skew

35、indata=true这是通用的算法优化,但算法优化总是漠视业务,习惯性提供 通用的解决方法。Etl开发人员更了解业务,更了解数据,所以通过业务逻辑解决倾斜的方 法往往更精确,更有效。对count(distinct)采取漠视的方法,尤其数据大的时候很容易产生倾斜问题,不抱 侥幸心理。自己动手,丰衣足食。对小文件进行合并,是行至有效的提高调度效率的方法,假如我们的作业设置合 理的文件数,对云梯的整体调度效率也会产生积极的影响。优化时把握整体,单个作业最优不如整体最优。7.优化的常用手段主要由三个属性来决定:hive.exec.reducers.bytes.per.reducer 这个参数控制一个

36、 job 会有多少个 reducer 来处理,依据的是输入文件的总大小。默认 1GB。hive.exec.reducers.max 这个参数控制最大的 reducer 的数 量, 如果 input / bytes per reduce max 则会启动这个参数所指定的 reduce 个数。 这个并不会影响 mapre.reduce.tasks 参数的设置。默认的 max 是 999。mapred.reduce.tasks #这个参数如果指定了,hive就不会用它 的 estimation 函数来自动计算 reduce 的个数,而是用这个参数来启动 reducer。默认是-1。7.1 参数设置的影响如果reduce太少:如果数据量很大,会导致这个reduce异常的慢, 从而导致这个任务不能结束,也有可能会00M 2、如果reduce太多:产 生的小文件太多,合并起来代价太高, namenode 的内存占用也会增大。 如果我们不指定 mapred.reduce.tasks, hive 会自动计算需要多少个reducer。

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!