Hive学习笔记2

概述

为什么使用hive

使用Hadoop MapReduce直接处理数据

人员学习成本太高 需要掌握java语言

mapReduce实现复杂查询逻辑开发难度太大

使用hive的好处

操作接口采用类sql语法,提供快速开发能力

避免直接写mapReduce,减少开发人员的学习成本

支持自定义函数,功能扩展方便

背靠hadoop,擅长存储分析海量数据

hive录用mapReduce查询分析数据,用hdfs存储数据

组件

用户接口

包括CLI,JDBC,WebGUIU,Hive中的Thrift服务器允许外部客户端通过网络与Hive进行交换,类似于JDBC或ODBC协议.WebGui是通过浏览器访问Hive

元数据存储

通常是存储在关系型数据库mysql/derby中.hive中的元数据包括的表的名字,表的列和分区及其属性,表的属性(是否为外部表),表的数据所在目录等

Driver驱动程序

包括语法解析器,编译器,优化器,执行器

完成HQL查询语句从词法分析,语法分析,编译,优化以及查询计划的生成.生成的查询计划存储在HDFS中,并在随后又执行引擎调用执行

执行引擎

hive本身并不直接处理数据文件.而是通过执行引擎进行处理.当下hive支持mapReduce,TEZ,spark3种执行引擎

数据模型

数据模型:原来描述数据,组织数据对数据进行操作,是对现实世界数据特征的描述

hive的数据模型类似于RDBMS库表结构,此外还有自己特有的模型

hive中的数据在粒度级别上分为三类

  • Table表
  • partition 分区
  • bucket 分桶

数据库

  • hive作为一个数据库,在结构上积极向传统数据库看齐,也分数据库(Schema)每个数据库下面有各自的表组成.默认数据库default
  • hive的数据都是存储在hdfs上的,默认有一个根目录,再hive-site.xml中,由参数hive.metastore.warehouse.dir指定.默认值为/user/hive/warehouse
  • 因此hive中的数据库在hdfs上的存储路径为${hive.metastore.warehouse.dir}databasename.db

tables表

hive表语关系型数据库中的表相同.hive中的表对应的数据通常是存储在hdfs中,而表相关的元数据是存储在RDBMS中

hive中的表的数据在HDFS上的存储路径为

${hive.matastore.warehouse.dir}/database.db/tablename

partitions分区

partition分区是hive的一种优化查询手段.分区指根据分区列(如日期)的值将表划分为不同的分区.这样可以更快地对制定分区的数据进行查询

分区在存储上面的表现是table表目录下子文件夹的形式存在

一个文件夹表示一个分区.子文件命名标准:分区列=分区值

hive还支持分区下继续创建分区,所谓多重分区

分桶

bucket分桶表是hive的一种优化手段.分桶是根据表中字段(比如id)的值,经过hash计算规则将数据文件划分成指定的若干个小文件

分桶规则:hashfunc(字段)%桶个数,余数系统的分到同一个文件

分桶的好处是可以优化join查询方便抽样查询

buket分桶在hdfs中表现为同一个目录下数据根据hash三列之后变成多个文件

元数据

元数据matadata,又称中介数据,为描述数据的数据(data about data)主要是描述数据属性的信息,用来支持指示存储位置,历史数据,资源查找,文件记录等功能

hive matadata即hive的元数据

包含用hive创建的database,table表的位置类型属性,字段顺序类型等元信息

元数据存储在关系型数据库中.如hive内置的derby,或者第三方如mysql中

hive matastore

即元数据服务,hive matastore服务的作用是管理matadata元数据,对外暴露地址,让各种客户端通过连接matastore服务,由matastore再去连接mysql数据库来存储元数据

有了matastore服务,就可以有多个客户端同时连接,而且这些客户端不需要知道mysql的用户名密码,只需要连接metastore服务即可.某种长度上也保证了hive元数据的安全

matastore服务由三种配置方式

内嵌模式,本地模式,远程模式

内嵌模式本地模式远程模式
metastore单独配置,启动
metadata存储介质derbymysqlmysql

内嵌模式

内嵌模式是matastore默认的部署模式

此种模式下,元数据存储在内置的derby数据库,并且derby数据库和matastore服务都嵌入在主HiveServer进程中,当启动HiveServer进程时,Derby和matastore都会启动.不需要额外另起matastore服务

但是一次只能支持一个活动用户,适用于测试体验,不适用生产环境

本地模式

本地模式下,metastore服务于主hiveserver进程在同一进程中运行,但是存储元数据的数据库在单独的进程中运行,但是存储元数据的数据库在单独的进程中运行,并且可以在单独的主机上,matastore服务将通过JDBC于matastore数据库进行通信

本地模式采用外部数据库来存储元数据,推荐使用mysql

hive根据hive.metastore.uris参数值来判断,如果为空,则为本地模式

缺点是没启动一次hive服务都配置了一个metastore

远程模式

远程模式(Remote matastore)下,matastore在其单独的jvm上运行,而不再hiveserver的jvm中运行.如果其他进程希望与matastore服务器通信,则可以使用Thrift network api进行通信

远程模式下,需配置hive.metastore.uris参数来制定metastore服务运行的机器ip和端口,并且需要单独手动启动metastore服务.元数据采用外部数据库存储,推荐mysql

生产环境中建议用远程模式hive metastore.再这种情况下,其他依赖hive的软件都可以通过metastore访问hive.由于还可以屏蔽掉数据库层,因此带来了更好的客观理性,安全性

关系

hiveserver2通过matastore服务读写元数据,所以在远程模式下,启动hiveServer2之前必须先启动matastore服务

远程模式下,beeline客户端只能通过hiveserver2服务访问hive.而bin/hive是通过metastore服务访问的

所以要先启动matastore再启动HiveServer2

使用体验

使用

再执行插入数据的时候,发现插入速度即慢,sql执行时间很长,插入一条数据30s之后才显示插入成功

  • hive底层是通过mapreduce执行数据插入动作的,所以速度慢
  • 如果数据量大这么一条条插入是不现实的
  • hive具有自己特有的数据插入方式

如何才能将结构化数据映射为表?

想要在hive中创建表结构化文件映射成功,需要注意一下几个问题:

创建表时字段顺序,字段类型要和文件中保持一致

如果类型不一致hive会尝试转换,不保证转换成功.不成功显示null

缺点

hive底层是通过mapreduce执行引擎来处理数据的

执行完一个mapreduce程序需要的时间不短

如果是小数据集,适用hive分析将得不偿失,延迟很高

适合大数据集的分析,底层mapreduce分布式计算

文件读写机制

SerDe是Serializer,Deserializer的简称,目的是用于序列化和反序列化

序列化是对象转换成字节码的过程;反序列化是字节码转对象的过程

hive使用serDe包括FileFormat读取和写入表行对象.需要注意的是,key部分在读取时会被忽略,而在写入时key始终是常数.基本上行对象存储在value中

读取机制

首先调用inputFormat返回一条条kv键值对记录.然后调用serde的deserializer将一套记录中的value根据分隔符切分成各个字段

写文件机制

将Row写入文件时,调用SerDe(默认LazySimpleSerDe)的Serializer将对象转换成字节序列,然后调用OutputFormat将数据写入HDFS中

存储

内部表与外部表

内部表

内部版intertnal table也成为被hive拥有和管理的托管表(managed table)

默认情况下创建的表就是内部表,hive拥有该表的结构和文件.换句话说,hive完全管理表(元数据和数据)的生命周期,类似于RDBMS中的表

当删除内部表会删除数据以及表的元数据

外部表

外部表(External table)中的数据不是hive拥有或管理的,只管理表元数据的生命周期

要创建一个外部表,需要使用external语法关键字

删除外部表只会删除元数据,而不会删除实际数据,再hive外仍然可以访问实际数据

实际场景中,外部表搭配,location语法制定数据的路径,可以让数据更安全

差异

无论是内部表还是外部表,hive都在hive metastore中管理表定义,字段类型等元数据信息

分区分桶

分区

hive表对应数据量大,文件个数多时,为了避免查询时扫描全表数据,hive支持指定根据指定的字段对表进行分区,分区的字段可以是日期,地域,种类等具有标识意义的字段

比如把一年整的数据划分为12个月,后续就可以查询指定月份的数据尽可能避免了全表扫描

分桶

分桶表也叫做桶表

分桶表对应的数据文件在底层会被分解成若干份,通俗来说就是拆分成若干份独立的小文件

分桶时,要制定根据哪个字段分桶

分桶规则:

编号相同的数据会被分到一个通中,具体取决于字段bucketing_column的类型

可以直接对int类型取模,或者对string的hashcode取模

查询指定分桶里面的数据,就可以查找出结果,此时是分桶扫描而不是全表扫描

事务表

hive设计之初是不支持事务的,因为hive的核心目标是将已经存在的结构化数据文件映射成为表,然后提供基于表sql分析处理,是一款面向分析的工具.并且映射的数据通常不存储在hdfs上,hdfs是不支持随机修改文件数据的

这个定位就意味着在早期的hive的sql语法中是没有update,delete操作的,也没所谓的支持事务了 ,因为都是select查询分析操作

从hive0.14版本开始具有acid语义的事务添加到hive中,以解决以下场景遇到的问题

流式传输数据

如使用apche Flume,kafka之类的根据将数据流式传输到hadoop集群中.虽然这些工具可以每秒百行或更多的行的速度写入数据,但是hive只能每隔15分钟添加一次分区.如果没分甚至每秒频繁添加分区很快会导致表中大量分区,并将许多小文件留在目录中,这将给NameNode带来压力

因此通常使用这些工具将数据流式传输到已有分区中,但这有可能会造成脏读,需要通过事务功能,允许用户获得一致性的视图避免过多小文件产生

尺寸变化缓慢

星型模式数据仓中,维度随着时间缓慢变化,例如零售商开设新商店,需要将其添加到商店表中,或者现有商店可能会更改其平方或某些其他跟踪的特征.这些更改导致都需要插入单个记录或更新单挑记录

数据重复

有时发现手机的数据不正确需要更正

局限性

虽然hive支持了acid语义的事务,但是使用起来并没有mysql中那样方便,有很多局限性.原因很简单,hive的设计目标不是为了支持事务操作,而是支持分析操作,并且最终基于hdfs的底层存储机制是的文件的增加删除操作需要懂一些小心思

  1. 上不支持begin ,commit和rollback 所有语言操作都是自动提交的
  2. 仅支持orc文件格式
  3. 默认情况下事务为关闭,需要配置参数开启使用
  4. 表必须是分桶表(Bucketed)才可以使用事务功能
  5. 表参数transactional必须为true
  6. 外部表不能成为acid表,不允许从非acid会话读取/写入acid表

物化视图

视图

hive中的视图是一种虚拟表,只保存定义不保存实际数据

通常从真实的物理表查询中创建生成视图,也可以从已存在的视图上创建新视图

创建视图时,将冻结视图的架构,如果删除或更改基础表,则视图将失败

视图是用来简化操作的,不缓冲记录,也没有提高查询性能

物化视图

物化视图是一个包括结果的数据库对象,可以用于预先计算保存表连接或聚集等耗时较多的操作结果,再执行查询时,就可以避免进行这些耗时操作,从而快速得到查询结构

物化视图的目的就是通过计算,提高查询性能,当然需要占用一定的存储空间

hive3.0开始引入物化视图

并提供对于物化视图的查询自动重写机制(通过apache calcite实现)

hive的物化视图还提供了物化视图存储选择机制,可以本地存储在hive,也可以通过用户自定义storage handlers存储在其他系统

hive引入物化视图就是为了优化数据查询访问效率,相当于从数据预处理的角度优化数据访问

hive从3.0丢弃了index无索引的语法支持,推荐使用物化视图和列式存储文件格式来加快查询速度

  1. 物化视图创建后,select查询执行数据自动落地,自动也即在query的执行期间,任何用户对该物化视图是不可见的,执行完毕后自动落地
  2. 默认情况下爱,创建好的物化视图可用于查询优化器optimizer查询重写,再物化视图创建期间可以通过bisable bewrite参数禁止使用
  3. 物化视图支持将数据存储在外部系统如druid
  4. 目前支持物化视图的drop和show操作,后续会增加其他操作
  5. 当数据变更(新数据inserted,数据修改,modified)物化视图也需要更新保证数据的一致性,目前需要用户主动触发rebuild重构

区别

视图是虚拟的逻辑存在的,只有定义存储数据

物化视图是真实的,物理存在的,里面存储着预计算的数据

物化视图能够缓存数据,再创建物化视图的时候就把数据缓存起来了,hive把物化视图当成一张表,将数据缓存,而视图只是一个虚表,只有表结构,没有数据,实际查询的时候再去写sql访问实际的数据表

视图的目的是简化降低查询的复杂度,而物化视图的目的是提高查询性能

materialized view物化视图

物化视图创建后即可用于相关查询的加速 ,即用户提交查询query,若该query经过重写后可以命中已经存在的物化视图,则直接通过物化视图查询数据返回结果

是否重写差U型你使用物化视图可以通过全局参数控制默认为true

用户可以选择性的控制指定的物化视图查询重写机制

Last modification:November 17, 2023
如果觉得我的文章对你有用,请随意赞赏