网站开发的毕业周记Wordpress禁止搜索内容
news/
2025/9/29 3:39:00/
文章来源:
网站开发的毕业周记,Wordpress禁止搜索内容,个人如何创建公众号,人才交流中心招聘网站建设方案原文链接#xff1a;https://zhuanlan.zhihu.com/p/174469951本篇将 Hive 的优化分成三个部分:第一部分是 SQL 通用语法优化#xff0c;第二部分是针对 Hive 所具有的数据倾斜的优化#xff0c;第三部分则介绍一些通用性的 Hive 参数设置优化。一、语法优化 SQL 的语法优化本… 原文链接https://zhuanlan.zhihu.com/p/174469951本篇将 Hive 的优化分成三个部分:第一部分是 SQL 通用语法优化第二部分是针对 Hive 所具有的数据倾斜的优化第三部分则介绍一些通用性的 Hive 参数设置优化。一、语法优化 SQL 的语法优化本质上是如何用更少的计算资源干相同的活基于此延伸出几条原则这几条原则又拓展出对应的一些具体方法原则1取更少的数这条原则特别朴素只要数据量少了运算的效率自然会提升但如何能够取更少数的同时不影响结果呢1、不要用 select *这条不多说了一些宽表少则二三十多则上百列而实际绝大多数都是我们不需要的在 select 时只挑选后续需要用到字段而不是 select *那么运算时间会成倍减少。2、谓词下推谓词下推指将过滤表达式尽可能移动至靠近数据源的位置以使真正执行时能直接跳过无关的数据。简单来说就是把 where 语句尽可能挪到最底层的位置在最底层就把不需要的数据都过滤掉然后让真正需要的数据参与运算而不是留到最后才进行过滤。根据谓词下推的思想可对下面的代码进行优化select t1.name, t2.age, t2.class, t2.income from t1 join t2 on t1.id t2.id where t2.age 18优化后select t1.name, t2.age, t2.class, t2.income from t1 join (select id, age, class, income from t2 where id 18) t2on t1.id t2.id3、多用子查询基于谓词下推的思想我们还可以做进一步的优化即多用子查询上面的代码可进一步优化成如下样子select t1.name, t2.age, t2.class, t2.income from(select id, name from t1) t1join(select id, age, class, income from t2 where age 18) t2on t1.id t2.id采用子查询后尽管会增加 job 数但提前把数据完成了过滤还提高了代码的可读性尤其是当需要关联的表和条件成倍增加后可读性将会非常重要。4、子查询的去重当子查询的表中所需的字段存在重复值那么对这些字段提前进行去重再进行关联同样会提高运算效率。还是以上面的代码为例select t1.name, t2.age, t2.class, t2.income from(select id, name from t1) t1join(select id, age, class, income from t2 where age 18 group by id, age, class, income) t2on t1.id t2.id至于为什么用 group by 而不是 distinct 去重会在数据倾斜部分进行解释。5、过滤null值当关联所用到的字段包含了太多 null 时需要从业务的角度考虑这些为 null 的数据是否有存在的必要如果不必要的话尽早过滤掉避免影响关联的效率。如果确实需要用到则可用 rand() 把数据均匀分布在不同的 reduce 上避免数据倾斜详细可见第二部分此处仅列出代码select n.*,o.namefrom nullidtable n full join bigtable o on nvl(n.id,rand())o.id原则2不排序SQL 中进行排序是要消耗计算资源的在 Hive 中这种资源消耗会更加明显。子查询里不要排序这一点就不多说了子查询中排序是毫无意义的同时在最后的结果步也尽可能少排序排序这需求完全可以通过交互查询的UI或把结果数据导出进行替代解决。当然如果进行查询时没有UI系统或者不方便把数据导出或者你就是想即时看到数据的排序情况就当这条建议不存在就好但在子查询里排序仍然还是毫无意义的。原则3分步该原则主要目的是把大数据集拆成小数据集来运行。1、减少在 selec 时用 case when有时出结果时需要用 case when 进行分类输出如下面例子select dt,count(distinct case when id1 then user_id else null end) as id_1_cnt,count(distinct case when id2 then user_id else null end) as id_2_cntfrom table_1where dt between 20200511 and 20200915group by dt但是实测发现 case when 的执行效率很低当数据量太大的时候甚至会跑不出数因此上面的代码可优化成如下形式select t1.dt,t1.id_1_cnt,t2.id_2_cntfrom(select dt,count(distinct user_id) as id_1_cntfrom table_1where dt between 20200511 and 20200915 and id1group by dt) t1left join(select dt,count(distinct user_id) as id_2_cntfrom table_1where dt between 20200511 and 20200915 and id2group by dt) t2on t1.dtt2.dt当数据量很大或者 select 时有太多的 case when采用上面的方式其执行效率会提高 10 倍以上。2、多用临时表当需要建的表其逻辑非常复杂时需要考虑用临时表的方式把中间逻辑分布执行一来方便阅读、修改和维护二来减少硬盘的开销(相较于建中间表的方式)。3、whereunion all当需要根据某字段分类汇总时发现运行速度很慢甚至跑不出结果那么有可能是因为某一类型的数据样本量过大造成数据倾斜此时可考虑通过 where 过滤 union all 合并的方法分步统计和汇总来处理该问题。优化前select age,count(distinct id) as id_cntfrom age_tablegroup by age优化后select age,count(distinct id) as id_cntfrom age_tablewhere age35group by ageunion allselect age,count(distinct id) as id_cntfrom age_tablewhere age35group by ageSQL 语句的优化方法贵精不贵多牢记上述原则和方法在日常取数建表写 SQL 时大部分情况下就已经接近最优效率了。二、数据倾斜 在展开数据倾斜的优化之前需要先了解 Hive 所采用 MapReduce 的原理以上图为例快速过一遍 MapReduce 的工作流程1、首先把需要处理的数据文件上传到 HDFS 上然后这些数据会被分为好多个小的分片然后每个分片对应一个 map 任务推荐情况下分片的大小等于 block 块的大小。然后 map 的计算结果会暂存到一个内存缓冲区内该缓冲区默认为 100M等缓存的数据达到一个阈值的时候默认情况下是 80%然后会在磁盘创建一个文件开始向文件里边写入数据。2、map 任务的输入数据的格式是 key-value 对的形式然后 map 在往内存缓冲区里写入数据的时候会根据 key 进行排序同样溢写到磁盘的文件里的数据也是排好序的最后 map 任务结束的时候可能会产生多个数据文件然后把这些数据文件再根据归并排序合并成一个大的文件。3、然后每个分片都会经过 map 任务后产生一个排好序的文件同样文件的格式也是 key-value 对的形式然后通过对 key 进行 hash 的方式把数据分配到不同的 reduce 里边去这样对每个分片的数据进行 hash再把每个分片分配过来的数据进行合并合并过程中也是不断进行排序的。最后数据经过 reduce 任务的处理就产生了最后的输出。简单来说map 阶段负责不同节点上一部分数据的统计工作reduce 阶段负责汇总聚合的工作。有时一个 reduce 可以处理多个任务但一些全局的工作只能让一个 reduce 负责例如统计总行数、distinct去重等此时就 reduce 就不能有多个实例并发执行这就会造成其他 reduce 的任务已经执行完了而负责全局的 reduce 还没执行完这就是数据倾斜的本质因此避免数据倾斜的核心在于均匀分配任务。1、数据量大的时候用group by当需要对数据进行去重时在数据量较大的情况下可以选择用 group by 而不是 distinct原理如下默认情况下map 阶段同一 key 数据分发给一个 reduce当一个 key 数据过大时就会发生数据倾斜了。但是并不是所有的聚合操作都只能在 reduce 完成很多聚合操作也可以先在 map 进行部分聚合最后在 reduce 端得出最终结果。开启 Map 端聚合参数设置(1)是否在 Map 端进行聚合默认为 trueset 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中)最后完成最终的聚合操作。而与之相对应的distinct 则只会用一个 reduce 来执行造成数据量过大而让整体任务执行时间过长或无法完成。但是需要注意的是用 group by 来去重会额外增加一个子查询只有当数据量很大的情况或任务执行中出现严重的数据倾斜group by 去重后 count 才会比 count(distinct) 效率更高。2、Mapjoin如果不指定 MapJoin 或者不符合 MapJoin 的条件那么 Hive 解析器会将 Join 操作转换成 Common Join即在 Reduce 阶段完成 join。容易发生数据倾斜。可以用 MapJoin 把小表全部加载到内存在 map 端进行 join避免 reducer 处理。(1)设置自动选择 Mapjoinset hive.auto.convert.join true; 默认为true(2)大表小表的阈值设置(默认25M以下认为是小表)set hive.mapjoin.smalltable.filesize25000000;数据倾斜的处理在 Hive 优化中是一个大课题实际场景中所遇到的 Hive 任务执行过长或报错有80%都与数据倾斜有关后续有机会的话可能专门写一篇针对解决数据倾斜的文章。三、参数优化 该部分罗列了一些常用的 Hive 参数设置并逐条做简单介绍1、set hive.input.formatorg.apache.hadoop.hive.ql.io.CombineHiveFormat;(默认开启)将多个小文件打包作为一个整体的 inputsplit减少 map 任务数2、set hive.merge.mapfilestrue;(默认值为真)合并 map 端小文件的输出3、set hive.auto.convert.jointrue;开启 mapjoin4、set hive.mapjoin.smalltable.filesize25000000; (默认25M)设置 mapjoin 的开启阈值5、set hive.optimize.skewjointrue;有数据倾斜的时候进行负载均衡6、set hive.skewjoin.key100000;表示当记录条数超过100000时采用 skewjoin 操作7、set hive.exec.paralleltrue;多个 join 多个 union all 优化开启不同 stage 任务并行计算8、set hive.exec.parallel.thread.number16;(默认为8)同一个 SQL 允许最大并行度9、set hive.map.aggrtrue;group by 数据倾斜优化 设置在 map 端进行聚合10、set hive.groupby.skewindatatrue;group by 数据倾斜优化11、set hive.exec.mode.local.autotrue;开启本地模式12、set mapred.compress.map.outputtrue;开启中间压缩以上是 Hive 通用属性的设置下面的参数主要目的是控制 map 和 reduce 的数量需要依情况而设定13、set hive.merge.smallfiles.avgsize16000000;平均文件大小是决定是否执行合并操作的阈值14、set mapred.min.split.size.per.node128000000;低于 128M 就算小文件数据在一个节点会合并在多个不同的节点会把数据抓取过来进行合并15、set mapred.min.split.size.per.rack64000000;每个机架处理的最小 split16、set mapred.max.split.size256000000;决定每个 map 处理的最大的文件大小17、set mapred.min.split.size10000000;决定每个 map 处理的最小的文件大小18、set hive.merge.size.per.task256000000(默认值为256000000)对 map 个数进行设置19、set mapred.reduce.tasks10;设置 reduce 的数量20、set hive.exec.reducers.bytes.per.reducer536870912;(512M)调整每个 reduce 处理数据量的大小以上关于 map 和 reduce 的参数需要根据实际情况设置具体的设置逻辑碍于篇幅所限就不展开了如果有机会的话需要单独列一篇作详细介绍。除了以上的优化方向外还可以通过设置 Hive 的文件格式来提高效率目前优化做得最好的文件格式就是 ORCfile可以在建表时通过 stored as ORC 来调用。另外可以根据实际工作需要把一些常用的统计汇总逻辑用中间表的形式存储起来便于后续查询。Hive 的优化是一个系统性的工作本篇仅列一二但是由于以后是 Spark 以及其他更优秀引擎的天下了所以如果以后还要对 Hive 进行优化那大概就是换一个语言吧(不是)。如果觉得还有帮助的话你的关注和转发是对我最大的支持O(∩_∩)O:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/921402.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!