3d网站带后台下载,网站备案信息是什么意思,郴州网签查询,江门网站建设推广策划Hive调优策略Hive作为大数据领域常用的数据仓库组件#xff0c;在设计和开发阶段需要注意效率。影响Hive效率的不仅仅是数据量过大;数据倾斜、数据冗余、job(小文件多)或I/O过多、MapReduce分配不合理等因素都对Hive的效率有影响。对Hive的调优既包含对HiveQL语句本身的优化在设计和开发阶段需要注意效率。影响Hive效率的不仅仅是数据量过大;数据倾斜、数据冗余、job(小文件多)或I/O过多、MapReduce分配不合理等因素都对Hive的效率有影响。对Hive的调优既包含对HiveQL语句本身的优化也包含Hive配置项和MR方面的调整。从以下几个方面调优1、架构调优2、参数调优3、SQL优化架构优化执行引擎Hive支持多种执行引擎分别是MR、Tez、Spark、Flink可以通过hive-site.xml文件中的hive.execution.engine属性配置。Tez是一个构建于YARN之上的支持复杂的DAG(有向无环图)任务的数据处理框 架。由Hontonworks开源将MapReduce的过程拆分成若干个子过程同时可以 把多个mapreduce任务组合成一个较大的DAG任务减少了MapReduce之间的文件存储同时合理组合其子过程从而大幅提升MR作业的性能。Tez.png优化器与关系型数据库类似Hive在真正执行的时候会先先通过解释器生成AST抽象语法树然后再通过编译器生成逻辑执行计划再通过优化器进行优化优化后通过执行器生成物理执行计划。而Hive有两种优化器Vectorize(矢量化优化器)和Cost-Based Optimization(CBO成本优化器)矢量化查询优化(向量化优化器)矢量化查询(要求执行引擎为Tez)执行通过一次批量执行1024行而不是每行一行来提高扫描、聚合、过滤器和和链接等操作的性能这个功能明显缩短查询执行时间## 默认 falseset hive.vectorized.execution.enabled true; ## 默认 falseset hive.vectorized.execution.reduce.enabled true; 备注要使用矢量化查询执行必须用ORC格式存储数据求执行引擎为Tez成本优化器Hive的CBO是基于Apache Calcite的Hive的CBO通过查询成本(有analyze收集的统计信息)会生成有效率的执行计划最终会较少执行的时间和资源利用使用CBO的配置如下--从 v0.14.0默认 trueSET hive.cbo.enabletrue;-- 默认false SET hive.compute.query.using.statstrue; -- 默认falseSET hive.stats.fetch.column.statstrue; -- 默认trueSET hive.stats.fetch.partition.statstrue;定期执行表(分析的命令analyze)的分析分析后的数据放在元数据库中。大表小表join.png低版本情况下小表在前的确效率高高版本优化器已经做了优化。是因为小表的数据可能会放到内存里面大表的数据内存存不下就会导致效率低。把重复关联键少的表放在join前面做关联可以提高join的效率分区表对于一个比较大的表将其设计成分区表可以提升查询的性能对于一个特定分区的查询只会加载对应分区路径的数据文件所以执行速度比较快分区字段的选择避免层级较深的分区否则会造成太多的字文件夹常见的分区字段日期或时间。如 year、month、day或者hour当表中存在时间或者日期字段时地理问题。如国家、省份、城市等业务逻辑。如部门、销售区域、客户等等分桶表与分区表类似分桶表的组织方式是将HDFS上的文件分割成多个文件。分桶可以加快数据采样也可以提升join的性能join的字段是分桶字段因为分桶可以确保某一个key对应的数据在一个特定的桶内(文件)巧妙的选择分桶字段可以大幅度提升join性能。通常情况下分桶字段可以选择经常用过滤操作或者join操作的字段文件格式在HiveQL的create table语句中可以使用 stored as … 指定表的存储格式。Hive表支持的存储格式有TextFile、SequenceFile、RCFile、ORC、Parquet等。存储格式一般需要根据业务进行选择生产环境中绝大多数表都采用TextFile、 ORC、Parquet存储格式之一。TextFile是最简单的存储格式它是纯文本记录也是Hive的默认格式。其磁盘开销 大查询效率低更多的是作为跳板来使用。RCFile、ORC、Parquet等格式的表都不能由文件直接导入数据必须由TextFile来做中转。Parquet和ORC都是Apache旗下的开源列式存储格式。列式存储比起传统的行式存 储更适合批量OLAP查询并且也支持更好的压缩和编码。选择Parquet的原因主要 是它支持Impala查询引擎并且对update、delete和事务性操作需求很低。数据压缩压缩技术可以减少map与reduce之间的数据传输从而可以提升查询性能关于压 缩的配置可以在hive的命令行中或者hive-site.xml文件中进行配置。-- 默认是falseSET hive.exec.compress.intermediatetrue开启压缩之后可以选择下面的压缩格式:压缩格式.png关于压缩的编码器可以通过mapred-site.xml, hive-site.xml进行配置也可以通过 命令行进行配置如:-- 中间结果压缩SET hive.intermediate.compression.codecorg.apache.hadoop.io.compress.SnappyCodec;-- 输出结果压缩SET hive.exec.compress.outputtrue;SET mapreduce.output.fileoutputformat.compress.codec org.apache.hadoop.io.compress.SnappyCodc设计阶段要考虑的优化点1、执行引擎2、优化器3、分区、分桶4、文件格式5、数据压缩参数优化本地模式当Hive处理的数据量较小的时启动分布式处理数据就会显得浪费因为可能启动时间比处理数据时间还要长Hive支持将作业动态的转为本地模式需要使用下面的配置-- 默认 falseSET hive.exec.mode.local.autotrue; -- 默认128MSET hive.exec.mode.local.auto.inputbytes.max50000000; -- 默认 4SET hive.exec.mode.local.auto.input.files.max5;一个作业只要满足下面的条件会启用本地模式输入文件的大小小于 hive.exec.mode.local.auto.inputbytes.max 配置的大小map任务的数量小于 hive.exec.mode.local.auto.input.files.max 配置的大小reduce任务的数量是1或者0严格模式所谓严格模式就是不允许执行3种有风险的HQL语句查询分区表的时候不限定分区列的语句两个表join产生了笛卡尔积用order by 来排序但没有指定limit要开启严格模式需要将参数要开启严格模式需要将参数 hive.mapred.mode 设为strict(缺省值)。该参数可以不在参数文件中定义在执行SQL之前设置(set hive.mapred.modenostrict ),即在当前SQL不是严格模式。JVM重用默认情况下Hadoop会为为一个map或者reduce启动一个JVM这样可以并行执行map和reduce。当map或者reduce是那种仅运行几秒钟的轻量级作业时JVM启动进程所耗费的时 间会比作业执行的时间还要长。Hadoop可以重用JVM通过共享JVM以串行而非并行的方式运行map或者reduce。JVM的重用适用于同一个作业的map和reduce对于不同作业的task不能够共享 JVM。如果要开启JVM重用需要配置一个作业最大task数量默认值为1如果设 置为-1则表示不限制# 代表同一个MR job中顺序执行的5个task重复使用一个JVM减少启动和关闭的开销 SET mapreduce.job.jvm.numtasks5;这个功能的缺点是开启JVM重用将一直占用使用到的task插槽以便进行重用直 到任务完成后才能释放。如果某个“不平衡的”job中有某几个reduce task执行的时间 要比其他Reduce task消耗的时间多的多的话那么保留的插槽就会一直空闲着却无 法被其他的job使用直到所有的task都结束了才会释放。并行执行Hive的查询通常会被转换成一系列的stage这些stage之间并不是一直相互依赖 的可以并行执行这些stage通过下面的方式进行配置:SET hive.exec.paralleltrue; -- 默认falseSET hive.exec.parallel.thread.number16; -- 默认8并行执行可以增加集群资源的利用率如果集群的资源使用率已经很高了那么并 行执行的效果不会很明显。推测执行在分布式集群环境下因为程序Bug、负载不均衡、资源分布不均等原因会造成同 一个作业的多个任务之间运行速度不一致有些任务的运行速度可能明显慢于其他任务(比如一个作业的某个任务进度只有50%而其他所有任务已经运行完毕) 则这些任务会拖慢作业的整体执行进度。为了避免这种情况发生Hadoop采用了推测执行机制它根据一定的规则推测出 “拖后腿”的任务并为这样的任务启动一个备份任务让该任务与原始任务同时处理 同一份数据并最终选用最先成功运行完成任务的计算结果作为最终结果。set mapreduce.map.speculativetrueset mapreduce.reduce.speculativetrueset hive.mapred.reduce.tasks.speculative.executiontrue合并小文件在map执行前合并小文件减少map数# 缺省参数set hive.input.formatorg.apache.hadoop.hive.ql.io.CombineHiveInputFormat;在Map-Reduce的任务结束时合并小文件# 在 map-only 任务结束时合并小文件默认true SET hive.merge.mapfiles true;# 在 map-reduce 任务结束时合并小文件默认false SET hive.merge.mapredfiles true;# 合并文件的大小默认256MSET hive.merge.size.per.task 268435456;# 当输出文件的平均大小小于该值时启动一个独立的map-reduce任务进行文件merge SET hive.merge.smallfiles.avgsize 16777216;Fetch模式Fetch模式是指Hive中对某些情况的查询可以不必使用MR计算select col1,col2 from tab;可以简单地读取表对应的存储目录下的文件然后输出查询结果到控制台在开启fetch模式之后在全局查找、字段查找、limit查找等都不启动MR# Default Value: minimal in Hive 0.10.0 through 0.13.1, more in Hive 0.14.0 and laterset hive.fetch.task.conversionmore参数调整1、本地模式2、严格模式3、JVM重用4、并行执行5、推测执行6、合并小文件7、fetch模式(规避没有必要的MapReduce)SQL优化列裁剪和分区裁剪列裁剪是在查询时至读取需要的列避免查询select * from tab这种分区裁剪就是只读取需要的分区不需要的分区不需要读取出来,分区表一定要跟上分区。select uid, event_type, record_data from calendar_record_log where pt_date 20190201 and pt_date 20190224 and status 0;sort by 代替 order byHiveQL中的order by与其他关系数据库SQL中的功能一样是将结果按某字段全局排序这会导致所有map端数据都进入一reduce中在数据量大时可能会长时间计算不完。如果使用sort by那么还是会视情况启动多个reducer进行排序并且保证每个 reducer内局部有序。为了控制map端数据分配到reducer的key往往还要配合 distribute by 一同使用。如果不加 distribute by 的话map端数据就会随机分配到 reducer。group by 代替count(distinct)当要统计某一列的去重数时如果数据量很大count(distinct) 会非常慢。原因与 order by类似count(distinct)逻辑只会有很少的reducer来处理。此时可以用 group by 来改写:-- 原始SQLselect count(distinct uid)from tab;-- 优化后的SQL select count(1) from (select uid from tabgroup by uid) tmp;这样写会启动两个MR job(单纯distinct只会启动一个)所以要确保数据量大到启动job的overhead远小于计算耗时才考虑这种方法。当数据集很小或者key的倾斜 比较明显时group by还可能会比distinct慢。group by配置调整----map端预聚合group by时如果先起一个combiner在map端做部分预聚合可以有效减少 shuffle数据量。-- 默认为trueset hive.map.aggr trueMap端进行聚合操作的条目数set hive.groupby.mapaggr.checkinterval 100000通过 hive.groupby.mapaggr.checkinterval 参数也可以设置map端预聚合的行 数阈值超过该值就会分拆job默认值10W。group by配置调整----倾斜均衡置顶group by时如果某些key对应的数据量过大就会发生数据倾斜。Hive自带了一个均衡数据倾斜的配置项 hive.groupby.skewindata 默认值false。其实现方法是在group by时启动两个MR job。第一个job会将map端数据随机输入 reducer每个reducer做部分聚合相同的key就会分布在不同的reducer中。第二 个job再将前面预处理过的数据按key聚合并输出结果这样就起到了均衡的效果。但是配置项毕竟是死的单纯靠它有时不能根本上解决问题建议了解数据倾斜 的细节并优化查询语句。join的在基础优化hive join 的三种方式common join普通连接在SQL中不特殊指定连接方式使用的都是这种普通连接,两个数据在做连接之前会先去做shuffle如下图会将关联id相同的时候同一个区再去真正的关联缺点性能差(性能差的原因要将数据分区有shuffle)优点操作简单适应性强common Join.pngmap joinmap端连接与普通连接的区别是这个连接中不会有reduce阶段存在连接在map端完成适用场景:大表与小表连接小表数据量应该能够完全加载到内存否则不适用优点:在大小表连接时性能提升明显备注:Hive 0.6 的时候默认认为写在select 后面的是大表前面的是小表 或者使用 /*mapjoin(map_table) */ select a., b. from a join b on a.id b.id【要求小表在前大表之后】hive 0.7 的时候这个计算是自动化的它首先会自动判断哪个是小表哪个是大 表这个参数由(hive.auto.convert.jointrue)来控制然后控制小表的大小由 (hive.smalltable.filesize25000000)参数控制(默认是25M)当小表超过这个 大小hive 会默认转化成common join。Hive 0.8.1hive.smalltable.filesize hive.mapjoin.smalltable.filesize 缺点:使用范围较小只针对大小表且小表能完全加载到内存中的情况。bucket map join分桶连接:Hive 建表的时候支持hash 分区通过指定clustered by (col_name,xxx ) into number_buckets buckets 关键字.当连接的两个表的join key 就是bucket column 的时候就可以通过设置hive.optimize.bucketmapjoin true 来执行优 化。原理:通过两个表分桶在执行连接时会将小表的每个分桶映射成hash表每个task 节点都需要这个小表的所有hash表但是在执行时只需要加载该task所持有大表分 桶对应的小表部分的hash表就可以所以对内存的要求是能够加载小表中最大的 hash块即可。注意点:小表与大表的分桶数量需要是倍数关系这个是因为分桶策略决定的分桶时会根据分桶字段对桶数取余后决定哪个桶的所以要保证成倍数关系。优点:比map join对内存的要求降低能在逐行对比时减少数据计算量(不用比对 小表全量)缺点:只适用于分桶表利用map join特性map join特别适合大小表join的情况。Hive会将build table和probe table在map端直接完成join过程消灭了reduce效率很高。select a.event_type, b.upload_time from calendar_event_code ainner join ( select event_type, upload_time from calendar_record_logwhere pt_date 20190225) b on a.event_type map join的配置项是 hive.auto.convert.join 默认值true。当build table大小小于hive.mapjoin.smalltable.filesize 会启用map join 默认值25000000(约25MB)。还有 hive.mapjoin.cache.numrows 表示缓存 build table的多少行数据到内存默认值25000。分桶表map joinmap join对分桶表还有特别的优化。由于分桶表是基于一列进行hash存储的因此 非常适合抽样(按桶或按块抽样)。它对应的配置项是 hive.optimize.bucketmapjoin 。倾斜均衡配置项这个配置与 group by 的倾斜均衡配置项异曲同工通过 hive.optimize.skewjoin 来配置默认false。如果开启了在join过程中Hive会将计数超过阈值 hive.skewjoin.key (默认 100000)的倾斜key对应的行临时写进文件中然后再启动另一个job做map join生 成结果。通过 hive.skewjoin.mapjoin.map.tasks 参数还可以控制第二个job的 mapper数量默认10000。去掉空值和无意义的值日志类数据中往往会有一些项没有记录到其值为null或者空字符串、-1等。如果 缺失的项很多在做join时这些空值就会非常集中拖累进度【备注:这个字段是连接字段】。若不需要空值数据就提前写 where 语句过滤掉。需要保留的话将空值key用随 机方式打散例如将用户ID为null的记录随机改为负值:select a.uid, a.event_type, b.nickname, b.age from (select(case when uid is null then cast(rand()*-10240 as int) else uid end) as uid, event_type from calendar_record_log where pt_date 20190201) a left outer join (select uid,nickname,age from user_info where status 4 ) b on a.uid b.uid;单独处理倾斜的key如果倾斜的 key 有实际的意义一般来讲倾斜的key都很少此时可以将它们单独抽 取出来对应的行单独存入临时表中然后打上一个较小的随机数前缀(比如 0~9)最后再进行聚合。不要一个Select语句中写太多的Join。一定要了解业务了解数据。(A0-A9) 分成多条语句分步执行;(A0-A4; A5-A9);先执行大表与小表的关联;调整Map数通常情况下作业会通过输入数据的目录产生一个或者多个map任务。主要因素包括:输入文件总数输入文件大小HDFS文件块大小Map不是越多也好而是合适的才是最好的。如果一个任务有很多小文件(远远小于128M)每个小文件也会被当做成一个数据块用一个MapTask来完成一个MapTask启动和初始化时间远远大于处理时间就会造成资源浪费而且系统中可用的map是有限的。对于小文件采用的策略是合并小文件。每个map处理接近128M的文件块会有其他问题吗。也不一定。有一个125M的文件一般情况下会用一个Map Task完成。假设这个文件字段很 少但记录数却非常多。如果Map处理的逻辑比较复杂用一个map任务去做性 能也不好。对于复杂文件采用的策略是增加 Map 数computeSliteSize(max(minSize, min(maxSize, blocksize))) blocksizeminSize : mapred.min.split.size (默认值1)maxSize : mapred.max.split.size (默认值256M)调整maxSize最大值。让maxSize最大值低于blocksize就可以增加map的个数。 建议用set的方式针对SQL语句进行调整。调整Reduce数reducer数量的确定方法比mapper简单得多。使用参数 mapred.reduce.tasks可以直接设定reducer数量。如果未设置该参数Hive会进行自行推测逻辑如下:参数hive.exec.reducers.bytes.per.reducer用来设定每个reducer能够处理的最大数据量默认值256M参数hive.exec.reducers.max用来设定每个job的最大reducer数量默认值999(1.2版本之前)或1009(1.2版本之后)得出reducer数:reducer_num Min(total_input_size / hive.exec.reducers.bytes.per.reducer,hive.exec.reducers.max )即: min(输入总数据量 / 256M, 1009)reducer数量与输出文件的数量相关。如果reducer数太多会产生大量小文件对 HDFS造成压力。如果reducer数太少每个reducer要处理很多数据容易拖慢运行 时间或者造成OOM。Hive优化小结深入理解 Hadoop 的核心能力对Hive优化很有帮助。Hadoop/Hive 处理数据过 程有几个显著特征:不怕数据多就怕数据倾斜对job数比较多的作业运行效率相对比较低比如即使有几百行的表多次关联多次汇总产品十几个jobs执行时间也需要较长时间。MapReduce作业初始化的时间是比较长的。对sum、count的聚合操作来说不存在数据倾斜count(distinct) 效率较低数据量大容易出问题从大的方面来说优化可以从几个方面好的设计模型事半功倍(该分区分区该分桶分桶压缩、本地模式)解决数据倾斜问题。仅仅依靠参数解决数据倾斜是通用的优化手段收获有限。开发人员应该熟悉业务了解数据规律通过业务逻辑解决数据倾斜往往更可靠。减少job数设置合理的mapTask、reduceTask数对小文件进行合并优化整体单一作业优化不如整体优化。