罗列些重点的修create table这些就不讲了
鈳以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径 (LOCATION)Hive 创建内部表时,会将数据移动到数据仓库指向的路径;
若创建外蔀 表仅记录数据所在的路径,不对数据的位置做任何改变在删除表的时候,内部表的 元数据和数据会被一起删除而外部表只删除元數据,不删除数据
表示注释,默认不能使用中文
表示使用表分区,一个表可以拥有一个或者多个分区,每一个分区单独存在一个目录下 .
clustered by 对于烸一个表分文件 Hive可以进一步组织成桶,也就是说桶是更为细粒
度的数据范围划分Hive也是 针对某一列进行桶的组织。
指定排序字段和排序規则
外部表因为是指定其他的hdfs路径的数据加载到表当中来所以hive表会认为自己不完全独占这份数据,所以删除hive表的时候数据仍然存放在hdfs當中,不会删掉.
[内部表和外部表的使用场景]()
每天将收集到的网站日志定期流入HDFS文本文件在外部表(原始日志表)的基础上做大量的统计汾析,用到的中间表、结果表使用内部表存储数据通过SELECT+INSERT进入内部表。
分别创建老师与学生表外部表并向表中加载数据
Note:要放一个mysql的jar包到hive嘚lib里,版本兼容很受影响要看仔细教程
在大数据中,最常用的一种思想就是分治我们可以把大的文件切割划分成一个个的小的文件,這样每次操作一个小的文件就会很容易了同样的道理,在hive当中也是支持这种思想的就是我们可以把大的数据,按照每月或者天进行切分成一个个的小的文件,存放在不同的文件夹中.
`创建外部分区表,并指定文件数据存放目录`
今天搞报错搞了挺久==版本问题慎重深坑
首先我们来看看Hadoop的计算框架特性,在此特性下会衍生哪些问题
数据量大不是问题,数据倾斜是个问题
jobs数比较多的作业运行效率相对比较低,比如即使有几百行的表如果多次关联多次汇总,产生十几个jobs耗时很长。原因是map reduce作业初始化的时间是比较长的
面对这些问题,我们能有哪些有效的优化手段呢下面列出一些在工作有效可行的优化手段:
好的模型设计事半功倍。
设置合理的map reduce的task数能有效提升性能。(比如10w+级別的计算,用160个reduce那是相当的浪费,1个足够)
了解数据分布,自己动手解决数据倾斜问题是个不错的选择set hive.groupby.skewindata=true;这是通用的算法优化,但算法優化有时不能适应特定业务背景开发人员了解业务,了解数据可以通过业务逻辑精确有效的解决数据倾斜问题。
对小文件进行合并昰行至有效的提高调度效率的方法,假如所有的作业设置合理的文件数对云梯的整体调度效率也会产生积极的正向影响。
优化时把握整體单个作业最优不如整体最优。
而接下来我们心中应该会有一些疑问,影响性能的根源是什么
hive性能优化时,把HiveQL当做M/R程序来读即从M/R嘚运行角度来考虑优化性能,从更底层思考如何优化运算性能而不仅仅局限于逻辑代码的替换层面。
RAC(Real Application Cluster)真正应用集群就像一辆机动灵活的小货车响应快;Hadoop就像吞吐量巨大的轮船,启动开销大如果每次只做小数量的输入输出,利用率将会很低所以用好Hadoop的首要任务是增大每次任务所搭载的数据量。
Hadoop的核心能力是parition和sort因而这也是优化的根本。
观察Hadoop处理数据的过程有几个显著的特征:
数据的大规模并不昰负载重点,造成运行压力过大是因为运行数据的倾斜
jobs数比较多的作业运行效率相对比较低,比如即使有几百行的表如果多次关联对此汇总,产生几十个jobs将会需要30分钟以上的时间且大部分时间被用于作业分配,初始化和数据输出M/R作业初始化的时间是比较耗时间资源嘚一个部分。
在使用SUMCOUNT,MAXMIN等UDAF函数时,不怕数据倾斜问题Hadoop在Map端的汇总合并优化过,使数据倾斜不成问题
COUNT(DISTINCT)在数据量大的情况下,效率较低如果多COUNT(DISTINCT)效率更低,因为COUNT(DISTINCT)是按GROUP BY字段分组按DISTINCT字段排序,一般这种分布式方式是很倾斜的;比如:男UV女UV,淘宝一天30亿的PV如果按性别分組,分配2个reduce,每个reduce处理15亿数据
数据倾斜是导致效率大幅降低的主要原因,可以采用多一次 Map/Reduce 的方法 避免倾斜。
最后得出的结论是:避实就虛用 job 数的增加,输入量的增加占用更多存储空间,充分利用空闲 CPU 等各种方法分解数据倾斜造成的负担。
我们知道了性能低下的根源同样,我们也可以从Hive的配置解读去优化Hive系统内部已针对不同的查询预设定了优化方法,用户可以通过调整配置进行控制 以下举例介紹部分优化的策略以及优化控制选项。
Hive 在读数据的时候可以只读取查询中所需要用到的列,而忽略其它列 例如,若有以下查询:
在实施此项查询中Q 表有 5 列(a,bc,de),Hive 只读取查询逻辑中真实需要 的 3 列 a、b、e而忽略列 c,d;这样做节省了读取开销中间表存储开销和数據整合开销。
可以在查询的过程中减少不必要的分区 例如,若有以下查询:
查询语句若将“subq.prtn=100”条件放入子查询中更为高效可以减少读叺的分区 数目。 Hive 自动执行这种裁剪优化
在编写带有 join 操作的代码语句时,应该将条目少的表/子查询放在 Join 操作符的左边 因为在 Reduce 阶段,位于 Join 操作符左边的表的内容会被加载进内存载入条目较少的表 可以有效减少 OOM(out of memory)即内存溢出。所以对于同一个 key 来说对应的 value 值小的放前,大嘚放后这便是“小表放前”原则。 若一条语句中有多个 Join依据 Join 的条件相同与否,有不同的处理方法
在使用写有 Join 操作的查询语句时有一條原则:应该将条目少的表/子查询放在 Join 操作符的左边。原因是在 Join 操作的 Reduce 阶段位于 Join 操作符左边的表的内容会被加载进内存,将条目少的表放在左边可以有效减少发生 OOM 错误的几率。对于一条语句中有多个 Join 的情况如果 Join 的条件相同,比如查询:
如果 Join 的 key 相同不管有多少个表,嘟会则会合并为一个 Map-Reduce
如果 Join 的条件不相同比如:
Map-Reduce 的任务数目和 Join 操作的数目是对应的,上述查询和以下查询是等价的:
Join 操作在 Map 阶段完成不洅需要Reduce,前提条件是需要的数据在 Map 的过程中可以访问到比如查询:
进行GROUP BY操作时需要注意一下几点:
事实上并不是所有的聚合操作都需要茬reduce部分进行,很多聚合操作都可以先在Map端进行部分聚合然后reduce端得出最终结果。
这里需要修改的参数为:
有数据倾斜时进行负载均衡
中從而达到负载均衡的目的;第二个 MapReduce 任务再根据预处 理的数据结果按照 Group By Key 分布到 reduce 中(这个过程可以保证相同的 Group By Key 分布到同一个 reduce 中),最后完成最終的聚合操作
我们知道文件数目小,容易在文件存储端造成瓶颈给 HDFS 带来压力,影响处理效率对此,可以通过合并Map和Reduce的结果文件来消除这样的影响
用于设置合并属性的参数有:
4.1熟练使用SQL提高查询
熟练地使用 SQL,能写出高效率的查询语句
场景:有一张 user 表,为卖家每天收箌表user_id,ds(日期)为 key属性有主营类目,指标有交易金额交易笔数。每天要取前10天的总收入总笔数,和最近一天的主营类目
下面给絀方法1的思路,实现步骤如下:
第一步:利用分析函数取每个 user_id 最近一天的主营类目,存入临时表 t1
第二步:汇总 10 天的总交易金额,交易筆数存入临时表 t2。
第三步:关联 t1t2,得到最终的结果
在工作中我们总结出:方案 2 的开销等于方案 1 的第二步的开销,性能提升由原有嘚 25 分钟完成,缩短为 10 分钟以内完成节省了两个临时表的读写是一个关键原因,这种方式也适用于 Oracle 中的数据查找工作
SQL 具有普适性,很多 SQL 通用的优化方案在 Hadoop 分布式计算方式中也可以达到效果
4.2无效ID在关联时的数据倾斜问题
问题:日志中常会出现信息丢失,比如每日约为 20 亿的铨网日志其中的 user_id 为主 键,在日志收集过程中会丢失出现主键为 null 的情况,如果取其中的 user_id 和 bmw_users 关联就会碰到数据倾斜的问题。原因是 Hive 中主键为 null 值的项会被当做相同的 Key 而分配进同一个计算 Map。
解决方法 1:user_id 为空的不参与关联子查询过滤 null
解决方法 2 如下所示:函数过滤 null
调优结果:原先由于数据倾斜导致运行时长超过 1 小时,解决方法 1 运行每日平均时长 25 分钟解决方法 2 运行的每日平均时长在 20 分钟左右。优化效果很明显
我们在工作中总结出:解决方法2比解决方法1效果更好,不但IO少了而且作业数也少了。解决方法1中log读取两次job 数为2。解决方法2中 job 数是1這个优化适合无效 id(比如-99、 ‘’,null 等)产生的倾斜问题把空值的 key 变成一个字符串加上随机数,就能把倾斜的 数据分到不同的Reduce上从而解決数据倾斜问题。因为空值不参与关联即使分到不同 的
4.3不同数据类型关联产生的倾斜问题
问题:不同数据类型 id 的关联会产生数据倾斜问題。
一张表 s8 的日志每个商品一条记录,要和商品表关联但关联却碰到倾斜的问题。 s8 的日志中有 32 为字符串商品 id也有数值商品 id,日志中類型是 string 的但商品中的 数值 id 是 bigint 的。猜想问题的原因是把 s8 的商品 id 转成数值 id 做 hash 来分配 Reduce 所以字符串 id 的 s8 日志,都到一个 Reduce 上了解决的方法验证了這个猜测。
解决方法:把数据类型转换成字符串类型
调优结果显示:数据表处理由 1 小时 30 分钟经代码调整后可以在 20 分钟内完成
问题:比如嶊广效果表要和商品表关联,效果表中的 auction_id 列既有 32 为字符串商 品 id也有数字 id,和商品表关联得到商品的信息
解决方法:Hive SQL 性能会比较好
比分別过滤数字 id,字符串 id 然后分别和商品表关联性能要好
所以商品表的 HDFS 读取只会是一次。
从业务逻辑上说子查询内的 GROUP BY 怎么都看显得多余(功能上的多余,除非有 COUNT(DISTINCT))如果不是因为 Hive Bug 或者性能上的考量(曾经出现如果不执行子查询 GROUP BY,数据得不到正确的结果的 Hive Bug)所以这个 Hive 按经验轉换成如下所示:
但如果换成是其他计算平台如 Oracle,那就不一定了因为把大的输入拆成两个输入, 分别排序汇总后 merge(假如两个子排序是并荇的话)是有可能性能更优的(比如希尔排 序比冒泡排序的性能更优)。
由于子查询里头有 COUNT(DISTINCT)操作直接去 GROUP BY 将达不到业务目标。这时采用 臨时表消灭 COUNT(DISTINCT)作业不但能解决倾斜问题还能有效减少 jobs。
调优结果:千万级别的类目表member 表,与 10 亿级得商品表关联原先 1963s 的任务经过调整,1152s 即完成
消灭子查询内的 JOIN
调优结果显示:针对千万级别的广告位表,由原先 5 个 Job 共 15 分钟分解为 2 个 job 一个 8-10 分钟,一个3分钟
关于COUNT(DISTINCT)的数据倾斜问題不能一概而论,要依情况而定下面是我测试的一组数据:
#统计每日IP(改造)
测试结果表名:明显改造后的语句比之前耗时,这是因为妀造后的语句有2个SELECT多了一个job,这样在数据量小的时候数据不会存在倾斜问题。
优化时把hive sql当做mapreduce程序来读,会有意想不到的惊喜理解hadoop嘚核心能力,是hive优化的根本这是这一年来,项目组所有成员宝贵的经验总结
长期观察hadoop处理数据的过程,有几个显著的特征:
不怕数据多就怕数据倾斜。
对jobs数比较多的作业运行效率相对比较低比如即使有几百行的表,如果多次关联多次汇总产生十几个jobs,没半小时是跑鈈完的map reduce作业初始化的时间是比较长的。
对sumcount来说,不存在数据倾斜问题
优化可以从几个方面着手:
好的模型设计事半功倍。
设置合理嘚map reduce的task数能有效提升性能。(比如10w+级别的计算,用160个reduce那是相当的浪费,1个足够)
自己动手写sql解决数据倾斜问题是个不错的选择。set hive.groupby.skewindata=true;这是通鼡的算法优化但算法优化总是漠视业务,习惯性提供通用的解决方法 Etl开发人员更了解业务,更了解数据所以通过业务逻辑解决倾斜嘚方法往往更精确,更有效
对count(distinct)采取漠视的方法,尤其数据大的时候很容易产生倾斜问题不抱侥幸心理。自己动手丰衣足食。
对小文件进行合并是行至有效的提高调度效率的方法,假如我们的作业设置合理的文件数对云梯的整体调度效率也会产生积极的影响。
优化時把握整体单个作业最优不如整体最优。
主要由三个属性来决定:
如果reduce太少:如果数据量很大会导致这个reduce异常的慢,从而导致这个任務不能结束也有可能会OOM 2、如果reduce太多: 产生的小文件太多,合并起来代价太高namenode的内存占用也会增大。如果我们不指定mapred.reduce.tasks hive会自动计算需要哆少个reducer。