写好Hive 程序的五个提示

Hive中Map任务和Reduce任务数量计算原理 Hive中Map任务和Reduce任务数计算原理 MapReduce原理 Map阶段(以FileInputFormat为例) 步骤:map, partition, sort, combiner InputFormat负责计算分片,一个分片对应一个Map任务,InputFormat而且还负责创建RecordReader,通过RecordReader的next()方法,然后循环调用map()方法... 阅读详情

使用Hive可以高效而又快速地编写复杂的MapReduce查询逻辑。但是某些情况下,因为不熟悉数据特性,或没有遵循Hive的优化约定,Hive计算任务会变得非常低效,甚至无法得到结果。一个”好”的Hive程序仍然需要对Hive运行机制有深入的了解。

有一些大家比较熟悉的优化约定包括:Join中需要将大表写在靠右的位置;尽量使用UDF而不是transfrom……诸如此类。下面讨论5个性能和逻辑相关的问题,帮助你写出更好的Hive程序。

全排序

Hive的排序关键字是SORT BY,它有意区别于传统数据库的ORDER BY也是为了强调两者的区别–SORT BY只能在单机范围内排序。考虑以下表定义:

CREATE TABLE if not exists t_order(

id int, -- 订单编号

sale_id int, -- 销售ID

customer_id int, -- 客户ID

product _id int, -- 产品ID

amount int -- 数量

) PARTITIONED BY (ds STRING);

在表中查询所有销售记录,并按照销售ID和数量排序:

set mapred.reduce.tasks=2;

Select sale_id, amount from t_order

Sort by sale_id, amount;

这一查询可能得到非期望的排序。指定的2个reducer分发到的数据可能是(各自排序):

Reducer1:

Sale_id | amount

0 | 100

1 | 30

1 | 50

2 | 20

Reducer2:

Sale_id | amount

0 | 110

0 | 120

3 | 50

4 | 20

因为上述查询没有reduce key,hive会生成随机数作为reduce key。这样的话输入记录也随机地被分发到不同reducer机器上去了。为了保证reducer之间没有重复的sale_id记录,可以使用DISTRIBUTE BY关键字指定分发key为sale_id。改造后的HQL如下:

set mapred.reduce.tasks=2;

Select sale_id, amount from t_order

Distribute by sale_id

Sort by sale_id, amount;

这样能够保证查询的销售记录集合中,销售ID对应的数量是正确排序的,但是销售ID不能正确排序,原因是hive使用hadoop默认的HashPartitioner分发数据。

这就涉及到一个全排序的问题。解决的办法无外乎两种:

1.) 不分发数据,使用单个reducer:

set mapred.reduce.tasks=1;

这一方法的缺陷在于reduce端成为了性能瓶颈,而且在数据量大的情况下一般都无法得到结果。但是实践中这仍然是最常用的方法,原因是通常排序的查询是为了得到排名靠前的若干结果,因此可以用limit子句大大减少数据量。使用limit n后,传输到reduce端(单机)的数据记录数就减少到n* (map个数)。

2.) 修改Partitioner,这种方法可以做到全排序。这里可以使用Hadoop自带的TotalOrderPartitioner(来自于Yahoo!的TeraSort项目),这是一个为了支持跨reducer分发有序数据开发的Partitioner,它需要一个SequenceFile格式的文件指定分发的数据区间。如果我们已经生成了这一文件(存储在/tmp/range_key_list,分成100个reducer),可以将上述查询改写为

set mapred.reduce.tasks=100;

set hive.mapred.partitioner=org.apache.hadoop.mapred.lib.TotalOrderPartitioner;

set total.order.partitioner.path=/tmp/ range_key_list;

Select sale_id, amount from t_order

Cluster by sale_id

Sort by amount;

有很多种方法生成这一区间文件(例如hadoop自带的o.a.h.mapreduce.lib.partition.InputSampler工具)。这里介绍用Hive生成的方法,例如有一个按id有序的t_sale表:

CREATE TABLE if not exists t_sale (

id int,

name string,

loc string

);

则生成按sale_id分发的区间文件的方法是:

create external table range_keys(sale_id int)

row format serde

'org.apache.hadoop.hive.serde2.binarysortable.BinarySortableSerDe'

stored as

inputformat

'org.apache.hadoop.mapred.TextInputFormat'

outputformat

'org.apache.hadoop.hive.ql.io.HiveNullValueSequenceFileOutputFormat'

location '/tmp/range_key_list';

 

insert overwrite table range_keys

select distinct sale_id

from source t_sale sampletable(BUCKET 100 OUT OF 100 ON rand()) s

sort by sale_id;

生成的文件(/tmp/range_key_list目录下)可以让TotalOrderPartitioner按sale_id有序地分发reduce处理的数据。区间文件需要考虑的主要问题是数据分发的均衡性,这有赖于对数据深入的理解。

怎样做笛卡尔积?

当Hive设定为严格模式(hive.mapred.mode=strict)时,不允许在HQL语句中出现笛卡尔积,这实际说明了Hive对笛卡尔积支持较弱。因为找不到Join key,Hive只能使用1个reducer来完成笛卡尔积。

当然也可以用上面说的limit的办法来减少某个表参与join的数据量,但对于需要笛卡尔积语义的需求来说,经常是一个大表和一个小表的Join操作,结果仍然很大(以至于无法用单机处理),这时MapJoin才是最好的解决办法。

MapJoin,顾名思义,会在Map端完成Join操作。这需要将Join操作的一个或多个表完全读入内存。

MapJoin的用法是在查询/子查询的SELECT关键字后面添加/*+ MAPJOIN(tablelist) */提示优化器转化为MapJoin(目前Hive的优化器不能自动优化MapJoin)。其中tablelist可以是一个表,或以逗号连接的表的列表。tablelist中的表将会读入内存,应该将小表写在这里。

PS:有用户说MapJoin在子查询中可能出现未知BUG。在大表和小表做笛卡尔积时,规避笛卡尔积的方法是,给Join添加一个Join key,原理很简单:将小表扩充一列join key,并将小表的条目复制数倍,join key各不相同;将大表扩充一列join key为随机数。

怎样写exist in子句?

Hive不支持where子句中的子查询,SQL常用的exist in子句需要改写。这一改写相对简单。考虑以下SQL查询语句:

SELECT a.key, a.value

FROM a

WHERE a.key in

(SELECT b.key

FROM B);

可以改写为

SELECT a.key, a.value

FROM a LEFT OUTER JOIN b ON (a.key = b.key)

WHERE b.key <> NULL;

一个更高效的实现是利用left semi join改写为:

SELECT a.key, a.val

FROM a LEFT SEMI JOIN b on (a.key = b.key);

left semi join是0.5.0以上版本的特性。

Hive怎样决定reducer个数?

Hadoop MapReduce程序中,reducer个数的设定极大影响执行效率,这使得Hive怎样决定reducer个数成为一个关键问题。遗憾的是Hive的估计机制很弱,不指定reducer个数的情况下,Hive会猜测确定一个reducer个数,基于以下两个设定:

1. hive.exec.reducers.bytes.per.reducer(默认为1000^3)

2. hive.exec.reducers.max(默认为999)

计算reducer数的公式很简单:

N=min(参数2,总输入数据量/参数1)

通常情况下,有必要手动指定reducer个数。考虑到map阶段的输出数据量通常会比输入有大幅减少,因此即使不设定reducer个数,重设参数2还是必要的。依据Hadoop的经验,可以将参数2设定为0.95*(集群中TaskTracker个数)。

合并MapReduce操作

Multi-group by

Multi-group by是Hive的一个非常好的特性,它使得Hive中利用中间结果变得非常方便。例如,

FROM (SELECT a.status, b.school, b.gender

FROM status_updates a JOIN profiles b

ON (a.userid = b.userid and

a.ds='2009-03-20' )

) subq1

INSERT OVERWRITE TABLE gender_summary

PARTITION(ds='2009-03-20')

SELECT subq1.gender, COUNT(1) GROUP BY subq1.gender

INSERT OVERWRITE TABLE school_summary

PARTITION(ds='2009-03-20')

SELECT subq1.school, COUNT(1) GROUP BY subq1.school

上述查询语句使用了Multi-group by特性连续group by了2次数据,使用不同的group by key。这一特性可以减少一次MapReduce操作。

Multi-distinct

Multi-distinct是淘宝开发的另一个multi-xxx特性,使用Multi-distinct可以在同一查询/子查询中使用多个distinct,这同样减少了多次MapReduce操作。

hive 参数调优手册 hive执行过程 1. reduce 个数设置 方法1.调整hive.exec.reducers.bytes.per.reducer和hive.exec.reducers.max hive.exec.reducers.bytes.per.reducer(每个reduce任务处理的数据量,默认为1G) hive.exec.reducers.max(每个任务最大的reduc... 阅读详情

相关推荐

汽车ECU诊断入门:手把手教你用UDS协议(ISO14229)读取和清除故障码

本文详细介绍了如何使用UDS协议(ISO14229)进行汽车ECU诊断,包括故障码读取与清除的完整流程。从诊断环境搭建、UDS协议基础到实战案例分析,手把手教你掌握0x19诊断服务、安全访问机制等核心技能,适用于汽车电子工程师和诊断开发人员。

weixin_33701251的博客 450

mysql semi join详解_MySQL中的semi-join

http://www.linuxidc.com/Linux/2015-05/117523.htm1. 背景介绍什么是semi-join?所谓的semi-join是指semi-join子查询。 当一张表在另一张表找到匹配的记录之后,半连接(semi-jion)返回第一张表中的记录。与条件连接相反,即使在右节点中找到几条匹配的记录,左节点 的表也只会返回一条记录。另外,右节点的表一条记录也不会返回。半...

weixin_28769407的博客 4031

保姆级教程:在通达信V7.611上配置欧奈尔RPS曲线(附完整公式与每日更新流程)

本文提供通达信V7.611配置欧奈尔RPS曲线的保姆级教程,涵盖从环境准备、基础设置到核心公式配置的全流程。详细讲解如何创建股票池、编写EXTRS基础公式及RPS显示公式,并附每日更新流程与实战应用技巧,帮助投资者精准捕捉强势股。

weixin_30000735的博客 458

hive之left semi join(左半连接)使用方法

目录 一、建表数据准备 二、语法 三、left semi join例子 四、left semi join、join、left join的区别 1、left semi join 2、left join 3、join 结语 一、建表数据准备 参考hive之full outer join(全连接)使用方法_IMezZ的博客-优快云博客目录介绍语法例子创建顾客表:customers创建订单表:ordersfull outer join语句 left join + union + right

ImezZ 2万+

OptiSystem仿真:波分与时分复用混合光网络的设计与性能优化

本文详细介绍了如何利用OptiSystem软件设计与优化波分复用与时分复用混合光网络。通过构建四路波分乘以四路时分的系统模型,文章阐述了从信源生成、复用合并、光纤传输到信号解复用与性能评估的全流程,并重点探讨了对抗色散、优化器件参数及探索高级调制格式等核心性能优化策略,为应对未来海量数据需求提供了高效、可行的仿真解决方案。

pink的博客 1106

7、复杂分布式水文模型的两阶段代理参数校准框架

本文提出了一种针对复杂分布式水文模型的两阶段代理参数校准框架,旨在解决可变入渗能力模型(VIC)在参数校准过程中计算成本高、耗时长的问题。该框架结合AdaBoost与反向传播神经网络(BPNN)构建高精度代理模型,并引入ε-NSGA II多目标优化算法加速搜索最优参数集。通过在兰江流域和湘江流域的实验验证,该方法在校准效率上提升了约20倍,同时保持了高模拟精度(NSE接近1,Bias接近0)。框架采用两阶段设计:第一阶段(SM-I)快速筛选关键参数范围,第二阶段(SM-II)进行高精度预测,显著减少了无效计

apple5的专栏 86

PostgreSQL之SEMI-JOIN半连接

Semi-Join半连接,当外表在内表中找到匹配的记录之后,Semi-Join会返回外表中的记录。但即使在内表中找到多条匹配的记录,外表也只会返回已经存在于外表中的记录。而对于子查询,外表的每个符合条件的元组都要执行一轮子查询,效率比较低下。此时使用半连接操作优化子查询,会减少查询次数,提高查询性能。其主要思路是将子查询上拉到父查询中,这样内表和外表是并列关系,外表的每个符合条件的元组,只需要在内表中找符合条件的元组即可,所以效率会大大提高。当参与等值JOIN的表达式存在有重复值。

★【World Of Moshow 郑锴】★ 2406

R3LIVE项目实战(3) —双目相机与激光雷达 lidar_camera_calib联合标定

lidar_camera_calib是一个在无目标环境中,用于高分辨率LiDAR(例如Livox)和摄像机之间准确的外部标定工具。我们的算法可以在室内和室外场景中运行,并且只需要场景中的边缘信息。如果场景适合,我们可以实现类似于或甚至超过基于目标的方法的像素级准确度。我们使用标定的外部参数给点云上色,并与实际图像进行比较。A和C是点云的局部放大视图。B和D是与A和C中的点云对应的摄像机图像的部分。

几度春风里的博客 4057

写好hive程序的五个提示

使用Hive可以高效而又快速地编写复杂的MapReduce查询逻辑。但是某些情况下,因为不熟悉数据特性,或没有遵循Hive的优化约定,Hive计算任务会变得非常低效,甚至无法得到结果。一个”好”的Hive程序仍然需要对Hive运行机制有深入的了解。 有一些大家比较熟悉的优化约定包括:Join中需要将大表写在靠右的位置;尽量使用UDF而不是transfrom……诸如此类。下面...

weixin_33804990的博客 220

损失函数大汇总(六十一)(Signed Distance Map Loss附公式推导与代码)

摘要 本文介绍了Signed Distance Map (SDM) Loss,一种将形状先验直接融入分割任务的方法。SDM将每个像素表示为到目标边界的带符号距离(内部为负,外部为正),相比二值mask能更连续地表达形状几何信息。SDM Loss的核心思想是让网络学习这个隐式形状场,通过可微的Heaviside函数近似将SDM转换为分割结果。文中重点分析了一种product-based regression loss,它能同时关注距离数值和内外符号的正确性,对边界区域尤为敏感。SDM Loss通常与传统的分割

悦学共鸣,温柔以待,汇聚光芒,共同成长 186

nicegui 可视化扩展库

总体来说,这段代码使用nicegui库创建了一个具有一些基本UI元素的界面,并使用扩展库来实现更多的布局功能。这段代码使用了nicegui库创建了一个UI界面。函数导入了一个扩展库,用于实现更多的布局功能。然后又使用了一个行布局,并添加了两个按钮(在UI界面中,使用了一个卡片(在行布局中依次添加了一个标签(在卡片中使用了一个头像(接下来使用了一个行布局(设置了背景颜色为绿色。设置了居中对齐和红色。设置了间距和字体大小。设置了居中对齐和样式。设置了按钮的对齐方式。

东方佑 1019

zz写好Hive 程序的五个提示

使用Hive可以高效而又快速地编写复杂的MapReduce查询逻辑。但是某些情况下,因为不熟悉数据特性,或没有遵循Hive的优化约定,Hive计算任务会变得非常低效,甚至无法得到结果。一个”好”的Hive程序仍然需要对Hive运行机制有深入的了解。 有一些大家比较熟悉的优化约定包括:Join中需要将大表写在靠右的位置;尽量使用UDF而不是transfrom……诸如此类。下面讨论5个性能和逻辑相关的...

weixin_33905756的博客 88

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Hive相关文章

下面是关于Hive的一些文章,欢迎推荐更多的关于Hive的理论、实战好文章! Apache Hive https://cwiki.apache.org/confluence/display/Hive/Home -> https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL -> https://cwiki.apa

Mac Track 1228

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

【hive】写好hive程序的五个启示

使用Hive可以高效而又快速地编写复杂的MapReduce查询逻辑。但是某些情况下,因为不熟悉数据特性,或没有遵循Hive的优化约定,Hive计算任务会变得非常低效,甚至无法得到结果。一个”好”的Hive程序仍然需要对Hive运行机制有深入的了解。 有一些大家比较熟悉的优化约定包括:Join中需要将大表写在靠右的位置;尽量使用UDF而不是transfrom……诸如此类。下面讨论5个性能和逻辑相关

shuhuai007的专栏 1248
上一篇: Hive 优化
下一篇: 简单说说MapReduce, Tez, Spark
Kelvin-Liang
博客等级 码龄18年 9粉丝 32原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值