hive使用小结
2016-02-26 17:34
537 查看
hive各版本主要特征
Hive 各版本关键新特性(Key New Feature)介绍官网下载页面的介绍
hive基础
命令行接口
hive提供的用户接口包括:CLI、Client、WebUI几种方式,我们平常主要使用CLI方式,未来集群升级之后可能会有提供可视化的界面允许我们直接从WebUi访问。早期的hive版本主要使用HIVE CLI(old),之后发展为使用BeeLine
CLI(new),目前SA已经切换为使用beeline。在CLI模式下,我们常用的命令包括:
set
用于查看和设置hive的配置参数,例如控制reduce数量、控制压缩格式等。
add jars
添加额外的jar包到hive运行环境,例如自定义了UDF/UDAF的jar包,可以通过这种方式添加
!
hive> ! ls;可以在hive里边直接运行shell命令
dfs
例如运行hive> dfs -ls /src/gamein/g4_sdc/;这样就不用开额外的session去运行hadoop fs -ls
Hive Sql
hive sql语法和我们使用的mysql语法基本类似,具体可以参考官网【DDL】和【DML】,支持的运算符,字符串、数字、日期等方法,内建的UDF,UDAF,UDTF参考官方手册【UDF-WIKI】。UDTF我们用的比较少,但需要的情况下会非常好用,例如LateralView和Explode的配合使用可以展开数据【一个lateral view的例子】。除了使用UDF-WIKI查看hive的函数,也可以在命令行里边查看。
hive> show functions; --显示所有函数
hive> describe function substr; --查看函数[substr]的用法
OK
substr(str, pos[, len]) - returns the substring of str that starts at pos and is of length len orsubstr(bin, pos[, len]) - returns the slice of byte array that starts at pos and is of length len
Time taken: 1.368 seconds, Fetched: 1 row(s)
这个功能不像mysql那样强大,mysql下支持“?”语法,例如在mysql命令行下查看load data的使用语法
mysql> ? load data;
Hive Serde
我们使用hive Serde的频率未来会越来越高。hive serde是指数据IO的序列化和反序列化,主要作用是解析hdfs文件,识别其中的格式。早期的一些hive-serde包已经废弃,最新文档参考【官方serde-wiki】,目前hive支持的内建serde如下,未来我们升级到hive1.0之后,下面这些就全部可以用了。Avro (Hive 0.9.1 and later)
ORC (Hive 0.11 and later)
RegEx
Thrift
Parquet (Hive 0.13 and later)
CSV (Hive 0.14 and later)
JsonSerDe (Hive 0.12 and later inhcatalog-core)
有很多团队直接用hive sql 直接进行数据处理,其核心就是自定义Serde,US那边比我们用的多一些。我们使用hive-serde的最典型场景就是快速查询、过滤出今天的hdfs日志, 使用的是RegEx(正则表达式)来按日志类型(登陆、退出、充值等)进行某些统计(如人数、充值额),这个效率会比直接使用hadoop fs -text快很多,具体使用情况参考另外一篇ETL内部的wiki《hdfs上的数据查询方法》。
说到文件格式解析,需要注意hive日志的默认分隔符的设置,默认情况如下:
字段分隔符:'\x01',导出为普通文本之后,可以用cat -A 来查看,在linux shell下能看到分隔符显示成^A
mapItem分隔符:'\x02',即字典的KV项与项之间的分隔符,(kv'\x02'kv)
mapKv分隔符:'\x03',即字典的KV内之间的分隔符(k\x02v)
掌握这些有助于我们将hive数据导入、导出为普通文本的时候避免出错。
Transform & UDF & UDAF
transform如 果想在hive中嵌入自定义的mapreduce脚本,就可以使用transform这种模式来完成一些复杂的操作,也能完成UDF、UDAF的一些功 能。BI用的比较少,US的童鞋之前用的多一些。transform执行效率其实不高,但贵在可以用python快速的完成某个功能编写,这比使用 JAVA编写UDF/UDAF的扩展类、并打包发布来的快很多。下面是一个hive+python的例子。利用transform功能我们很容易完成诸 如,将数据组合成数组、有序字典和其他一些复杂的日志拆分功能。
【参考手册-transform】
UDF & UDAF
自 定义函数UDF和自定义聚集函数UDAF,会依赖一些jar包,并必须继承相应的接口。相应的具体例子,大家可以在网上自行搜索,编写的过程和 MapReduce代码非常相似。UDF和UDAF的执行效率比Transform快一些。我们在etl_hadoop_lib项目中有一些例子,比如 MaxRow方法介绍如下:MaxRow(compare_col,col1,col2,col3....) 根据指定的compare列进行比较,返回最大行,包含值compare-col,col1,col2...返回结构是struct,需要根据
struct结构取值。
Transform方式和UDF、UDAF的比较可以参照上图右。
HIVE优化
理解HIVE
hive详细的设计框架如下。经过一定的发展,现在形成了如下的层次
最顶层是sql解析和执行计划;中间层是计算框架,已经从最初的MapReduce发展为支持基于DAG的Tez和SPARK。最底层是数据的存储,从最初的textfile/sequencefile扩展到更快更优的格式,如ORC File。
Hive on Mapreduce
在 hive主要使用MR做执行引擎,Tez是对MR执行过程的优化。所以,我们对hive的执行效率的优化,核心需要对Hive实际执行环境的 MapReduce过程进行优化。MapReduce的详细过程见下图(参考《hadoop权威指南》),记住这张图,能帮我们很多忙,比如数据倾斜引起 的单个reduce太忙,表现就是reduce到98%、99%之后一直卡住,为了让数据更均匀地分散,需要将key散列到更多的partition。理 解MapReduce的各个环节,也可以帮我们理解Hive发展的优化方向,例如tez将传统reduceto localfile -> copy -> map ->reduce这些环节所见为 reduce -> reduce,另外考虑到hive要读写hdfs,更好的压缩、解压效率需要使用更优的文件格式如ORC File等,而Spark则直接避免数据写硬盘,而改用内存。
Hive JOIN
理解hive的集中join方式,能够帮助我们更好的理解大部分的数据关联问题,有兴趣的童鞋尝试自己用MapReduce实现hive-join类似的功能。据说面试官们特别喜欢拿hive-join来考察对方对MR的理解。reduce-side join ( common join)
注意执行顺序,关联相同的key可以减少一次MapReduce的执行过程。
map join
将其中一张小表全部载入内存。载入内存有数据大小的限制。偶尔这个是触发报错的原因。hive在某个版本之后实现了bloom filter,来扩展内存的限制。
bucket map join
left-semi join
关于hive-join的具体过程可以参考【官方LanguageManual JoinOptimization】【join详解】【Hive
JOIN使用详解】。顺便谈一下hive的排序,有sort by / order by /distribute by/ cluster by ,其中的差别参考【手册-sortby】
hive-sql的优化可以参考这篇文章,讲的还不错,里边有原理和详细的hive参数的设置【深入浅出数据仓库中SQL性能优化之Hive篇】。hive核心的参数设置,上面几篇文章都有,本文不再做具体的参数讲解。
文件格式与压缩
hive 的数据是存储在hdfs上,默认都是备份3份。采用不同的压缩方法,对于磁盘的要求是差别非常大。另外,hive语句的执行效率与文件格式的关系也非常 大。总的来说,如果压缩的特别小,解压效率就会差一些,最终需要在压缩、解压效率之间取得一个平衡。下面这个图通过圆圈面积的大小形象地描述了不同文件格 式如TextFile、SequenceFile、RCFILE、AVRO、PARQUET、ORCFile与不同压缩算法gz、snappy、 bzip2、Lzo组合情况下的直观比例。我 们肉眼能看的只有Text未压缩的格式。但textfile压缩之后,就不是splitable的,也就是在MapR的执行过程中只能当成一大块,这样会 极大的影响效率。从性能的角度讲,以后的日志格式会更多的选择ORC(RCFile的改进) , Parquet (google传说中3秒查询1PB数据的Dremel的开源实现版)。有兴趣的童鞋可以仔细的研究一下这两种文件存储。
我们目前的中间结果是用sequencefile存储的,在MapReduce的脚本里边选用的压缩是gz(压缩率高、解压慢),hive默认是snappy。未来可能会做调整为ORC + tez引擎,以进一步提高hive的执行速度。
HIVE执行引擎的进化:Hive/Tez
Tez是Apache开源的支持DAG作业的计算框架,它直接源于MapReduce框架。中文介绍可以看董的博客《Apache Tez:一个运行在YARN之上支持DAG作业的计算框架》。下面的这张图以一条sql语句为例,描述了hive/mr与hive/tez的主要区别。目前的hive版本已经支持tez引擎,只要下面的一条hive命令就可以完成engine的切换。
hive> set hive.execution.engine=tez;
另 外,hive其实也是支持spark引擎的。本文不对spark做额外的介绍,但hive-on-spark的性能并不是很理想,其性能不如直接使用 SPARK-SQL效率高。我们现在已经有部分sql已经改用SAPRK-SQL来执行了,碰到的SPARK-SQL的主要问题包括:1. 特别吃内存,需要对不同作业的内存参数分别配置;2. 对于数据量很大的情况,容易内存溢出,即便内存不溢出,执行效率也不是很理想,例如计算所有手游的沉默用户,计算慢的你会想哭。
我们现在的 hive任务的执行引擎已经默认是tez了,但还没有结合ORCFile进行测试。对于小作业,可以直接用spark-sql,数据量特别大的作业,目前 更优的选择是tez+orcFile的运行模式。那我们什么时候需要改变呢,除非spark未来寄出更多的大招。下面是Hortnworks,tez的主 要开发优化者,对于hive/tez,hive/spark,spark-sql做过的一个性能测试比较的一个截图片段,最终结论大概是spark是狠 牛,但hive-tez并不虚,看hive-tez如何变100X。Spark-Sql、Cloudera-impala、Hortnwork-tez都
说自己是最牛的,这个需要我们在实际环境中、根据机器和数据自行比较判定。
NEXT
hive的过去、现在、与未来都在下面这张图了。遇到不熟悉的名词,请自行google,即便是用的百度,也不要告诉SA,会被他们鄙视的。不好意思,写的有点长,歪楼了。也许用不了太长时间,hive真能进入sub-second的时代。也可能那个时候不叫hive,或者是spark-sql,或者是别的什么。为了好好鼓励大家使用hive,祭出最后一张大招图。
其他
类似工具
impalacloudera 开源的一个‘interactive’ SQL query engine,能查询存储在Hadoop的HDFS和HBase中的PB级大数据,可以基于yarn运行,部署起来还是比较方便的,之前组内有发布过相关 的研究资料。Cloudera的一篇官方博客在2016年4月发布的数据测试说,impala执行sql的实时响应可以秒杀Spark-Sql、 hive-tez,见《New
SQL Benchmarks: Apache Impala (incubating) Uniquely Delivers Analytic Database Performance》,不贴图了,免得以后不想用hive。impala没有使用hive+mapreduce的框架,而是受到Google的Dremel启发,借鉴了MPP并行数据库的思想。(果然,抄google没错)。
Drill
官网描述可以“Query any non-relational datastore”,国内好像不是很火了,验证了一句话,什么都可以,就是什么都不可以。
Presto
an open source ‘interactive’ SQL query engine built by facebook。支持PB字节的交互式数据查询。不适用MapReduce框架。目前Airbnb 和 Dropbox、好像美团也在使用Presto。
shark -> Spark-Sql
shark估计要跪,属于spark子项目,但渐被spark-sql取代。国内的Spark社区灰常火热,大家都觉得这是未来,Spark-sql估计会使用的越来越多。
BigSql (ibm提供的一个分布式sql查询引擎,不开源,资料也少,貌似大家就不用关心了)
Apache Phoenix(也是一个sql引擎,主要用来查hbase的,好像不用在这说)
HAWQ(EMC提供,不开源)
个人感觉重点关注一下spark-sql,impala就可以。
与其他数据库的交互
与hbase的交互
我 们可以通过hive来操作hbase。包括读取hbase数据,以及通过hive-sql更新hive表的方式来更新hbase,前提是先建立hive表 与hbase表的映射关系。通常有两种方式:1. Hbase的一个列族映射为hive的一个Map,map里边包含所有的列信息。2. 将Hbase每个列族的所有列,分别映射为hive表的一列。各有优劣,视实际情况而定。hive与hbase的集成方法参考《Hive-HBaseIntegration》。另外,hive还能帮助生成HFile,目前有一定的限制条件,比如只允许只有个ColumnFamily。生成HFile之后,采用Bulkload的方法,是目前大批量数据刷写Hhase最快的方法。
与Mysql的交互
使 用最广泛的工具是Sqoop,启动的是一个MapReduce的过程。“Apache Sqoop(TM) is a tool designed for efficiently transferring bulk data between Apache Hadoop and structured datastores such as relational databases.sqoop”。sqoop不仅限于hive,其实也能用于hbase等。最新稳定版是1.4.6,详细的参数解释和使用方法参考官方 《指引文档-sqoop》我们平时遇到的坑主要在于对非textfile的hdfs文件如sequencefile是否支持、对NULL数据的如何处理等。
说明
1. 全文的图片都是抄的,之前收藏剪辑的,不记得来源了。大概资料来源:《hadoop权威指南》《hadoop实战》《hadoop技术内幕》
董西成的博客
Hortnworks、Cloudera的博客
Hadoop Summit上面的一些ppt
google/百度的图片
2. sa的hive入口命令解释
hive --config /home/hadoop/hiveconf/metastore/sy_sdc/ \
--auxpath /home/hadoop/hbase/lib \ # 如果要在hive里边访问hbase,需要添加hbase包,
-hiveconf hive.new.job.grouping.set.cardinality=32 \ #cube维度的上限,如果有N个维度,就需要设置上限>2^N
-hiveconf hive.exec.scratchdir=/tmp/hive-${whoami} ##调度器账号和个人账号需要使用不同的临时目录
3. 导出select结果
一般用insert overwrite local directory的方法,在python下使用os.popen()方法,还会读取到额外的hive执行过程的信息。
相关文章推荐
- 分享Hive的一份胶片资料
- MySQL 优化
- Hadoop生态上几个技术的关系与区别:hive、pig、hbase 关系与区别
- Google排名优化的几个影响因素
- DB2优化(简易版)
- Mysql limit 优化,百万至千万级快速分页 复合索引的引用并应用于轻量级框架
- C#中尾递归的使用、优化及编译器优化
- 对优化Ruby on Rails性能的一些办法的探究
- 优化Ruby脚本效率实例分享
- Asp编码优化技巧
- 如何监测和优化OLAP数据库
- mysql -参数thread_cache_size优化方法 小结
- 深入学习SQL Server聚合函数算法优化技巧
- MySQL常见的底层优化操作教程及相关建议
- 详解mysql的limit经典用法及优化实例
- 数据库学习建议之提高数据库速度的十条建议
- oracle数据库sql的优化总结
- SQL语句优化提高数据库性能
- SQL优化经验总结
- SQL优化技巧指南