首页 > 其他 > 详细

Hive

时间:2020-04-07 17:09:06      阅读:74      评论:0      收藏:0      [点我收藏+]

#Hive 原文地址:https://www.cnblogs.com/itboys/tag/HIVE/

Hive是基于Hadoop的数据仓库工具,可对存储在HDFS上的文件中的数据集进行数据整理、特殊查询和分析处理,提供了类似于SQL语言的查询语言——HiveQL,可通过HQL语句实现简单的MR统计,Hive将HQL语句转换成MR任务进行执行。

##概述 ###数据仓库概念 数据仓库(Data Warehouse)是一个面向主题的(Subject Oriented)、集成的(Integrated)、相对稳定的(Non-Volatile)、反应历史变化(Time Variant)的数据集合,用于支持管理决策。

数据仓库体系结构通常含四个层次:数据源、数据存储和管理、数据服务、数据应用。

  • 数据源:是数据仓库的数据来源,含外部数据、现有业务系统和文档资料等;
  • 数据集成:完成数据的抽取、清洗、转换和加载任务,数据源中的数据采用ETL(Extract-Transform-Load)工具以固定的周期加载到数据仓库中。
  • 数据存储和管理:此层次主要涉及对数据的存储和管理,含数据仓库、数据集市、数据仓库检测、运行与维护工具和元数据管理等。
  • 数据服务:为前端和应用提供数据服务,可直接从数据仓库中获取数据供前端应用使用,也可通过OLAP(OnLine Analytical Processing,联机分析处理)服务器为前端应用提供负责的数据服务。
  • 数据应用:此层次直接面向用户,含数据查询工具、自由报表工具、数据分析工具、数据挖掘工具和各类应用系统。

###传统数据仓库的问题

  • 无法满足快速增长的海量数据存储需求,传统数据仓库基于关系型数据库,横向扩展性较差,纵向扩展有限。 这个本来就不是RDBMS的优势,横向扩展的时候分库分表,纵向扩展(扩展内存,CPU等)。
  • 无法处理不同类型的数据,传统数据仓库只能存储结构化数据,企业业务发展,数据源的格式越来越丰富。
  • 传统数据仓库建立在关系型数据仓库之上,计算和处理能力不足,当数据量达到TB级后基本无法获得好的性能。

###Hive Hive是建立在Hadoop之上的数据仓库,由Facebook开发,在某种程度上可以看成是用户编程接口,本身并不存储和处理数据,依赖于HDFS存储数据,依赖MR处理数据。有类SQL语言HiveQL,不完全支持SQL标准,如,不支持更新操作、索引和事务,其子查询和连接操作也存在很多限制。

Hive把HQL语句转换成MR任务后,采用批处理的方式对海量数据进行处理。数据仓库存储的是静态数据,很适合采用MR进行批处理。Hive还提供了一系列对数据进行提取、转换、加载的工具,可以存储、查询和分析存储在HDFS上的数据。

###Hive与Hadoop生态系统中其他组件的关系

  • Hive依赖于HDFS存储数据,依赖MR处理数据;
  • Pig可作为Hive的替代工具,是一种数据流语言和运行环境,适合用于在Hadoop平台上查询半结构化数据集,用于与ETL过程的一部分,即将外部数据装载到Hadoop集群中,转换为用户需要的数据格式;
  • HBase是一个面向列的、分布式可伸缩的数据库,可提供数据的实时访问功能,而Hive只能处理静态数据,主要是BI报表数据,Hive的初衷是为减少复杂MR应用程序的编写工作,HBase则是为了实现对数据的实时访问。

技术分享图片

###Hive与传统数据库的对比 | | Hive | 传统数据库 | | ----- | ---- | --------- | | 数据插入 | 支持批量导入,不可单条导入 | 支持单条和批量导入 | | 数据更新 | 不支持 | 支持 | | 索引 | 有限索引功能,不像RDBMS有键的概念,
可在某些列上建索引,加速一些查询操作。
创建的索引数据,会被保存在另外的表中
| 支持 | | 分区 | 支持,Hive表示分区形式进行组织的,根据
“分区列”的值对表进行粗略划分,
加快数据的查询速度 | 支持,提供分区功能来改善大型表以及具有各
种访问模式的表的可伸缩性、可管理性,
以及提高数据库效率 | | 执行延迟 | 高,构建在HDFS和MR之上,比传统数据库
延迟要高 | 低,传统SQL语句的延迟一般少于1秒,而HQL
语句延迟可达分钟级。 | | 扩展性 | 好,基于Hadoop集群,有很好的横向扩展性 | 有限,RDBMS非分布式,横向扩展(分布式添
加节点)难实现,纵向扩展(扩展内存,CPU
等)也很有限 |

###Hive的部署和应用

当前企业中部署的大数据分析平台,除Hadoop的基本组件HDFS和MR外,还结合使用Hive、Pig、HBase、Mahout,从而满足不同业务场景需求。

技术分享图片

上图是企业中一种常见的大数据分析平台部署框架 ,在这种部署架构中:

  • Hive和Pig用于报表中心,Hive用于分析报表,Pig用于报表中数据的转换工作。
  • HBase用于在线业务,HDFS不支持随机读写操作,而HBase正是为此开发,可较好地支持实时访问数据。
  • Mahout提供一些可扩展的机器学习领域的经典算法实现,用于创建商务智能(BI)应用程序。

##Hive系统架构

技术分享图片

Hive主要由以下三个模块组成:

  • 用户接口模块,含CLI、HWI、JDBC、Thrift Server等,用来实现对Hive的访问。CLI是Hive自带的命令行界面;HWI是Hive的一个简单网页界面;JDBC、ODBC以及Thrift Server可向用户提供进行编程的接口,其中Thrift Server是基于Thrift软件框架开发的,提供Hive的RPC通信接口。
  • 驱动模块(Driver),含编译器、优化器、执行器等,负责把HiveQL语句转换成一系列MR作业,所有命令和查询都会进入驱动模块,通过该模块的解析变异,对计算过程进行优化,然后按照指定的步骤执行。
  • 元数据存储模块(Metastore),是一个独立的关系型数据库,通常与MySQL数据库连接后创建的一个MySQL实例,也可以是Hive自带的Derby数据库实例。此模块主要保存表模式和其他系统元数据,如表的名称、表的列及其属性、表的分区及其属性、表的属性、表中数据所在位置信息等。

喜欢图形界面的用户,可采用几种典型的外部访问工具:Karmasphere、Hue、Qubole等。

##Hive工作原理 ###SQL语句转换成MapReduce作业的基本原理 ####用MapReduce实现连接操作

假设连接(join)的两个表分别是用户表User(uid,name)和订单表Order(uid,orderid),具体的SQL命令:

SELECT name, orderid FROM User u JOIN Order o ON u.uid=o.uid;

技术分享图片

上图描述了连接操作转换为MapReduce操作任务的具体执行过程:

  • 首先,在Map阶段,
    • User表以uid为key,以name和表的标记位(这里User的标记位记为1)为value,进行Map操作,把表中记录转换生成一系列KV对的形式。比如,User表中记录(1,Lily)转换为键值对(1,<1,Lily>),其中第一个“1”是uid的值,第二个“1”是表User的标记位,用来标示这个键值对来自User表;
    • 同样,Order表以uid为key,以orderid和表的标记位(这里表Order的标记位记为2)为值进行Map操作,把表中的记录转换生成一系列KV对的形式;
  • 接着,在Shuffle阶段,把User表和Order表生成的KV对按键值进行Hash,然后传送给对应的Reduce机器执行。比如KV对(1,<1,Lily>)、(1,<2,101>)、(1,<2,102>)传送到同一台Reduce机器上。当Reduce机器接收到这些KV对时,还需按表的标记位对这些键值对进行排序,以优化连接操作;
  • 最后,在Reduce阶段,对同一台Reduce机器上的键值对,根据“值”(value)中的表标记位,对来自表User和Order的数据进行笛卡尔积连接操作,以生成最终的结果。比如键值对(1,<1,Lily>)与键值对(1,<2,101>)、(1,<2,102>)的连接结果是(Lily,101)、(Lily,102)。

###用MapReduce实现分组操作

  • 首先,在Map阶段,对表Score进行Map操作,生成一系列KV对,其键为<rank, level>,值为“拥有该<rank, level>组合值的记录的条数”。比如,Score表的第一片段中有两条记录(A,1),所以进行Map操作后,转化为键值对(<A,1>,2);
  • 接着在Shuffle阶段,对Score表生成的键值对,按照“键”的值进行Hash,然后根据Hash结果传送给对应的Reduce机器去执行。比如,键值对(<A,1>,2)、(<A,1>,1)传送到同一台Reduce机器上,键值对(<B,2>,1)传送另一Reduce机器上。然后,Reduce机器对接收到的这些键值对,按“键”的值进行排序;
  • 在Reduce阶段,把具有相同键的所有键值对的“值”进行累加,生成分组的最终结果。比如,在同一台Reduce机器上的键值对(<A,1>,2)和(<A,1>,1)Reduce操作后的输出结果为(A,1,3)。

###Hive中SQL查询转换成MR作业的过程 当Hive接收到一条HQL语句后,需要与Hadoop交互工作来完成该操作。HQL首先进入驱动模块,由驱动模块中的编译器解析编译,并由优化器对该操作进行优化计算,然后交给执行器去执行。执行器通常启动一个或多个MR任务,有时也不启动(如SELECT * FROM tb1,全表扫描,不存在投影和选择操作)

技术分享图片

上图是Hive把HQL语句转化成MR任务进行执行的详细过程:

  • 由驱动模块中的编译器–Antlr语言识别工具,对用户输入的SQL语句进行词法和语法解析,将HQL语句转换成抽象语法树(AST Tree)的形式;
  • 遍历抽象语法树,转化成QueryBlock查询单元。因为AST结构复杂,不方便直接翻译成MR算法程序。其中QueryBlock是一条最基本的SQL语法组成单元,包括输入源、计算过程、和输入三个部分;
  • 遍历QueryBlock,生成OperatorTree(操作树),OperatorTree由很多逻辑操作符组成,如TableScanOperator、SelectOperator、FilterOperator、JoinOperator、GroupByOperator和ReduceSinkOperator等。这些逻辑操作符可在Map、Reduce阶段完成某一特定操作;
  • Hive驱动模块中的逻辑优化器对OperatorTree进行优化,变换OperatorTree的形式,合并多余的操作符,减少MR任务数、以及Shuffle阶段的数据量;
  • 遍历优化后的OperatorTree,根据OperatorTree中的逻辑操作符生成需要执行的MR任务;
  • 启动Hive驱动模块中的物理优化器,对生成的MR任务进行优化,生成最终的MR任务执行计划;
  • 最后,有Hive驱动模块中的执行器,对最终的MR任务执行输出。

Hive驱动模块中的执行器执行最终的MR任务时,Hive本身不会生成MR算法程序。它通过一个表示“Job执行计划”的XML文件,来驱动内置的、原生的Mapper和Reducer模块。Hive通过和ResourceManager通信来初始化MR任务,而不需直接部署在ResourceManager所在管理节点上执行。通常在大型集群中,会有专门的网关机来部署Hive工具,这些网关机的作用主要是远程操作和管理节点上的ResourceManager通信来执行任务。Hive要处理的数据文件常存储在HDFS上,HDFS由名称节点(NameNode)来管理。

##Hive HA基本原理 在实际应用中,Hive也暴露出不稳定的问题,在极少数情况下,会出现端口不响应或进程丢失问题。Hive HA(High Availablity)可以解决这类问题。

技术分享图片

在Hive HA中,在Hadoop集群上构建的数据仓库是由多个Hive实例进行管理的,这些Hive实例被纳入到一个资源池中,由HAProxy提供统一的对外接口。客户端的查询请求,首先访问HAProxy,由HAProxy对访问请求进行转发。HAProxy收到请求后,会轮询资源池中可用的Hive实例,执行逻辑可用性测试。

  • 如果某个Hive实例逻辑可用,就会把客户端的访问请求转发到Hive实例上;
  • 如果某个实例不可用,就把它放入黑名单,并继续从资源池中取出下一个Hive实例进行逻辑可用性测试。
  • 对于黑名单中的Hive,Hive HA会每隔一段时间进行统一处理,首先尝试重启该Hive实例,如果重启成功,就再次把它放入资源池中。

由于HAProxy提供统一的对外访问接口,因此,对于程序开发人员来说,可把它看成一台超强“Hive”。

#Hive metastore三种配置方式 Hive的meta数据支持以下三种存储方式,其中两种属于本地存储,一种为远端存储。远端存储比较适合生产环境。Hive官方wiki详细介绍了这三种方式,链接为:https://cwiki.apache.org/confluence/display/HADOOP2/Hive/AdminManual/MetastoreAdmin

##本地derby 这种方式是最简单的存储方式,只需要在hive-site.xml做如下配置便可

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
 
<configuration>
	<property>
	  <name>javax.jdo.option.ConnectionURL</name>
	  <value>jdbc:derby:;databaseName=metastore_db;create=true</value>
	</property>
	 
	<property>
	  <name>javax.jdo.option.ConnectionDriverName</name>
	  <value>org.apache.derby.jdbc.EmbeddedDriver</value>
	</property>
	 
	<property>
	  <name>hive.metastore.local</name>
	  <value>true</value>
	</property>
	 
	<property>
	  <name>hive.metastore.warehouse.dir</name>
	  <value>/user/hive/warehouse</value>
	</property>
</configuration>

注:使用derby存储方式时,运行hive会在当前目录生成一个derby文件和一个metastore_db目录。这种存储方式的弊端是在同一个目录下同时只能有一个hive客户端能使用数据库,否则会提示如下错误

hive> show tables;
FAILED: Error in metadata: javax.jdo.JDOFatalDataStoreException: Failed to start database ‘metastore_db‘, see the next exception for details.
NestedThrowables:
java.sql.SQLException: Failed to start database ‘metastore_db‘, see the next exception for details.
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask

##本地mysql 这种存储方式需要在本地运行一个mysql服务器,并作如下配置(下面两种使用mysql的方式,需要将mysql的jar包拷贝到$HIVE_HOME/lib目录下)。

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
 
<configuration>
	<property>
	  <name>hive.metastore.warehouse.dir</name>
	  <value>/user/hive_remote/warehouse</value>
	</property>
	 
	<property>
	  <name>hive.metastore.local</name>
	  <value>true</value>
	</property>
	 
	<property>
	  <name>javax.jdo.option.ConnectionURL</name>
	  <value>jdbc:mysql://localhost/hive_remote?createDatabaseIfNotExist=true</value>
	</property>
	 
	<property>
	  <name>javax.jdo.option.ConnectionDriverName</name>
	  <value>com.mysql.jdbc.Driver</value>
	</property>
	 
	<property>
	  <name>javax.jdo.option.ConnectionUserName</name>
	  <value>hive</value>
	</property>
	 
	<property>
	  <name>javax.jdo.option.ConnectionPassword</name>
	  <value>password</value>
	</property>
</configuration>

##远端mysql 这种存储方式需要在远端服务器运行一个mysql服务器,并且需要在Hive服务器启动meta服务。

这里用mysql的测试服务器,ip位192.168.1.214,新建hive_remote数据库,字符集位latine1

hive.metastore.warehouse.dir /user/hive/warehouse javax.jdo.option.ConnectionURL jdbc:mysql://192.168.1.214:3306/hive_remote?createDatabaseIfNotExist=true javax.jdo.option.ConnectionDriverName com.mysql.jdbc.Driver javax.jdo.option.ConnectionUserName hive javax.jdo.option.ConnectionPassword password hive.metastore.local false hive.metastore.uris thrift://192.168.1.188:9083

注:这里把hive的服务端和客户端都放在同一台服务器上了。服务端和客户端可以拆开,将hive-site.xml配置文件拆为如下两部分

服务端配置文件

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
 
<configuration>
	<property>
	  <name>hive.metastore.warehouse.dir</name>
	  <value>/user/hive/warehouse</value>
	</property>
	 
	<property>
	  <name>javax.jdo.option.ConnectionURL</name>
	  <value>jdbc:mysql://192.168.1.214:3306/hive_remote?createDatabaseIfNotExist=true</value>
	</property>
	 
	<property>
	  <name>javax.jdo.option.ConnectionDriverName</name>
	  <value>com.mysql.jdbc.Driver</value>
	</property>
	 
	<property>
	  <name>javax.jdo.option.ConnectionUserName</name>
	  <value>root</value>
	</property>
	 
	<property>
	  <name>javax.jdo.option.ConnectionPassword</name>
	  <value>test1234</value>
	</property>
</configuration>

客户端配置文件

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
 
<configuration>
 
	<property>
	  <name>hive.metastore.warehouse.dir</name>
	  <value>/user/hive/warehouse</value>
	</property>
	 
	<property>
	  <name>hive.metastore.local</name>
	  <value>false</value>
	</property>
	 
	<property>
	  <name>hive.metastore.uris</name>
	  <value>thrift://192.168.1.188:9083</value>
	</property>
 
</configuration>

启动hive服务端程序

$ hive --service metastore 

客户端直接使用hive命令即可

root@my188:~$ hive 
Hive history file=/tmp/root/hive_job_log_root_201301301416_955801255.txt
hive> show tables;
OK
test_hive
Time taken: 0.736 seconds
hive>

#Hive中MetaServer与HiveServer2的应用 在hive中有metaServer与hiveServer2两种服务,看了好多文章说这两个的区别,文章内容有对有错,不够全面,故在这里好好总结一下。

首先,下面这个hive构架图,我们一定不陌生,它反应出hive有哪些组件结构

技术分享图片

当然下面的图是hadoop1的部分,现在JobTracker是Yarn了 上面的部分是访问Hive的三个入口,

  • 1: 直接Cli
  • 2: 通过JDBC
  • 3: webUI

当我们要连接Hive进行操作时,首先必须是安装了,安装hive很简单,直接在conf/hive-site配置存放Hive元数据的连接信息,通常是用mysql,如下:

<property>
      <name>javax.jdo.option.ConnectionURL</name>
      <value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true</value>
</property>
<property>
      <name>javax.jdo.option.ConnectionDriverName</name>
      <value>com.mysql.jdbc.Driver</value>
</property>
<property>
      <name>javax.jdo.option.ConnectionUserName</name>
      <value>root</value>
</property>
<property>
      <name>javax.jdo.option.ConnectionPassword</name>
      <value>root</value>
</property>

这样配置好后,在hive的lib里加入Mysql JDBC 驱动后,我们就可以通过 bin/hive的方式连接hive客户端,请求数据。如下图:

技术分享图片

这样在大多数公司,特别是小公司小集群里基本是这样操作的,当然我们公司也是这样的,这样本身没有错误. 但我们看一下上面的配置,这样是不是把连接数据库的信息全泄露了,你可能会说,大家都是同公司的大数据部分,还有各种权限,泄露也无所谓,但我们想一下,在一个大的公司里,大数据平台是几个部门共用的,这样会有多台hive cli连接mysql,这样泄露mysql的信息的风险还是挺大的. 另一方面,比如我们元数据Mysql库无法启动,我们要替换从库时,或者我们要移植元数据到另一台机器上时,那么我们这么多的hive cli是不是全要修改一遍....

那么这时我们Hive的另一个组件出场了,它就是MetaStoreServer

启动:nohup $HIVE_HOME/bin/hive –metastore &

技术分享图片

如图,我们在Hive cli与mysql中间是不是启动一个MetaStoreServer, 这样我们的Hive cli就不需要连接Mysql,直接连接这个MetaStoreServer不就行了吗, 在hive-site.xml只要简单的配置一下:

<property>
    <name>hive.metastore.uris</name>
    <value>thrift://xxxxxx:9083</value>
</property>

这样我就通过metaserver取得了元数据的信息对吧 当然上面的图只是一个MetaStoreServer,存在单点问题,但我们完全可以配置两个或者多个MetaStoreServer,就实现了负载均衡与容错的功能了,如下面的配置

<property>
	<name>hive.metastore.uris</name>
	<value>thrift://dw1:9083,thrift://dw2:9083</value>
</property>

Hive

原文:https://www.cnblogs.com/qg000/p/12653659.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!