Hive 体系结构介绍
Posted shujuxiong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hive 体系结构介绍相关的知识,希望对你有一定的参考价值。
创建数据文件:test_inner_table.txt
加载数据:LOAD DATA LOCAL INPATH ‘filepath’ INTO TABLE test_inner_table
查看数据:select * from test_inner_table; select count(*) from test_inner_table
删除表:drop table test_inner_table
外部表简单示例:
创建数据文件:test_external_table.txt
创建表:create external table test_external_table (key string)
加载数据:LOAD DATA INPATH ‘filepath’ INTO TABLE test_inner_table
查看数据:select * from test_external_table; •select count(*) from test_external_table
删除表:drop table test_external_table
创建数据文件:test_partition_table.txt
创建表:create table test_partition_table (key string) partitioned by (dt string)
加载数据:LOAD DATA INPATH ‘filepath’ INTO TABLE test_partition_table partition (dt=‘2006’)
查看数据:select * from test_partition_table; select count(*) from test_partition_table
删除表:drop table test_partition_table
创建数据文件:test_bucket_table.txt
创建表:create table test_bucket_table (key string) clustered by (key) into 20 buckets
加载数据:LOAD DATA INPATH ‘filepath’ INTO TABLE test_bucket_table
查看数据:select * from test_bucket_table; set hive.enforce.bucketing = true;
示例:create view test_view as select * from test
(1)HQL中对查询语句的解释、优化、生成查询计划是由Hive完成的
(2)所有的数据都是存储在Hadoop中
(3)查询计划被转化为MapReduce任务,在Hadoop中执行(有些查询没有MR任务,如:select * from table)
(4)Hadoop和Hive都是用UTF-8编码的
protected List <Operator<? extends Serializable >> childOperators;
protected List <Operator<? extends Serializable >> parentOperators;
protected boolean done; // 初始化值为false
TableScanOperator:扫描hive表数据
ReduceSinkOperator:创建将发送到Reducer端的<Key,Value>对
JoinOperator:Join两份数据
SelectOperator:选择输出列
FileSinkOperator:建立结果数据,输出至文件
FilterOperator:过滤输入数据
GroupByOperator:GroupBy语句
MapJoinOperator:/*+mapjoin(t) */
LimitOperator:Limit语句
UnionOperator:Union语句
Hive通过ExecMapper和ExecReducer执行MapReduce任务。在执行MapReduce时有两种模式,即本地模式和分布式模式 。
由于Hive采用了SQL的查询语言HQL,因此很容易将Hive理解为数据库。其实从结构上来看,Hive和数据库除了拥有类似的查询语言,再无类似之 处。数据库可以用在Online的应用中,但是Hive是为数据仓库而设计的,清楚这一点,有助于从应用角度理解Hive的特性。
Hive
|
RDBMS
|
|
查询语言
|
HQL
|
SQL
|
数据存储
|
HDFS
|
Raw Device or Local FS
|
数据格式
|
用户定义
|
系统决定
|
数据更新
|
不支持
|
支持
|
索引
|
无
|
有
|
执行
|
MapReduce
|
Executor
|
执行延迟
|
高
|
低
|
处理数据规模
|
大
|
小
|
可扩展性
|
高
|
低
|
4、Hive元数据库
启动derby数据库:/home/admin/caona/hive/build/dist/,运行startNetworkServer -h 0.0.0.0。
- <P style="TEXT-ALIGN: left; PADDING-BOTTOM: 0px; WIDOWS: 2; TEXT-TRANSFORM: none; BACKGROUND-COLOR: rgb(255,255,255); TEXT-INDENT: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT: 14px/26px Arial; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: rgb(0,0,0); WORD-SPACING: 0px; PADDING-TOP: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"> </P>
输入:./ij Connect ‘jdbc:derby://hadoop1:1527/metastore_db;create=true‘;
表名 | 说明 | 关联键 |
TBLS | 所有hive表的基本信息 | TBL_ID,SD_ID |
TABLE_PARAM | 表级属性,如是否外部表,表注释等 | TBL_ID |
COLUMNS | Hive表字段信息(字段注释,字段名,字段类型,字段序号) | SD_ID |
SDS | 所有hive表、表分区所对应的hdfs数据目录和数据格式 | SD_ID,SERDE_ID |
SERDE_PARAM | 序列化反序列化信息,如行分隔符、列分隔符、NULL的表示字符等 | SERDE_ID |
PARTITIONS | Hive表分区信息 | PART_ID,SD_ID,TBL_ID |
PARTITION_KEYS | Hive分区表分区键 | TBL_ID |
PARTITION_KEY_VALS | Hive表分区名(键值) | PART_ID |
从上面表的内容来看,hive整个创建表的过程已经比较清楚了。
(1)解析用户提交hive语句,对其进行解析,分解为表、字段、分区等hive对象
(2)根据解析到的信息构建对应的表、字段、分区等对象,从 SEQUENCE_TABLE中获取构建对象的最新ID,与构建对象信息(名称,类型等)一同通过DAO方法写入到元数据表中去,成功后将SEQUENCE_TABLE中对应的最新ID+5。
实际上我们常见的RDBMS都是通过这种方法进行组织的,典型的如postgresql,其系统表中和hive元数据一样裸露了这些id信息
(oid,cid等),而Oracle等商业化的系统则隐藏了这些具体的ID。通过这些元数据我们可以很容易的读到数据诸如创建一个表的数据字典信息,比
如导出建表语名等。
(3)LIKE允许用户复制现有的表结构,但是不复制数据。
(4)用户在建表的时候可以自定义SerDe或者使用自带的 SerDe ( Serialize/Deserilize 的简称,目的是用于序列化和反序列化 )。如果没有指定 ROW FORMAT 或者 ROW FORMAT DELIMITED,将会使用自带的SerDe。在建表的时候,用户还需要为表指定列,用户在指定表的列的同时也会指定自定义的SerDe,Hive通过 SerDe确定表的具体的列的数据。
(5)如果文件数据是纯文本,可以使用STORED AS TEXTFILE。如果数据需要压缩,使用STORED AS SEQUENCE。
(6)有分区的表可以在创建的时候使用 PARTITIONED BY语句。一个表可以拥有一个或者多个分区,每一个分区单独存在一个目录下。而且,表和分区都可以对某个列进行CLUSTERED BY操作,将若干个列放入一个桶(bucket)中。也可以利用SORT BY对数据进行排序。这样可以为特定应用提高性能。
(7)表名和列名不区分大小写,SerDe和属性名区分大小写。表和列的注释是字符串。
SET mapred.reduce.tasks = 1 SELECT * FROM sales SORT BY amount DESC LIMIT 5
SELECT `(ds|hr)?+.+` FROM sales
SELECT语句:查询数据。
(1)字符集
Hadoop和Hive都是用UTF-8编码的,所以, 所有中文必须是UTF-8编码, 才能正常使用。
备注:中文数据load到表里面,,如果字符集不同,很有可能全是乱码需要做转码的,但是hive本身没有函数来做这个。
(2)压缩
hive.exec.compress.output 这个参数,默认是false,但是很多时候貌似要单独显式设置一遍,否则会对结果做压缩的,如果你的这个文件后面还要在hadoop下直接操作,那么就不能压缩了。
(3)count(distinct)
当前的Hive不支持在一条查询语句中有多Distinct。如果要在Hive查询语句中实现多Distinct,需要使用至少n+1条查询语句(n为 distinct的数目),前n条查询分别对n个列去重,最后一条查询语句对n个去重之后的列做Join操作,得到最终结果。
(4)JOIN
只支持等值连接
(5)DML操作
只支持INSERT/LOAD操作,无UPDATE和DELTE
(6)HAVING
不支持HAVING操作。如果需要这个功能要嵌套一个子查询用where限制
(7)子查询
Hive不支持where子句中的子查询
(8)Join中处理null值的语义区别
SQL标准中,任何对null的操作(数值比较,字符串操作等)结果都为null。Hive对null值处理的逻辑和标准基本一致,除了Join时的特殊 逻辑。这里的特殊逻辑指的是,Hive的Join中,作为Join key的字段比较,null=null是有意义的,且返回值为true。
select concat(cookie_id,concat(‘;‘,’zoo’)) from c02_clickstat_fatdt1 limit 2; FAILED: Parse Error: line 0:-1 cannot recognize input ‘<EOF>‘ in function specification
可以推断,Hive解析语句的时候,只要遇到分号就认为语句结束,而无论是否用引号包含起来。
解决的办法是,使用分号的八进制的ASCII码进行转义,那么上述语句应写成:select concat(cookie_id,concat(‘\\073‘,‘zoo‘)) from c02_clickstat_fatdt1 limit 2;
为什么是八进制ASCII码?我尝试用十六进制的ASCII码,但Hive会将其视为字符串处理并未转义,好像仅支持八进制,原因不详。这个规则也适用于 其他非SELECT语句,如CREATE TABLE中需要定义分隔符,那么对不可见字符做分隔符就需要用八进制的ASCII码来转义。
* 内存中的数据格式: Java Integer/String, Hadoop IntWritable/Text
* 用户提供的map/reduce脚本:不管什么语言,利用stdin/stdout传输数据
* 用户自定义函数:Substr, Trim, 1 – 1
* 用户自定义聚合函数:Sum, Average…… n – 1
TextFile | SequenceFIle | RCFFile | |
Data type | Text Only | Text/Binary | Text/Binary |
Internal Storage Order | Row-based | Row-based | Column-based |
Compression | File Based | Block Based | Block Based |
Splitable | YES | YES | YES |
Splitable After Compression | No | YES | YES |
CREATE TABLE mylog ( user_id BIGINT, page_url STRING, unix_time INT) STORED AS TEXTFILE;
CREATE TABLE base64_test(col1 STRING, col2 STRING) STORED AS INPUTFORMAT ‘org.apache.hadoop.hive.contrib. fileformat.base64.Base64TextInputFormat‘ OUTPUTFORMAT ‘org.apache.hadoop.hive.contrib. fileformat.base64.Base64TextOutputFormat‘;
SerDe是Serialize/Deserilize的简称,目的是用于序列化和反序列化。序列化的格式包括:分隔符(tab、逗号、CTRL-A)、Thrift 协议
反序列化(内存内):Java Integer/String/ArrayList/HashMap、Hadoop Writable类、用户自定义类
其中,LazyObject只有在访问到列的时候才进行反序列化。 BinarySortable保留了排序的二进制格式。
当存在以下情况时,可以考虑增加新的SerDe:
* 用户有更有效的序列化磁盘数据的方法。
CREATE TABLE apache_log( host STRING, identity STRING, user STRING, time STRING, request STRING, status STRING, size STRING, referer STRING, agent STRING) ROW FORMAT SERDE ‘org.apache.hadoop.hive.contrib.serde2.RegexSerDe‘ WITH SERDEPROPERTIES ( "input.regex" = "([^ ]*) ([^ ]*) ([^ ]*) (-|\\\\[[^\\\\]]*\\\\]) ([^ \\"]*|\\"[^\\"]*\\") (-|[0-9]*) (-|[0-9]*)(?: ([^ \\"]*|\\"[^\\"]*\\") ([^ \\"]*|\\"[^\\"]*\\"))?", "output.format.string" = "%1$s %2$s %3$s %4$s %5$s %6$s %7$s %8$s %9$s";) STORED AS TEXTFILE;
CREATE TABLE mythrift_table ROW FORMAT SERDE ‘org.apache.hadoop.hive.contrib.serde2.thrift.ThriftSerDe‘ WITH SERDEPROPERTIES ( "serialization.class" = "com.facebook.serde.tprofiles.full", "serialization.format" = "com.facebook.thrift.protocol.TBinaryProtocol";);
用户可以自定义Hive使用的Map/Reduce脚本,比如:
FROM ( SELECT TRANSFORM(user_id, page_url, unix_time) USING ‘page_url_to_id.py‘ AS (user_id, page_id, unix_time) FROM mylog DISTRIBUTE BY user_id SORT BY user_id, unix_time) mylog2 SELECT TRANSFORM(user_id, page_id, unix_time) USING ‘my_python_session_cutter.py‘ AS (user_id, session_info);
Map/Reduce脚本通过stdin/stdout进行数据的读写,调试信息输出到stderr。
用户可以自定义函数对数据进行处理,例如:
<P>[sql]</P> <P>add jar build/ql/test/test-udfs.jar; CREATE TEMPORARY FUNCTION testlength AS ‘org.apache.hadoop.hive.ql.udf.UDFTestLength‘; SELECT testlength(src.value) FROM src; DROP TEMPORARY FUNCTION testlength;</P>
package org.apache.hadoop.hive.ql.udf; public class UDFTestLength extends UDF { public Integer evaluate(String s) { if (s == null) { return null; } return s.length(); } }
* Hadoop的Writables/Text 具有较高性能。
* UDF可以被重载。
* Hive支持隐式类型转换。
* UDF支持变长的参数。
* genericUDF 提供了较好的性能(避免了反射)。
例子:
<P>[sql]</P> <P>SELECT page_url, count(1), count(DISTINCT user_id) FROM mylog;</P>
1 public class UDAFCount extends UDAF { 2 public static class Evaluator implements UDAFEvaluator { 3 private int mCount; 4 5 public void init() { 6 mcount = 0; 7 } 8 9 public boolean iterate(Object o) { 10 if (o!=null) 11 mCount++; 12 13 return true; 14 } 15 16 public Integer terminatePartial() { 17 return mCount; 18 } 19 20 public boolean merge(Integer o) { 21 mCount += o; 22 return true; 23 } 24 25 public Integer terminate() { 26 return mCount; 27 } 28 }
以上是关于Hive 体系结构介绍的主要内容,如果未能解决你的问题,请参考以下文章
1.27.Flink实时性容错机制窗口等介绍内幕作业调度JobManager数据结构1.29.Flink和Hive整合支持的Hive版本使用 Flink 提供的 Hive jar