Hive综述
Hive提供了一门简单的基于SQL的查询语言HQL,使得熟悉SQL的使用者可以很容易的执行随机查询和数据分析。同时HQL也支持传统的MapReduce编程模式,以扩展语言内建的功能,实现复杂的数据分析逻辑。
对于大多数查询,Hive编译器将产生多个map-reduce job,并将job提交到由参数mapred.job.tracker指定的map-reduce集群。Hadoop也允许在用户所在的本地机器运行map-reduce job,这对于运行在小数据集上的查询非常有效,这种情况下本地模式比集群模式查询速度明显更快,相反地,本地模式启动一个reducer,因此在大数据集上将变得更慢。Hive 0.7之后,可以通过命令SET mapred.job.tracker=local指定以本地模式运行Hive查询job,此时参数mapred.local.dir应该指向一个有效的本地路径,否则Hive job在分配本地磁盘空间的时候会抛出一个异常。在Hive 0.7之后,也支持自动的以本地模式运行map-reduce job,默认情况下是该功能是关闭的,通过命令SET hive.exec.mode.local.auto=true开启自动本地模式。自动本地模式开启时,Hive将分析map-reduce 查询job的输入数据大小,map tasks数量,reduce数量,如果job输入数据小于hive.exec.mode.local.auto.inputbytes.max(默认是128MB),map tasks数量小于hive.exe.mode.local.auto.tasks.max(默认是4),reduce tasks数量为1或者0,如上任何一个条件满足时,Hive将启用本地模式运行Hive查询job。注意因为Hadoop server节点和Hive client本地机器运行环境的差别(比如JVM版本,软件包版本差异),在运行本地模式时可能会出现未预料的异常。而且本地模式运行job是在Hive client的子JVM中执行,可以通过参数hive.mapred.local.mem指定子JVM可以使用的最大内存,默认值为0,表示由Hadoop决定子JVM能够使用的最大内存。
Hive采用log4j记录日志,默认日志不会显示在命令行界面中。Hive 0.13.0之前版本的记录级别是WARN,从0.13.0之后记录级别是INFO。日志被保存在/tmp/<user name>/hive.log目录下。可以通过文件./conf/hive-log4j.properties中参数hive.log.dir配置一个新的日志保存路径。日志可以通过在启动Hive client时设置参数,如bin/hive --hiveconf hive.root.logger=INFO,console在命令行显示日志,通过SET命令设置该参数不起作用,因为该参数是在创建Hive client时候初始化的。
Hive命令
可以通过命令,例如:CREATE TABLE invites (foo INT, bar STRING) PARTITIONED BY (ds STRING),创建Hive tables。PARTITIONED BY中指定的列是虚拟列,其并不保存在数据块中,而是保存在该数据块所在的数据分片路径中。默认情况下,表格采用文本输入格式,以^A为定界符。创建表时可以采用关键词row format delimited fields terminated by '\t',指定字段之间采用'\t'分割。表中的每一个字段支持COMMENT关键词(后接单引号字符串),为该字段添加注释。可以通过命令SHOW TABLES ‘in*’,显示Hive中的所有匹配正则表达式的表;DESCRIBE invites,显示表invites中的列。Hive表的表名可以重命名,列可以增加或者替换,例如命令:ALTER TABLE events RENAME TO sniff。当采用REPLACE COLUMNS替换所有已经存在的列时,并不会改变表中的数据,只是改变了表的schema。alter table命令还支持ADD COLUMNS操作:可以采用命令DROP TABLE invites,删除表。
Hive表的元数据信息保存在内置的数据库中,数据库在磁盘中的位置由配置参数javax.jdo.option.ConnectionURL决定,默认的地址是./metastore_db。默认情况下,metadata一次只能有一个用户访问。元数据可以保存在任何支持JPOX的数据库中,由javax.jdo.option.ConnectionURL和javax,jdo.option. ConnectionDriverName设置数据库的地址和驱动类。将来元数据可以由单独的server保存,使得多个节点能访问元数据。
Hive使用命令LOAD DATA LOCAL INPATH ‘./example.txt’ OVERWRITE INTO TABLE invites,将包含三列以^A分隔的本地文件example.txt加载到表invites中。LOCAL关键词表名是本地文件,如果没有该关键字,默认是从HDFS中加载。OVERWRITE关键词,表明已经存在的表将会被覆盖,如果没有该关键字,默认是将数据加载到表中。加载数据的时候也可以指定PARTITION,例如PARTITION (ds='2008-0815’)。
Hive支持SQL查询语句,select a.foo from table invites where a.ds=’2008-08-15’ group by a.foo。where关键词后面可以接一个或者多个逻辑表达式,group by关键词表示将查询结果中某一列相同的记录分成一组。Hive也支持将查询的结果保存到文件(local或者hdfs),例如命令:insert overwrite local directory '/tmp/out' select url from url_titles;Hive也支持将查询结果插入另一个表中,例如命令:insert overwrite table urls select url from url_titles。命令中的overwrite和local关键词如果没有,分别表示写hdfs文件,和不重建新的表格。Hive支持两个表之间的join操作,例如命令:from pokes t1 join invites t2 on (t1.bar = t2.bar) insert overwrite table events select t1.bar, t1.foo, t2.foo。Hive支持一次查询产生多个查询结果并分别保存到不同的表或者文件中,例如命令:from src insert table dest1 select src.* where src.key < 100
insert directory '/tmp/hdfsout' select src.value where src.key > 300;
Hive streaming支持用户自定义map和reduce操作函数,对查询产生的记录进行MapReduce变换操作。例如命令:insert table u_data_new select transform (userid, movieid, rating, unixtime) using 'python weekmapper.py' as (userid, movidid, rating, weekday) from u_data。
HQL细节点汇总
1. left semi join比inner join更高效,一旦左表中的记录在右表中找到匹配的记录,Hive就会立即停止扫描
2. 无on条件的join是计算两个表的笛卡尔积,结果行数等于左表行数乘以右表行数,设置属性hive.mapred.mode值为strict,Hive会阻止用户执行耗时的笛卡尔积查询
3. map-side join:在大表join小表时,可以将小表完全放到内存中,Hive可以在大表的map操作中执行连接过程。Hive v0.7之前需要显式添加标记,之后的版本通过设置属性hive.auto.convert.join为true(默认为false),启动该优化,并可以通过属性hive.mapjoin.smalltable.filesize设置小表的大小(单位为字节)。当join操作的表都是按照on语句中的键进行分桶时,且一张表的分桶个数是另一张表的若干倍,Hive也可以在map阶段按照分桶数据进行连接,同样该功能需要设置参数hive.optimize.bucketmapjoin为true时才可以开启优化;特殊地,如果连接操作的两个表分桶数量相同,且按照分桶键值进行连接,此时Hive可以执行一个更快的分类合并连接,需要设置如下属性才能开启,set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat; set hive.optimize.bucketmapjoin=true; set hive.optimize.bucketmapjoin.sortmerge=true。