一:计划
目录
3. Hive Client、Beeline Client 19
3.3. 第二代客户端Hive Beeline Client 24
二:数据仓库
1、数据仓库的基本概念
数据仓库,英文名称Data Warehouse,可简写为DW或DWH。数据仓库的目的是构建面向分析的集成化数据环境,为企业提供决策支持(Decision Support)。它出于分析性报告和决策支持目的而创建。
数据仓库本身并不"生产"任何数据,同时自身也不需要"消费"任何的数据,数据来源于外部,并且开放给外部应用,这也是为什么叫"仓库",而不叫"工厂"的原因。
数据仓库由何而来:
2、数据仓库的主要特征
数据仓库是面向主题的(Subject-Oriented)、集成的(Integrated)、非易失的(Non-Volatile)和时变的(Time-Variant)数据集合,用以支持管理决策。
2.1 面向主题
传统数据库中,最大的特点是面向应用进行数据的组织,各个业务系统可能是相互分离的。而数据仓库则是面向主题的。主题是一个抽象的概念,是较高层次上企业信息系统中的数据综合、归类并进行分析利用的抽象。在逻辑意义上,它是对应企业中某一宏观分析领域所涉及的分析对象。
操作型处理(传统数据)对数据的划分并不适用与决策分析。而基于主题组织的数据则不同,它们被划分为各自独立的领域,每个领域有各自的逻辑内涵但互不交叉,在抽象层次上对数据进行完整、一致和准确的描述。一些主题相关的数据通常分布在多个操作型系统中。
2.2 集成性
通过对分散、独立、异构的数据库数据进行抽取、清理、转换和汇总便得到了数据仓库的数据,这样保证了数据仓库内的数据关于整个企业的一致性。
数仓中综合数据不能从原有的数据库系统直接得到。因此在数据进入数仓之前,必然要经过统一与综合,这一步是数仓建设中最关键、最复杂的一步,所要完成的工作有:
(1)要统一源数据中所有矛盾之处,如字段的同名异义、一名同义、单位不统一、字长不一致,等等。
(2)进行数据综合和计算。数仓中的数据综合工作可以在从原有数据库抽取数据时生成,但许多是在数仓内部生成的,即进入数仓以后进行综合生成的。下图说明一个保险公司综合数据的简单处理过程,其中数仓中与"保险"主题有关的数据来自于多个不同的操作型系统。这些系统内部数据的命名可能不同,数据格式也可能不同。把不同来源的数据存储到数仓之前,需要去除这些不一致。
![]()
数据仓库的数据集成 2.3 非易失性(不可更新性)
操作型数据库主要服务于日常的业务操作,使得数据库需要不断地对数据实时更新,,以便迅速获得当前最新数据,不至于影响正常的业务运作。在数仓中只要保存过去的业务数据,不需要每一笔业务都实时更新数仓,而是根据商业需要每隔一段时间把一批较新的数据导入数仓。
数仓的数据反映的是一段相当长的时间内历史数据的内容,是不同时点的数据库快照的集合,以及基于这些快照进行统计、综合和重组的导出数据。数据非易失性主要是针对应用而言。数仓的用户对数据的操作大多是数据查询或比较复杂的挖掘,一旦数据进入数仓以后,一般情况下被较长时间保留。数仓中一般有大量的查询操作,但修改和删除操作很少。因此,数据经加工和集成进入数仓后是极少更新的,通常只需定期的加载和更新。
2.4 时变性
数仓包含各种粒度的历史数据。数仓中的数据可能与某个特定日期、星期、月份、季度或者年份有关。数仓的目的是通过分析企业过去一段时间业务的经营状况,挖掘其中隐藏的模式。虽然数仓的用户不能修改数据,但是并不是说数仓的数据是永远不变的。分析的结果只能反映过去的情况,当业务变化后,挖掘出的模式会失去时效性。因此数仓的数据需要更新,以适应决策的需要。从这个角度讲,数仓建设是一个项目,更是一个过程。数仓的数据随时间的变化表现在以下几个方面。
(1)数仓的数据时限一般要远远长于操作型数据的数据时限
(2)操作型系统存储的是当前数据,而数据仓库中的数据是历史数据
(3)数仓中的数据是按照时间顺序追加的,他们都带有时间属性
3、数仓与数据库的区别
数据库与数仓的区别实际讲的是OLTP和OLAP的区别。
操作型处理,叫联机事务处理OLTP(On-Line Transaction Processing),也称为面向交易的处理系统,它是针对具体业务在数据库联机的日常操作,通常对少数记录进行查询、修改。用户较为关心操作的响应时间、数据的安全性、完整性和并发支持的用户数等问题。传统的数据库系统作为数据管理的主要手段,主要用于操作型处理。
分析型处理,叫联机分析处理OLAP(On-Line Analytical Processing)一般针对某些主题的历史数据进行分析,支持管理决策。
首先要明白,数仓的出现,并不是要取代数据库
- 数据库是面向事务的设计,数仓是面向主题设计的
- 数据库一般存储业务数据,数仓存储的一般是历史数据
- 数据库设计是尽量避免冗余,一般针对某一业务应用进行设计,比如一张简单的user表,记录用户名、密码等简单数据即可,符合业务应用,但是不符合分析。数仓在设计是有意引入冗余,依照分析需求,分析维度、分析指标进行设计。
- 数据库是为捕获数据而设计,数仓是为分析数据而设计。
以银行业务为例。数据库是事务系统的数据平台,客户在银行做的每笔交易都会写入数据库,被记录下来,这里,可以简单的理解为用数据库记账。数仓是分析系统的数据平台,它从事务系统获取数据,并做汇总、加工,为决策者提供决策的依据。比如,某银行某分行一个月发生多少交易,该分行当前存款余额是多少。如果存款又多,消费交易又多,那么该地区就有必要设立ATM了。
显然,银行的交易量是巨大的,通常以百万甚至千万次来计算。事务系统是实时的,这就要求时效性,客户存一笔钱需要几十秒是无法忍受,这就要求数据库只能存储很短一段时间的数据。而分析系统时事后的,它要提供关注时间段内所有的有效数据。这些数据是海量的,汇总计算起来也要慢一些,但是,只要能提供有效的分析数据就达到目的了。
数仓,是在数据库已经大量存在的情况下,为了进一步挖掘数据资源、为了决策需要而产生的,它决不是所谓的"大型数据库"。
4、数仓分层架构
按照数据流入流出的过程,数仓架构可分为三层--源数据、数仓、数据应用
数仓的数据来源于不同的源数据,并提供多样的数据应用,数据自下而上流入数仓后向上层开放应用,而数仓只是中间集成化数据管理的一个平台。
- 源数据层(ODS):此层数据无任何更改,直接沿用外围系统数据结构和数据,不对外开放;为临时存储层,是接口数据的临时存储区域,为后一步的数据处理做准备。
- 数据仓库层(DW):也称为细节层,DW层的数据应该是一致的、准确的、干净的数据,即对源系统数据进行清洗(去除杂质)后的数据
- 数据应用层(DA或APP):前端应用直接读取的数据源;根据报表、专题分析需求而计算生成的数据。
数仓从各数据源获取数据及在数仓内的数据转换和流动都可以认为是ETL(抽取Extra,转化Transfer,装载Load)的过程,ETL是数仓的流水线,也可以认为是数仓的血液,它维系着数仓中数据的新陈代谢,而数仓日常的管理和维护工作的大部分精力就是保持ETL的正常和稳定。
为什么要对数仓分层?
用空间换时间,通过大量的预处理提升应用系统的用户体验(效率),因此数仓存在大量冗余的数据;不分层的话,如果源业务系统的业务规则发生变化将会影响整个数据清洗过程,工作量巨大。
通过数据分层管理可以简化数据清洗的过程,因为把原来一步的工作分到了多个步骤去完成,相当于把一个复杂的工作拆成了多个简单的工作,把一个大的黑盒变成了一个白盒,每一层的处理逻辑都相对简单和容易理解,这样我们比较容易保证每一步骤的正确性,当数据发生错误的时候,往往我们只需要局部调整某个步骤即可。
数仓分层架构:
5、数据仓库元数据管理
元数据(Meta Date),主要记录数仓中模型的定义、各层级间的映射关系、监控数仓的数据状态及ETL的任务运行状态。一般会通过元数据资料库(Metadata Repository)来统一地存储和管理元数据,其主要目的是使数仓的设计、部署、操作和管理能达成协同和一致。
元数据是数仓管理系统的重要组成部分,元数据管理是企业级数仓中的关键组件,贯穿数仓构建的这个过程,直接影响着数仓的构建、使用和维护。
- 构建数仓的主要步骤之一是ETL。这时元数据将发挥重要的作用,它定义了源数据系统到数仓的映射、数据转换的规则、数仓的逻辑结构、数据更新的规则、数据导入历史记录以及装载周期等相关内容。数据抽取和转换的专家以及数仓管理员正是通过元数据高效地构建数仓。
- 用户在使用数仓时,通过元数据访问数据,明确数据项的含义以及定制报表。
- 数仓的规模及其复杂性离不开正确的元数据管理,包括增加或移除外部数据源,改变数据清洗方法,控制出错的查询以及安排备份等
元数据可分为技术元数据和业务元数据。技术元数据为开发和管理数仓的IT人员使用,它描述了与数仓开发、管理和维护相关的数据,包括数据源信息、数据转换描述、数仓模型、数据清洗与更新规则、数据映射和访问权限等。而业务元数据为管理层和业务分析人员服务,从业务角度描述数据,包括商务术语、数仓中有什么数据、数据的位置和数据的可用性等,帮助业务人员更好的理解数仓中哪些数据是可用的以及如何使用。
由上可见,元数据不仅定义了数仓中数据的模式、来源、抽取和转换规则等,而且是整个数仓系统运行的基础,元数据把数仓系统中各个松散的组件联系起来,组成一个有机的整体。
三、Apache Hive
1、Hive简介
1.1 什么是Hive
hive是基于hadoop的一个数仓工具,可将结构化数据文件映射为一张数据库表,并提供类SQL查询功能
本质是将SQL转换为MapReduce程序。主要用途:用来做离线数据分析,比直接用MapReduce开发效率更高。
1.2 为什么使用Hive
直接使用Hadoop MapReduce处理数据所面临的问题:人员学习成本太高;MapReduce实现复杂查询逻辑开发难度太大。
使用Hive:操作接口采用类SQL语法,提供快速开发的能力;避免了去写MapReduce,减少开发人员的学习成本;功能扩展很方便
如何实现用户写sql 程序转换成mr执行处理数据(猜想hive的执行机制):
2、Hive架构
2.1 Hive架构图
2.2 Hive组件
用户接口:包括CLI、JDBC/ODBC、WebGUI。其中,CLI(command line interface)为shell命令行;JDBC/ODBC是Hive的JAVA实现,与传统数据库JDBC类似;WebGUI是通过浏览器访问hive
元数据存储:通常是存储在关系数据库日mysql/derby中。Hive将元数据存储在数据库中。Hive中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等。
解释器、编译器、优化器、执行器:完成HQL查询语句从词法分析、语法分析
编译、优化以及查询计划的生成。生成的查询计划存储在HDFS中,并在随后有MapReduce调用执行。
2.3 Hive与Hadoop的关系
Hive利用HDFS存储数据,利用MapReduce查询分析数据。
3、Hive与传统数据库对比
hive用于海量数据的离线数据分析
hive具有sql数据库的外表,但应用场景完全不同,hive是适合用来做批量数据统计分析 。
更直观的对比请看下面这幅图:
4、Hive数据模型
Hive中所有的数据都存储在HDFS中,没有专门的数据存储格式
在创建表时指定数据中的分隔符,Hive就可以映射成功,解析数据。
Hive中包含以下数据模型:
db:在HDFS中表现为hive.metastore.warehouse.dir目录下一个文件夹
table:在HDFS中表现所属db目录下一个文件夹
external table:数据存放位置可以在HDFS任意指定路径
partition:在hdfs中表现为table目录下的子目录
bucket:在hdfs中表现为同一个表目录下根据hash散列之后的多个文件
四:Hive安装部署
Hive安装前需要安装好JDK和Hadoop。配置好环境变量,如果需要使用mysql来存储元数据,则需要mysql也安装好。
1、metadata、metastore
Metadata即元数据。元数据包含用Hive创建的database、table、表的字段等元信息。元数据存储在关系型数据库中。如hive内置的Derby、第三方如MySQL等。
Metastor即元数据服务,作用是:客户端连接metastore服务,metastore再去连接MySQL数据库来存储元数据。有了metastore服务,就可以有多个客户端同时连接,而且这些客户端不需要知道MySQL数据库的用户名和密码,只需要连接metastore服务即可。
2、metastore三种配置方式
2.1 内嵌模式
内嵌模式使用的是内嵌的Derby数据库来存储元数据,也不需要额外起metastore服务。数据库和metastore服务都嵌入在主Hive Server进程中。这个是默认的,配置简单,但是一次只能一个客户端连接,适用于用来实验,不适用与生产环境。解压hive安装包bin/hive 启动即可使用。缺点:不同路径启动hive,每一个hive拥有一套自己的元数据,无法共享。
2.2 本地模式
本地模式采用外部数据库来存储元数据,目前支持的数据库有:MySQL、Postgres、Oracle、MS SQL Server。在这里我们使用MySQL。本地模式不需要单独起metastore服务,用的是跟hive在同一个进程里的metastore服务。也就是说当你启动一个hive服务,里面默认会帮我们启动一个metastore服务。hive根据hive.metastore.uris参数值来判断,如果为空,则为本地模式。缺点是:每启动一次hive服务,都内置启动了一个metastore。
本地模式下hive的配置主需要指定mysql的相关信息即可。
hive安装包conf/hive-site.xml文件中配置,如果没有自己创建该文件。
<configuration> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://node-1: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>hadoop</value> </property> </configuration>
2.3 远程模式
远程模式下,需要单独起metastore服务,然后每个客户端都在配置文件里配置连接到该metastore服务。远程模式的metastore服务和hive运行在不同的进程里。在生产环境中,建议用远程模式来配置Hive metastore。在这种情况下,其他依赖hive的软件都可以通过metastore访问hive。
远程模式下,需要配置hive.metastore.uris参数来指定metastore服务运行的机器ip和端口,并且需要单独手动启动metastore服务。
metastore metadata:
3、Hive Client、Beeline Client
课程中采用远程模式部署hive的metastore服务。使用hive自带的客户端进行连接访问。在node-1机器上,解压hive的安装包。
注意:以下两件事在启动hive之前必须确保正常完成。
1、选择某台机器提前安装mysql,确保具有远程访问的权限
2、启动hadoop集群确保集群正常健康
上传mysql jdbc的驱动包到hive的安装包lib目录下。修改hive的配置文件,具体如下:
tar zxvf hive-1.1.0-cdh5.14.0.tar.gz
mv hive-1.1.0-cdh5.14.0 hive
cd hive/conf/
mv hive-env.sh.template hive-env.sh
vim conf/hive-env.sh
export HADOOP_HOME=/export/servers/hadoop-2.6.0-cdh5.14.0
vim hive-site.xml,如下:<configuration> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://node-1: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>hadoop</value> </property> <property> <name>hive.server2.thrift.bind.host</name> <value>node-1</value> </property> <property> <name>hive.metastore.uris</name> <value>thrift://node-1:9083</value> </property> </configuration>
3.1 metastore的启动方式
前台启动:/export/servers/hive/bin/hive --service metastore
该启动方式下,进程会一直占用shell终端前台。如果ctrl+c结束进程,则hive metastore服务也会同时关闭。
后台启动:nohup /export/servers/hive/bin/hive --service metastore &
推荐使用后台启动的方式。
后台启动的情况下,如果想关闭metastore服务使用jps查看进程,kill -9进程号即可。
3.2 第一代客户端Hive Client
在hive安装包的bin目录下,有hive提供的第一代客户端bin/hive。使用该客户端可以访问hive的metastore服务。从而达到操作hive的目的。如果需要在其他机器上通过该客户端访问hivve metastore服务,只需要在该机器的hive-site.xml配置中添加metastore服务地址即可。上传hive安装包到另一个机器上,比如node-3:
tar zxvf hive-1.1.0-cdh5.14.0.tar.gz
mv hive-1.1.0-cdh5.14.0 hive
cd hive/conf/mv hive-env.sh.template hive-env.sh
vim conf/hive-env.sh
export HADOOP_HOME=/export/servers/hadoop-2.6.0-cdh5.14.0
vim hive-site.xml 如下:<configuration> <property> <name>hive.server2.thrift.bind.host</name> <value>node-1</value> </property> <property> <name>hive.metastore.uris</name> <value>thrift://node-1:9083</value> </property> </configuration>
使用下面的命令启动hive的客户端:
/export/servers/hive/bin/hive
可以发现官方提示:第一代客户端已经不推荐使用了。
3.3 第二代客户端Hive Beeline Client
hive经过发展,推出第二代客户端beeline,但是beeline客户端不是直接访问metastore服务的,而是需要单独启动hiveserver2服务。在hive运行的服务器上,首先启动metastore服务,然后启动hiveserver2服务。
nohup /export/servers/hive/bin/hive --service metastore &
nohup /export/servers/hive/bin/hive --service hiveserver2 &在node-3上使用beeline客户端进行连接访问。
/export/servers/hive/bin/beeline
Beeline version 1.1.0-cdh5.14.0 by Apache Hive
beeline> ! connect jdbc:hive2://node-1:10000
Enter username for jdbc:hive2://node-1:10000: root
Enter password for jdbc:hive2://node-1:10000: *******
hive的两代客户端:
五:Hive基本操作
1、DDL操作
1.1 创建表
建表语法:
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name [(col_name data_type [COMMENT col_comment], ...)] [COMMENT table_comment] [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)] [CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS] [ROW FORMAT row_format] [STORED AS file_format] [LOCATION hdfs_path]
说明:
- create table:创建一个指定名字的表。如同相同名字的表已经存在,则抛出异常;用户可以用IF NOT EXISTS选项来忽略这个异常。
- external:关键字可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径(LOCATION)。Hive创建内部表时,会将数据移动到数仓指向的路径;若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变。在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据
- like:允许用户复制现有的表结构,但是不复制数据。CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name LIKE existing_table;
- row format delimited:
[FIELDS TERMINATED BY char] [COLLECTION ITEMS TERMINATED BY char] [MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char] | SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value, property_name=property_value,...)]
hive建表的时候默认的分隔符是'\001',若在建表的时候没有指明分隔符,load文件的时候文件的分隔符需要是'\001';若文件分隔符不是'\001',程序不会报错,单表查询结果会全部为’null‘;用vi编辑器Ctrl+v然后Ctrl+a即可输入'\001'-> ^A。SerDe是Serialize/Deserilize的简称,目的是用于序列化和反序列化。Hive读取文件机制;首先调用InputFormat(默认TextInputFormat),返回一条一条记录(默认是一行对应一条记录)。然后调用SerDe(默认LazySimpleSerDe)的Deserializer,将一条记录切分为各个字段(默认'\001')。Hive写文件机制:将Row写入文件时,主要调用OutputFormat、SerDe的Seriliazer,顺序与读取相反。可通过desc formatted表名;进行相关信息查看。当我们的数据格式化比较特殊的时候,可以自定义SerDe。
- partitioned by:在hive select查询中一般会扫描整个表内容,会消耗很多时间做没必要的工作。有时候只需要扫描表中关心的一部分数据,因此建表时引入partition分区概念。分区表指的是在创建表时指定的partition的分区空间。一个表可以拥有一个或多个分区,每个分区以文件夹的形式单独存在表文件夹的目录下。表和列明不区分大小写。分区是以字段的形式在表结构中存在,通过describe table命令可以查看到字段存在,但是该字段不存放实际的数据内容,仅仅是分区的表示。
- stored as sequencefile|textfile|rcfile:如果文件数据是纯文本,可以使用stored as textfile。如果数据需要压缩,使用stored as sequencefile|。textfile是默认的文件格式,使用delimited子句来读取分隔的文件。
- clustered by into num_buckets buckets:对于每一个表(table)或者分,Hive可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分。Hive也是针对某一列进行桶的组织。Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条件记录存放在哪个桶当中。把表(或者分区)组织成桶(Bucket)有两个理由:
(1)获取更高的查询处理效率。桶为表加上额外的结构,Hive在处理有些查询时能利用这个结构。具体而言,连续两个在(包含连接列的)相同列上划分了桶的表,可以使用map端连接(Map-side join)高效实现。比如join操作,对于join操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保持相同列值的桶进行join操作就可以,可大大减少join的数据量。
(2)使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。
分桶表的好处:
1.2 修改表
增加分区:
alter table table_name ADD PARTITION (dt='20170101') location
'/user/hadoop/warehouse/table_name/dt=20170101'; //一次添加一个分区alter table table_name ADD PARTITION (dt='2008-08-08', country='us') location
'/path/to/us/part080808' PARTITION (dt='2008-08-09', country='us') location
'/path/to/us/part080809'; //一次添加多个分区删除分区
alter table table_name DROP IF EXISTS PARTITION (dt='2008-08-08');
alter table table_name DROP IF EXISTS PARTITION (dt='2008-08-08', country='us');
修改分区
alter table table_name PARTITION (dt='2008-08-08') RENAME TO PARTITION (dt='20080808');添加列
alter table table_name ADD|REPLACE COLUMNS (col_name STRING);
注:ADD是代表新增一个字段,新增字段位置在所有列后面(partition列前)
REPLACE则是表示替换表中所有字段。修改列
test_change (a int, b int, c int);alter table test_change CHANGE a a1 INT; //修改a字段名
// will change column a's name to a1, a's data type to string, and put it after column b. The new table's structure is: b int, a1 string, c int
alter table test_change CHANGE a a1 STRING AFTER b;// will change column b's name to b1, and put it as the first column. The new table's structure is: b1 int, a ints, c int
alter table test_change CHANGE b b1 INT FIRST;表重命名
alter table table_name RENAME TO new_table_name
1.3 显示命令
show tables;
显示当前数据库所有表
show databases |schemas;
显示所有数据库
show partitions table_name;
显示表分区信息,不是分区表执行报错
show functions;
显示当前版本hive支持的所有方法
desc extended table_name;
查看表信息
desc formatted table_name;
查看表信息(格式化美观)
describe database database_name;
查看数据库相关信息