hive使用小结

来源:互联网 发布:网络信息英文怎么写 编辑:程序博客网 时间:2024/06/06 08:29

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我们用的比较少,但需要的情况下会非常好用,例如Lateral View和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将传统reduce to 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,祭出最后一张大招图。

其他

类似工具

  • impala

cloudera 开源的一个‘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执行过程的信息。


0 0
原创粉丝点击