1、Hive 介绍本文是对前段时间的研究工作进行总结。目的是介绍 Hive 的功能,架构和如何应用到 Hypertable 上,来达到对 hypertable 查询的辅助和扩展。Hive 是什么?Hive 是建立在 Hadoop 上的数据仓库基础构架。它提供了一系列的工具,可以用来进行数据提取转化加载(ETL) ,这是一种可以 存储、查询和分析存储在 Hadoop 中的大规模数据的机制。Hive 定义了简单的类 SQL 查询语言,称为 QL,它允许熟悉 SQL 的用户查询数据。同时,这个语言也允许熟悉 MapReduce 开发者的开发自定义的 mapper 和 reducer 来处理内建的 map
2、per 和 reducer 无法完成的复杂的分析工作(就是支持自定义函数,可以用在计算引擎的实现中) 。简单的来说,Hive 是 Hadoop 生态系统中的一个重要的组件。最开始是由Facebook 提出并实现的。使用它的前提就是运行在 Hadoop 系统之上,现在成熟的 Hadoop 发行版都已集成了 Hive,例如 Mapr,CDH4 等。包括很多国际大公司都在实际项目中使用 Hive。那么 Hive 和 Hbase 或者 Hypertable 这种多维度映射的稀疏列数据还是有本质的不同的。我个人理解,最主要的不同还是专注解决的问题不同。HBase和 Hypertable 都是 googl
3、e 的 Big-table 的开源实现。当时 google 最先实现了分布式文件系统 GFS,和分布式计算框架 Map-reduce。GFS 本身适合存储一些很大的文件,也不提供随机查询的功能。因此,2006 年的时候一篇论文,Big-table 应运而生。HBase 也是在 HDFS 的基础上,解决这样的数据存储和查询问题。HBase 本身是一种 NoSql 数据库,Not only Sql 。 它专注于互联网的业务需求,基于一个假设,即每次读取数据时并不需要返回全部的列信息,而且每一行并不一定每一列都有数据。这种设计对于存储大量的稀疏数据很有效率。但另一方面,这种数据只能提供简单的操作,
4、(Create,Update,Read,Delete 和Scan) 。而 Hive 的提出,是希望提供一种工具,能够读取存储在 HDFS 上的文件数据,并提供类 SQL 的语句,来处理和操作这些文件数据,Hive 本身不是一种数据库的实现,它更像数据的展示工具。能够通过规定的分隔符,读取分布式文件系统上的任一文件。并能够对这些数据进行筛选,计算和并表查询等功能。可以看做是一个数据分析工具。同时,Hive 还开放了它读入数据的格式,即 MapReduce 的数据流,这样能够支持扩展读取其他外部系统的文件。随着Hypertable 的发展,官方也推出了 Hive-connector 组件,实现 H
5、ive 读取操作Hypertable 系统中表的数据。这也是目前我想到最有效的扩展 Hypertable 的立足点。如何使用 Hive?Hadoop 和其之上的开源软件现在发展的很好,很多使用起来都已经很方便。安装 Hive 的过程也十分简答。配置好 Hadoop 和 HBase 之后,下载解压Hive 包,简单配置即可使用。Hive 本身有三个程序访问入口:命令行( CLI) ,客户端, Web 界面。其中最常用的是 CLI,启动的时候,会同时启动一个 Hive 服务。Client 是 Hive 的客户端(其实同 Hypertable 所谓的客户端一样,就是一些库文件) ,用户连接至Hive
6、 Server。在启动 Client 模式的时候,需要指出 Hive Server 所在节点,并且在该节点启动 Hive Server。 WUI 是通过浏览器访问 Hive 的 Web 工具。上图是 Hypertable 官网的例子,介绍了如何用 Hive 操作 Hypertable 中的数据。大概的过程:在 Hypertable 中新建一个测试表,插入一些数据。启动 Hive,启动的时候指定 Hypertable-Hive-Connector 的 jar 包路径。在 Hive 中创建一个新的外部表,指明字段的结构和需要读取的 Hypertable的表名和命名空间,以及对应 Hypertabl
7、e 表中的哪几列。之后 Hive 会自动创建一张外部表,只保存表结构的元信息,不会保存表数据,因为数据事实上已经保存在 Hypertable 中。可以看到现在已经能够通过 Hive 对 Hypertable 表中的数据进行操作了。值得注意的是,在 Hive 中对这张表添加数据,会影响到 Hypertable,即数据最终被添加进 hypertable 中那张原始表中。Hive 的架构元数据存储 Hive 将元数据存储在数据库中,如 MySQL 或者 Derby 嵌入式数据库。若将元数据存储在 MySQL 中,在 TBLS 中可以看见你建立的所有表信息,Hive 中的元数据包括表的名字,表的列和分
8、区及其属性,表的属性(是否为外部表等),表的数据所在目录等。执行 解释器、编译器、优化器完成 HQL 查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在 HDFS 中,并在随后有MapReduce 调用执行。HDFS 存储 Hive 的数据存储在 HDFS 中,大部分的查询由 MapReduce 完成(包含 * 的查询,比如 select * from tbl 不会生成 MapRedcue 任务) 。附:Hive 内置查询语言(Hiveql)DDL CREATE DATABASE/SCHEMA, TABLE, VIEW, FUNCTION, INDEX DROP
9、DATABASE/SCHEMA, TABLE, VIEW, INDEX TRUNCATE TABLE ALTER DATABASE/SCHEMA, TABLE, VIEW MSCK REPAIR TABLE (or ALTER TABLE RECOVER PARTITIONS) SHOW DATABASES/SCHEMAS, TABLES, TBLPROPERTIES, PARTITIONS, FUNCTIONS, INDEXES, COLUMNS, CREATE TABLE DESCRIBE DATABASE, table_name, view_name原链接:https:/cwiki.ap
10、ache.org/confluence/display/Hive/LanguageManual+DDLLoad / Insert 原链接: https:/cwiki.apache.org/confluence/display/Hive/LanguageManual+DMLSelect SyntaxWITH CommonTableExpression (, CommonTableExpression)* (Note: Only available starting with Hive 0.13.0)SELECT ALL | DISTINCT select_expr, select_expr, .
11、FROM table_referenceWHERE where_conditionGROUP BY col_listCLUSTER BY col_list| DISTRIBUTE BY col_list SORT BY col_listLIMIT numberhttps:/cwiki.apache.org/confluence/display/Hive/LanguageManual+Select(分区索引)支持 JOINExample:Select count(*) cnt From store_sales ss join household_demographics hd on (ss.ss
12、_hdemo_sk = hd.hd_demo_sk) join time_dim t on (ss.ss_sold_time_sk = t.t_time_sk) join store s on (s.s_store_sk = ss.ss_store_sk) Where t.t_hour = 8 t.t_minute = 30 hd.hd_dep_count = 2 order by cnt;Hive 支持的运算符关系运算符常见的关系运算符等值比较: =不等值比较: =空值判断: IS NULL非空判断: IS NOT NULLLIKE 比较: LIKEJAVA 的 LIKE 操作: RLIKE
13、REGEXP 操作: REGEXP数学运算加法操作: +减法操作: -乘法操作: *除法操作: /取余操作: %位与操作: CREATE TEMPORARY FUNCTION testlength AS org.apache.hadoop.hive.ql.udf.UDFTestLength; SELECT testlength(src.value) FROM src; DROP TEMPORARY FUNCTION testlength; UDFTestLength.java 为: package org.apache.hadoop.hive.ql.udf; public class UDFT
14、estLength extends UDF public Integer evaluate(String s) if (s = null) return null; return s.length(); 自定义函数可以重载: add jar build/contrib/hive_contrib.jar; CREATE TEMPORARY FUNCTION example_add AS org.apache.hadoop.hive.contrib.udf.example.UDFExampleAdd; SELECT example_add(1, 2) FROM src; SELECT exampl
15、e_add(1.1, 2.2) FROM src; UDFExampleAdd.java: public class UDFExampleAdd extends UDF public Integer evaluate(Integer a, Integer b) if (a = null | b = null) return null; return a + b; public Double evaluate(Double a, Double b) if (a = null | b = null) return null; return a + b; % 在使用 UDF 的时候,会自动进行类型转
16、换,这个 java 或者 C 中的类型转换有些类似,比如: SELECT example_add(1, 2.1) FROM src; 的结果是 3.1,这是因为 UDF 将类型为 Int 的参数 “1 转换为 double。 类型的隐式转换是通过 UDFResolver 来进行控制的,并且可以根据不同的 UDF 进行不同的控制。 UDF 还可以支持变长的参数,例如 UDFExampleAdd.java: public class UDFExampleAdd extends UDF public Integer evaluate(Integer. a) int total = 0; for (i
17、nt i=0; ia.length; i+) if (ai != null) total += ai; return total; / the same for Double public Double evaluate(Double. a) 使用例子为: SELECT example_add(1, 2) FROM src; SELECT example_add(1, 2, 3) FROM src; SELECT example_add(1, 2, 3, 4.1) FROM src; 综上,UDF 具有以下特性: * 用 java 写 UDF 很容易。 * Hadoop 的 Writables/Text 具有较高性能。 * UDF 可以被重载。 * Hive 支持隐式类型转换。 * UDF 支持变长的参数。 * genericUDF 提供了较好的性能(避免了反射) 。