Hive核心概念剖析及示例
来源:互联网 发布:北京中云数据有限公司 编辑:程序博客网 时间:2024/06/07 15:10
一、Hive文件存储格式和记录格式
Hive中的文件格式和记录格式
Hive存储数据时底层一般使用的都是Hadoop的HDFS文件系统,Hive数据存在的形式为HDFS文件。
我们可以使用Hive load
命令和insert ··· directory···select···from
SQL实现:
- 把文件中的数据导入到Hive数据表;
- 把Hive表中感兴趣的字段数据转储到指定的数据文件;
那么在这些过程中hive是怎么操作的呢?
补充:
1、load伪命令:load data local inpath ‘/yourDir’ overwrite into table ‘yourTable’ partion(column=’value’);2、insert 伪SQL:insert overwrite local directory ‘/yourDir’ select * from yourTable where yourCondition;
首先,在Hive看来,Hive不会强制要求将数据转换成特定的文件格式
后才能使用:
(1)Hive利用Hadoop的inputStream api从不同的数据源中读取数据,例如:文本格式文件、sequence格式文件,甚至用户自定义格式文件;
(2)同样的,Hive利用Hadoop的outputFormat api也可以将数据保存为不同的格式文件。
其次,在Hive看来,对于文件格式,只需要关注两个方面:
(1)文件是怎么分割成行(记录)
Hive默认使用文件文件保存数据,文本文件使用\n作为默认的行分隔符。
当用户没有使用默认的文本文件格式时,用户需要告诉Hive使用的InputFormat和OutputFormat是什么。事实上,用户需要指定对于输入和输出格式实现的Java类的名称。InputFormat中定义了如何读取划分,以及如何将划分分割为记录;而OutputFormat中定义了将这些划分写回到文件或控制台输出中。
实际上,InputFormat和OutputFormat就是Hadoop io中用于读写文件的inputstream和outputstream。
(2)行(记录)是怎么分割成字段(列)
Hive使用^A作为文本文件中默认的字段分隔符。
Hive使用SerDe(序列化/反序列化的缩写)作为对输入记录(反序列化)进行分割以及写记录(序列化)的模板。
一个SerDe包含了将一条记录的非结构化字节转化成Hive可以使用的一条记录的过程。
在Hive内部,Hive引擎使用定义的InputFormat来读取一行数据记录,这行记录之后被传递给SerDe.deserialize()方法进行处理。有些SerDe需要指定特定的属性才能完整的实例化某个对象。
所有这些信息用户在创建表的时候都可以在表定义语句中进行制定。创建完成后,用户可以向平时一样查询表,而无需关心底层格式。
示例1
这里使用一个自定义的SerDe、输入格式和输出格式的完整例子做个示例:
CREATE TABLE yourTablePARTITIONED BY(ds string)ROW FORMAT SERDE 'com.linkedin.haivvreo.AvroSerDe'WITH SERDEPROPERTIES('schema.url' = ‘http://schema_provider/kst.avsc’)STORED AS INPUTFORMAT 'com.linkedin.haivvreo.AvroInputFormat'OUTPUTFORMAT 'com.linkedin.haivvreo.AvroOutputFormat'
ROW FORMAT SERDE指定了使用的SerDe,Hive提供了WITH SERDEPROPERTIES功能,允许用户传递配置信息给SerDe,Hive本身并不知晓这些属性的含义,需要SerDe去决定这些属性所代表的含义。
STORED AS INPUTFORMAT······ OUTPUTFORMAT······子句分别指定了用于输入格式和输出格式的Java类。
需要注意的是,用户必须同时对输入格式和输出格式都进行指定。
示例2
在Hive中,某些语法是其它语法的快捷语法,例如:
CREATE TABLE yourtableSTORED AS TEXTFILE;
语法STORED AS的替代方式同时指定INPUTFORMAT和OUTPUTFORMAT:
- 指定INPUTFORMAT为’org.apache.hadoop.mapred.TextInputFormat’;
- 指定OUTPUTFORMAT为’org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat’;
示例3
创建表时指定记录格式,用户可以指定列分隔符及集合元素间的分隔符:
CREATE TABLE yourtable(······)ROW FORMAT DELIMITEDFIELDS TERMINATED BY '\001'COLLECTION ITEMS TERMINATED BY '\002'MAP KEYS TERMINATED BY '\002'LINES TERMINATED BY '\n'STORED AS TEXTFILE;
定义完这些分隔符后,用户就可以读取保存特定记录格式的文本文件。
这种强大的可定制功能使得可以很容易的使用Hive来处理那些由其它工具和程序产生的文件。
二、Hive与MapRedece
Apache HCatalog项目:以Hadoop MapReduce的方式操作Hive中海量数据
HCatalog官方文档
HCatalog提供了一个HCatInputFormat类来共MapReduce用户从Hive的数据仓库中读取数据。其允许用户只读取需要的表分区和字段,同时以一种方便的列表格式(HCatRecord)来使用记录,这样就不需要用户来进行划分了。
HCatalog提供了一个HCatOutputFormat类来写数据到文件。当HCatOutputFormat写数据时,输出的键不重要,而值得类型必须是HCatRecord。
在执行MapReduce任务时,Hive本身是不会生成Java MapReduce算法程序的。相反,Hive通过一个表示“job执行计划”的XML文件驱动执行内置的,原生的mapper和reducer模块。换句话说,这些通用的模块函数类似于微型的语言翻译程序,而这个驱动计算的“语言”是以XML形式编码的。
Hive通过和JobTracker通信来初始化MapReduce任务,而不必部署在JobTracker所在的管理节点上执行。
这里是一个官网使用HCatalog进行读写的示例:
public class GroupByAge extends Configured implements Tool { public static class Map extends Mapper<WritableComparable, HCatRecord, IntWritable, IntWritable> { int age; @Override protected void map( WritableComparable key, HCatRecord value, org.apache.hadoop.mapreduce.Mapper<WritableComparable, HCatRecord, IntWritable, IntWritable>.Context context) throws IOException, InterruptedException { age = (Integer) value.get(1); context.write(new IntWritable(age), new IntWritable(1)); } } public static class Reduce extends Reducer<IntWritable, IntWritable, WritableComparable, HCatRecord> { @Override protected void reduce( IntWritable key, java.lang.Iterable<IntWritable> values, org.apache.hadoop.mapreduce.Reducer<IntWritable, IntWritable, WritableComparable, HCatRecord>.Context context) throws IOException, InterruptedException { int sum = 0; Iterator<IntWritable> iter = values.iterator(); while (iter.hasNext()) { sum++; iter.next(); } HCatRecord record = new DefaultHCatRecord(2); record.set(0, key.get()); record.set(1, sum); context.write(null, record); } } public int run(String[] args) throws Exception { Configuration conf = getConf(); args = new GenericOptionsParser(conf, args).getRemainingArgs(); String inputTableName = args[0]; String outputTableName = args[1]; String dbName = null; Job job = new Job(conf, "GroupByAge"); HCatInputFormat.setInput(job, InputJobInfo.create(dbName, inputTableName, null)); // initialize HCatOutputFormat job.setInputFormatClass(HCatInputFormat.class); job.setJarByClass(GroupByAge.class); job.setMapperClass(Map.class); job.setReducerClass(Reduce.class); job.setMapOutputKeyClass(IntWritable.class); job.setMapOutputValueClass(IntWritable.class); job.setOutputKeyClass(WritableComparable.class); job.setOutputValueClass(DefaultHCatRecord.class); HCatOutputFormat.setOutput(job, OutputJobInfo.create(dbName, outputTableName, null)); HCatSchema s = HCatOutputFormat.getTableSchema(job); System.err.println("INFO: output schema explicitly set for writing:" + s); HCatOutputFormat.setSchema(job, s); job.setOutputFormatClass(HCatOutputFormat.class); return (job.waitForCompletion(true) ? 0 : 1); } public static void main(String[] args) throws Exception { int exitCode = ToolRunner.run(new GroupByAge(), args); System.exit(exitCode); }}
HCatInputFormat通过和Hive的元数据存储进行通信来 获取要读取的表和分区的信息。这包括获取表的模式,也包括获取每个分区的模式。对于每个分区,还要确定对应的用于读取该分区数据的实际的InputFormat和SerDe。这些会被收集在一起,然后和所有的分区的数据划分一起,返回一个InputSplits对象列表。
同样,对于每个底层的InputFormat都会有对应的RecordReader用于对划分进行解码。然后HCatRecordReader会通过和分区对应的SerDe将来自底层的RecordReader的值转化成HCatRecord。这个过程中包含有为每个分区补充对应缺少的列,或者过滤掉不需要的列。
HCatOutputFormat也会和Hive元数据存储进行通信,以确定写入的文件格式和模式。
三、Hive与NoSQL
把其它NoSQL类型的数据当作标准的Hive数据表处理
HiveStorageHandler是Hive用于连接如HBase、Cassandra等类似NoSQL存储的主要接口,检查下接口可以发现需要定义一个定制的InputFormat、一个OutputFormat以及SerDe。存储处理程序负责从底层存储子系统中读取或写入数据。这就转变成通过写select查询读取数据系统中的数据,以及通过如reports这样的操作将数据写入到数据系统。
Hive中的抽象如表、类型、行格式以及其他元数据都用于Hive理解源数据。一旦Hive了解了源数据的描述信息,那么查询引擎就可以使用熟悉的HiveSQL操作符来处理数据。
在一个系统整体架构中将NoSQL数据库和Hadoop结合使用的一个通用技术就是使用NoSQL数据库集群来进行实时处理,而利用Hadoop集群进行非实时面向批处理的工作。如果NoSQL系统是主要数据存储,而其数据又需要通过Hadoop的批处理job进行查询的话,批量导出是一个将NoSQL数据导入到HDFS文件中的高效的方式。一旦HDFS中的文件通过导出生成后,就可以以最大效率执行批处理Hadoop job。
四、Hive的Thrift服务
以JDBC/ODBC编程方式访问Hive表中的数据和管理Hive的元数据
五、HiveSQL
- Hive不支持行级别的增删改;
- 和标准SQL一样,HiveSQL也可以分为三个部分:DDL、DML、DCL。
其中,DCL又和Hive安全紧密相关(用户、组和角色;Grant 和 Revoke权限).
在使用HiveSQL时,经常会使用到分区,其实一个分区就对应着一个包含多个文件的文件夹。
六、Hive自定义函数UDF
Hive UDF分为3类:UDF/UDAF/UDTF
UDF官方文档
UDF
官网UDF示例
User Defined Scalar Function,通常也称之为UDF。用户自定义标量值函数(User Defined Scalar Function)通常也称之为UDF。其输入与输出是一对一的关系,即读入一行数据,写出一条输出值。
UDAF
官网UDAF示例
UDAF(User Defined Aggregation Function),自定义聚合函数,其输入与输出是多对一的关系,即将多条输入记录聚合成一条输出值。可以与 SQL中的Group By语句联用。
UDTF
官方UDTF示例
UDTF(User Defined Table Valued Function),自定义表值函数,是用来解决一次函数调用输出多行数据场景的,也是唯一能返回多个字段的自定义函数。而UDF只能一次计算输出一条返回值。
参考文献
Hive编程指南
HCatalog官方文档
- Hive核心概念剖析及示例
- Storm核心概念剖析
- DAGScheduler原理剖析和一些核心概念
- 《JavaScript核心概念及实践》
- tomcat核心概念及应用
- Xinetd概念及示例配置
- Hive中的UDF及自定义函数示例
- 面向对象及相关概念剖析
- SOA核心概念及Tuscany安装配置
- Apriori算法(基础及核心概念)
- EM算法(基础及核心概念)
- LR算法(基础及核心概念)
- Storm 核心概念及工作原理
- 2.四个核心概念及使用
- Spring入门示例及相关概念介绍
- Spring入门示例及相关概念介绍
- Spring入门示例及相关概念介绍
- Spring入门示例及相关概念介绍
- iOS Safari把数字识别为电话
- HTML5 canvas 时钟
- 元数据
- 正则表达式的坑
- FIN7 APT组织攻击木马分析报告
- Hive核心概念剖析及示例
- git回退远程分支的版本
- Vim
- CTF比赛中SQL注入的一些经验总结
- hdu 3037 Saving Beans 隔板法+lucas
- Sitemesh 3 的使用及配置 1 . Sitemesh 3 简介 Sitemesh 是一个网页布局和修饰的框架,基于 Servlet 中的 Filter,类似于 ASP.NET 中的‘母版页’
- NYOJ:28-大数阶乘
- 在原型继承的时候为什么需要对constructor属性就行修正
- 我必须得告诉大家的MySQL优化原理