hive优化

最近使用hive一个多月下来(终于完成第一期数据分析迁移工作了),当时使用的0.8的版本(现在最新版本是0.8.1),一个多月下来收获很多。从安装环境、

调试、开发、业务理解、技术攻关、业务实现等,一一都体验了一把!

总的来说,除了目前网上所介绍的常规hive使用和优化外。

因为目前hive只支持0.20的相关版本,所以我们的环境还是使用的0.20版本的hadoop来进行搭建。
使用hive和hadoop是一种综合能力的体现,之前我在使用的过程当中,还涉及到很多系统层面的问题。如果让hive和hadoop结合的更紧密,个人认为是从以下几个角度进行:
第一:hive的类SQL语句本身进行调优
第二:就是hive的参数调优
第三:hadoop里的hdfs的参数调优(存储格式、压缩格式、RPC调用、连接数控制)
第四:hadoop里的map/reduce的调优(datanode间的数据传输、处理大小、每个child的相关JVM设置等)
第五:就是hadoop环境里的网络传输的调优(硬件环境)
第六:就是hdfs的存储格式调优(文本格式、顺序格式等)
第七:操作系统层面的磁盘I/O调优(多路复用等)
第八:操作系统层面的网络调优(缓冲区大小、连接数放大等)
第九:操作系统层面的内存调优(虚拟内存设置、内存控制等)
第十:hadoop的容错机制的掌握,因为正常的运行到没什么,怕就是出现异常时,有相应的应对方案(调度器、队列等)
第十一:hadoop的管理(包括datanode失效、namenode失效、加入或删除datanode、负载均衡、集群等)

另外网上更多的是基于SUN的JVM来搭建hadoop环境,但我在使用的过程中是用jrockit的JVM来搭建hadooop环境,主要是考虑到目前在jrockit 6.0的版本上性能比较强劲(体现在网络传输、线程、GC回收等)。

另一方面是使用到了多种程序语言,如SQL(不过还是跟真正在数据库的SQL语法有区别的)、java、python(还好之前有用过python做过开发)、shell等。
现在先说说hive,毕竟在这次的开发过程中,hive使用比例很大。关于hive其中有些参数的使用和搭配,目前我还在测试过程当中(几个关键参数),以后再详细讲解。
hive个人觉得更适合做一些聚合场景的相关处理,其自定义函数UDAF更能体现这样的一个特点。
关于UDF这种自定义函数比较适合做一些字段上的转换处理,例如一个Text类型转换成一个array类型;另外就是可以实现更为丰富的解码方式,如在URL中有些参数使用了UTF-8编码或者GBK编码的方式。
还支持自定义的map/reduce方式(相关关键字)。

/*mapjoin*/这种标识(这里描述有误,mapjoin是提供了一种提高join的方式)。
支持多种存储格式,如:行格式、文件格式等,hdfs里也支持多种存储格式。
支持导入/导出数据,这里需要提醒下,使用hive命令的导出,会把一行数据进行合并,也就看不出字段;所以一般都采用 hive -e 'select * from t' >> 123.txt这样形式命令,才能使导出的字段由空格进行分割(后来验证过,这是我的一个使用失误,其实里面还是有\001的符号,只是显示的时候不显示而已,所以两种方式都适合)。
NULL和空值的区别,在hive的处理时需要注意(特别是与python这样的脚本结合使用,另外还有在python中的字段切割问题)。

现在总结下hive不擅长的地方
因为我这次的开发任务是将有些用SAS计算的任务迁移到hadoop上面进行数据分析,因为SAS上有很多强劲的功能,在做数据分析时很有帮助;但在hive上面就没有这样的功能了。举例如下:
SAS上有类似与游标的概念的东东,可以操作记录行,并对记录里一某个字段进行移动(如将某个字段移到前一条记录上面)
SAS有排重功能(也就是根据几个字段,去掉重复数据)
SAS可以轻松进行分组后,前取每个分组里的前10条记录
SAS不好的地方就是进行解码转换(如经过UTF-8或者GBK编码的方式,这里主要指的是URL里,就比较麻烦)
常见场景等,另外还有几种情况描述起来较为复杂,这里略之。

关于之前描述的前三种情况,如果只是简单的用HIVE本身的SQL语句方式那是很难实现的,三种情况的共同点就是如何操作一行记录。
hadoop里有一种方式叫streaming,就是一行一行的读取,然后通过脚本的方式进行处理,在这里刚好hive是支持脚本的,所以可以用脚本来实现操作一行记录(我这里使用的是python脚本)
关于排重功能,在SAS实现的原理基本就是按照几个关键字进行排序,然后进行排重处理(因为排序之后,重复的数据肯定是在一起的,这样做排重处理就比较方便了)。
所以在hive这边,首先也是进行按几个关键字排序,然后采用脚本方式进行去掉重复数据。
虽然脚本的运行时间比纯java要慢,但是因为脚本满足了业务需求,所以运行慢的缺陷我们是可以忽略的,毕竟hive后期调优中,也有关键字的支持map、reduce。
关于如何用脚本进行取每个分组的前10条记录(给一个简单的业务场景,取每个地区(按上海、北京、深圳、广州等)的销售量前十名的业务员),由读者自己可以思考下。
第四个场景,关于URL参数解码问题,很简单,就自定义一个UDF,然后通过java的方式来进行解决。这里有个比较麻烦的地方就是如何区分出这个URL是用UTF-8编码还是GBK编码。

另补充两点:

就是一个hiveSQL脚本,最好别太多SQL,不然会导致一些异常情况出现。最好进行拆分。如下:

1.sql

1_1.sql

1_2.sql

形式,这样方便在shell里进行控制。
第二个就是多看源码(hadoop源码、hive源码),发现有些参数配置,都在程序里,但文档中并没有体现。

这些就是大致使用下来的感觉,后续还有新的体验,再增加吧!
如有不懂的地方,可以提问。

这里是再次补充下这个项目有关hive的使用问题:

 首先是去重问题,后来经过反复测试发现,map个数不能是多个,不然前一个split的最后一条记录,与后一个split的第一条记录,无法进行匹配去重。

所以当碰到这样的问题时,MR的优势将无法体现出来,目前采用的是最简单的方法就是map个数和redce个数都设置成1

但是不知道MR其中有一种chain方式是否可行。

综上所述,当碰到这种上下记录有关联的时候,如何利用MR这种模式,还是要好好琢磨和不断的测试的。

你可能感兴趣的:(hive优化)