文档章节

Hive TOP N 实现方法

Avner
 Avner
发布于 2017/08/11 15:21
字数 1282
阅读 57
收藏 0
点赞 0
评论 0

本文主要转至:http://www.cnblogs.com/skyl/p/4776083.html

1).Hive中Select Top N的实现

Hive中使用 Order by + Limit 可以很容易地实现Select Top N。

hive默认的order by实现只会用1个reduce做全局排序,这在数据量大的时候job运行效率非常低。hive在0.12版本引入了parallel order by,也就是通过sampling的方式实现并行(即基于TotalOrderPartitioner)。具体开关参数是hive.optimize.sampling.orderby。但是如果使用这个参数还是很可能碰到问题的:

  • 首先如果order by字段本身取值范围过少,会造成Split points are out of order错误。这是因为,假设job中reduce数量为r的话,那么TotalOrderPartitioner需要order by字段的取值至少要有r - 1个。那么这样一来还需要关心reduce数量,增加了开发负担,而且如果把reduce数量设的很小,优化的效果就不太明显了。
  • 其次,设置这个参数还可能造成聚会函数出错,这个问题只在比较新的hive版本中解决了。

实际上,如果只是取top n而非全局排序,只需要使用sort by col limit n的写法就能达到很好的效果。sort by语法本身保证每个reduce内数据有序,这样就等于是做并行排序。而limit n则保证两件事:一方面是使得并行排序时每个reduce的输出记录数只是n,也就是先在每个reduce内部做top n(可以explain一下看看执行计划更加清楚);另外一方面,等局部top n完成之后,再起一轮job,用1个reduce做全局top n,这个时候虽然不是并行排序,但是处理的数据量也已经大大减少,不会造成效率问题了。当然,如果自己实现mapreduce,可以在mapper任务内维护最小最大堆,直接在map端实现并行的top n,再输出给1个reducer做全局top n,只需要一轮job即可完成。不过如果n的大小没有限制很可能会撑爆内存,而且即使没有内存问题,实现也比较复杂,所以hive中没有实现这样的Operator,而是用上面描述的方式解决。毕竟在reduce端做top n,排序问题就已经在MR框架层面解决了,只需要考虑limit即可。

从执行计划explain中可以看出Sort by Limit N启动了两个MR Job。第一个Job是在每个Reduce中做局部排序,然后分别取Top N。假设启动了M个reduce,第二个Job再对M个Reduce分别局部排好序的总计M * N条数据做全局排序,再取最终的Top N,从而得到想要的结果。这样就可以大大提高Select Top N的效率。

set mapred.reduce.tasks=3;
select * from tea sort by age limit 3;

除了对全部数据取top n,分组top n也是常见场景,比如学生成绩表取每个学科前三名,用户点击流数据取每个用户最早的几个点击等等。如果每个分组需要排序的数据量不大,那么可以用窗口函数解决,或者在不支持窗口函数的比较老的hive版本自己实现udf。但是如果每个分组本身很大,还是会很慢。如果追求性能的话,同样可以借鉴sort by limit的写法,在分组个数不多且固定的情况下直接将分组写死。比如“取每个性别访问次数最多的10人”类似这样的情景,就可以拆解为“男性访问次数最多的10人 + 女性访问次数最多的10人”。

 

2).Hive中分组  Select Top N的实现;

drop table tmp_users_time;  
create table tmp_users_time   
as  
select * from  
(  
  select u.*,row_numwer() over(distribute by grade sort by score desc) sn  
  from users u  
)tu  
where tu.sn > 2;  

或者

insert into table users_time_top  
select tu.grade,tu.score  
from  
(  
  select u.*,row_number() over(distribute by grade sort by score desc) sn  
  from users u  
)tu  
where tu.sn > 2;  

 

3).hive中的分号字符 -- 此部分内容在最新版的HIVE中已修复;

分号是SQL语句结束标记,在HiveQL中也是,但是在HiveQL中,对分号的识别没有那么智慧,例如:

hive> select concat(';','a');
--会报异常NoViableAltException(-1@[]),解决方案:
最新版的HIVE输出的结果为:';a'

hive> select concat('\073','a');
--分号的ASCII值是59,八进制为073.只能使用八进制,对于十六进制无效
--concat(str1,str2)作用为拼接字符串
最新版Hive的输出结果:';a'

3).Hive客户端默认配置

以下操作均可在$HIVE_HOME/bin/.hiverc文件中保存,设置为默认参数:

set hive.mapred.mode=strict;
//开启strict模式,以下情况报错:(1)没有limit限制的order by语句.(2)动态分区插入

set hive.cli.print.current.db=true;
//显示当前工作的数据库

set hive.cli.print.header=true;
//显示列名

set mapred.reduce.tasks=3;
//设置reduce的个数

set hive.exec.reducers.bytes.per.reducer;
//多少字节开一个reducer,默认256000000

set hive.exec.dynamic.partition.mode=strict;
//该模式下必须指定一个静态分区

 

 

 

 

© 著作权归作者所有

共有 人打赏支持
Avner
粉丝 8
博文 42
码字总数 45068
作品 0
杭州
程序员
Hive JDBC——深入浅出学Hive(四)

目录: 初始Hive Hive安装与配置 Hive 内建操作符与函数开发 Hive JDBC hive参数 Hive 高级编程 Hive QL Hive Shell 基本操作 hive 优化 Hive体系结构 Hive的原理 第一部分:搭建Hive JDBC开...

东方神剑 ⋅ 2016/01/15 ⋅ 0

Hive JDBC开发步骤

第一部分:搭建Hive JDBC开发环境 搭建:Steps •新建工程hiveTest •导入Hive依赖的包 •Hive 命令行启动Thrift服务 •hive --service hiveserver & 第二部分:基本操作对象的介绍 Connecti...

linni ⋅ 2014/01/09 ⋅ 0

Hadoop Hive概念学习系列之hive里的用户定义函数UDF

Hive可以通过实现用户定义函数(User-Defined Functions,UDF)进行扩展(事实上,大多数Hive功能都是通过扩展UDF实现的)。想要开发UDF程序,需要继承org.apache.hadoop.ql.exec.UDF类,并重...

sjyttkl ⋅ 04/22 ⋅ 0

大数据环境中,根据一张表(idList)的数据去修改另一张表的数据(id_label),有没有比较高效的方法?

现在有一个类似的需求,在cloudera环境中,是根据一个表的数据去更新另一个表的对应的行的某个字段。 如在hive中有: 表A(字段有一个,为id),对应数据为(1,2); 表B(字段有两个,分别为...

码农曾 ⋅ 05/07 ⋅ 0

Pig、Hive 自定义输入输出分隔符以及Map、Array嵌套分隔符冲突问题

PIG中输入输出分隔符默认是制表符t,而到了hive中,默认变成了八进制的001, 也就是ASCII: ctrl - A Oct Dec Hex ASCIIChar 001 1 01 SOH (start of heading) 官方的解释说是尽量不和文中的...

xrzs ⋅ 2012/10/21 ⋅ 0

使用TPC-H对Hive测试

最近由于工作要求,需要对Hive进行一下测试。在一篇论文中看到使用TCP-H,上网查了一下还算是比较靠谱的一个基准测试程序,所以决定拿来一试。网上关于这方面的博客貌似很少(能力有限,没找...

vieky ⋅ 2014/12/05 ⋅ 0

利用sqoop1.6对mysql和hive进行同步的问题

问题1: 从mysql数据库中导入到hive中可以执行: sqoop import --connect jdbc:mysql://localhost/gamewave --username root --password 123456 --table log --hive-import -m 1 其中-m 1 参数......

aibati2008 ⋅ 2016/04/26 ⋅ 0

Sqoop从Oracle导入到Hive(小坑)

使用sqoop从oracel导入数据到hive数据错位,第一个想到的问题就是可能分隔符造成的, 默认使用'001'来切分字段,使用'n'来切分行,这一切看起来挺好,但是如果导入的内容中包含了'001'或者'...

莫问viva ⋅ 2016/12/01 ⋅ 0

使用TPC-H对Hive测试

最近由于工作要求,需要对Hive进行一下测试。在一篇论文中看到使用TCP-H,上网查了一下还算是比较靠谱的一个基准测试程序,所以决定拿来一试。网上关于这方面的博客貌似很少(能力有限,没找...

youting ⋅ 2014/12/03 ⋅ 4

Pig、Hive、MapReduce 解决分组 Top K 问题

问题: 有如下数据文件 city.txt (id, city, value) cat city.txt 1 wh 500 2 bj 600 3 wh 100 4 sh 400 5 wh 200 6 bj 100 7 sh 200 8 bj 300 9 sh 900 需要按 city 分组聚合,然后从每......

xrzs ⋅ 2012/10/26 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

高并发之Nginx的限流

首先Nginx的版本号有要求,最低为1.11.5 如果低于这个版本,在Nginx的配置中 upstream web_app { server 到达Ip1:端口 max_conns=10; server 到达Ip2:端口 max_conns=10; } server { listen ...

算法之名 ⋅ 今天 ⋅ 0

Spring | IOC AOP 注解 简单使用

写在前面的话 很久没更新笔记了,有人会抱怨:小冯啊,你是不是在偷懒啊,没有学习了。老哥,真的冤枉:我觉得我自己很菜,还在努力学习呢,正在学习Vue.js做管理系统呢。即便这样,我还是不...

Wenyi_Feng ⋅ 今天 ⋅ 0

博客迁移到 https://www.jianshu.com/u/aa501451a235

博客迁移到 https://www.jianshu.com/u/aa501451a235 本博客不再更新

为为02 ⋅ 今天 ⋅ 0

win10怎么彻底关闭自动更新

win10自带的更新每天都很多,每一次下载都要占用大量网络,而且安装要等得时间也蛮久的。 工具/原料 Win10 方法/步骤 单击左下角开始菜单点击设置图标进入设置界面 在设置窗口中输入“服务”...

阿K1225 ⋅ 今天 ⋅ 0

Elasticsearch 6.3.0 SQL功能使用案例分享

The best elasticsearch highlevel java rest api-----bboss Elasticsearch 6.3.0 官方新推出的SQL检索插件非常不错,本文一个实际案例来介绍其使用方法。 1.代码中的sql检索 @Testpu...

bboss ⋅ 今天 ⋅ 0

informix数据库在linux中的安装以及用java/c/c++访问

一、安装前准备 安装JDK(略) 到IBM官网上下载informix软件:iif.12.10.FC9DE.linux-x86_64.tar放在某个大家都可以访问的目录比如:/mypkg,并解压到该目录下。 我也放到了百度云和天翼云上...

wangxuwei ⋅ 今天 ⋅ 0

PHP语言系统ZBLOG或许无法重现月光博客的闪耀历史[图]

最近在写博客,希望通过自己努力打造一个优秀的教育类主题博客,名动江湖,但是问题来了,现在写博客还有前途吗?面对强大的自媒体站点围剿,还有信心和可能型吗? 至于程序部分,我选择了P...

原创小博客 ⋅ 今天 ⋅ 0

IntelliJ IDEA 2018.1新特性

工欲善其事必先利其器,如果有一款IDE可以让你更高效地专注于开发以及源码阅读,为什么不试一试? 本文转载自:netty技术内幕 3月27日,jetbrains正式发布期待已久的IntelliJ IDEA 2018.1,再...

Romane ⋅ 今天 ⋅ 0

浅谈设计模式之工厂模式

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻...

佛系程序猿灬 ⋅ 今天 ⋅ 0

Dockerfile基础命令总结

FROM 指定使用的基础base image FROM scratch # 制作base image ,不使用任何基础imageFROM centos # 使用base imageFROM ubuntu:14.04 尽量使用官方的base image,为了安全 LABEL 描述作...

ExtreU ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部