• 大数据开发实战:离线大数据处理的主要技术--Hive,概念,SQL,Hive数据库


      1、Hive出现背景

          Hive是Facebook开发并贡献给Hadoop开源社区的。它是建立在Hadoop体系架构上的一层SQL抽象,使得数据相关人员使用他们最为熟悉的SQL语言就可以进行海量数据的处理、分析和统计工作,

        而不是必须掌握Java等编程语言和具备开发MapReduce程序的能力。Hive SQL实际上先被SQL解析器进行解析然后被Hive框架解析成一个MapReduce可执行计划,并按照该计划生成MapReduce任务后交给Hadoop集群处理。

          由于Hive SQL是翻译为MapReduce任务后在Hadoop集群执行的,而Hadoop是一个批处理系统,所以Hive SQL是高延迟的,不但翻译成的MapReduce任务执行延迟高,任务提交和处理过程也会消耗时间,因此即使Hive处理

        的数据集非常小(比如即MB,几十MB),在执行时也会出现延迟现象。这样Hive的性能就不能很好地和传统的Oracle数据库、MySQL数据库进行比较。Hive不能提供数据排序和查询缓存功能,也不提供在线事务处理、更不提供

        实时的查询和记录级的更新,但它能很好的处理不变的大规模数据集,当然这是 和其根植于Hadoop近似线性的可扩展性分不开的。

      2、Hive基本架构

          作为基于Hadoop的主要数据仓库解决方案,Hive SQL是主要的交互接口,实际的数据保存在HDFS文件中,真正的计算和执行则由MapReduce完成。而它们之间的桥梁是Hive引擎。下面是架构图:

        

        Hive组件包括UI组件、Driver组件(Complier,Optimizer和Executor)、Metastore组件、CLI(Command Line Interface, 命令行接口)、JDBC/ODBC、Thrift Server和Hive Web Interface(HWI)等。

        Driver组件:核心组件,整个Hive的核心,该组件包括Complier(编译)、Optimizer(优化器)和Executor(执行器),它们的作用是对Hive SQL语句进行解析、编译优化,生成执行计划,然后调用底层的MapReduce计算框架。

        Metastore组件:元数据服务组件,这个组件存储Hive的元数据。Hive的元数据存储在关系数据库里,Hive支持的关系数据库有Derby和MySQL。默认情况下,Hive元数据保存在内嵌的Derby数据库中,只能允许一个会话链接,

                只适合简单的测试。实际生产中不适用,为了支持多用户会话,需要一个独立的元数据库(如MySQL),Hive内部对MySQL提供了很好的支持。

        CLI:命令行接口。

        Thrift Server:提供JDBC和ODBC接入的能力,用来进行可扩展且跨语言 的服务开发。Hive集成了该服务,能让不同的编程 语言调用Hive的接口。

        Hive Web  Interface(HWI):Hive客户端提供了一个通过网页方式访问Hive所提供的服务,这个接口对应Hive的HWI组件。

        Hive通过CLI、JDBC/ODBC,或者HWI接收相关的Hive SQL查询,并通过Driver组件进行编译、分析优化,最后变成可执行的MapReduce。Hive主要组件执行过程如下图:

        

      3、Hive SQL

          Hive SQL是Hive用户使用Hive的主要工具。Hive SQL是类似于ANSI SQL标准的SQL语言,但两者又不完全相同。Hive SQL和MySQL的SQL方言最为接近,但两者之前也存在显著差异,比如Hive不支持行级数据插入、

        更新和删除,也不支持事务等。

       3.1、Hive关键概念

        3.1.1、Hive数据库

          Hive中的数据库从本质上来说仅仅是一个目录或命名空间,但是对于具有很多用户和组的集群来说,这个概念非常有用。首先,这样可以避免表命名冲突;其次,它等同于数据型数据库在的数据库概念呢,是一组表或表

        的逻辑组,非常容易理解。

        3.1.2、Hive表

          Hive中的表(Table)和关系数据库中的table在概念上是类似的,每个table在Hive在都有一个对应的目录存储数据,如果么有指定表的数据库,那么HIve会通过{HIVE_HOME}/conf/hive-site.xml配置文件中的hive.metastore.

        warehouse.dir属性来使用默认值(一般是 /user/hive/warehouse, 也可以根据实际的情况来修改这个配置),所有的table数据(不包括外部表)都保存在这个目录。

          Hive分为两类,即内部表和外部表。所谓内部表(managed table)即Hive管理的表,Hive内部表的管理既包含逻辑以及语法上的,也包含实际物理意义上的,即创建Hive内部表时,数据将真实存在于表所在的目录内,删除

        内部表时,物理数据和文件也一并删除。外部表(external table )则不然,其管理仅仅是在逻辑和语法意义上的,即新建表仅仅是指向一个外部目录而已。同样,删除时也不物理删除外部目录,而仅仅是将引用和定义删除。

          考虑下面的语句:

          CREATE TABLE my_managed_table(col1 STRING);

          LOAD DATA INPATH '/user/root/data.txt'  INTO table  my_managed_table

          上述语句会将hdfs:// user/root/data.txt 移动到Hive的对应目录hdfs://user/hive/warehouse/my_managed_table,但是载入数据的速度非常快,因为Hive只是把数据移动到对应的目录,不会对数据是否符合定义的Schema做校验,

        这个工作通常在读取时候进行(即为Schema On Read)。

          同时,my_managed_table使用DROP语句删除后,其数据和表的元数据被删除,不再存在,这就是 Hive managed的意思:

          DROP TABLE my_managed_table;

          外部表则不一样,数据的创建和删除完全由自己控制,Hive不管理这些数据,数据的位置在创建时指定:

          CREATE EXTERNAL TABLE external_table(dummy STRING)

            LOCATION  '/user/root/external_table';

          LOAD DATA INPATH '/user/root/data.txt' INTO TABLE exteranl_table;

          指定EXTERNAL关键字后,Hive不会把数据移动warehouse目录中。事实上,Hive甚至不会校验外部表的目录是否存在。这使得我们可以在创建表之后再创建数据,当删除外部表时,Hive只删除元数据,而不会删除外部实际

        物理文件。

          选择内部表还是外部表?在大多数情况下,这两者的区别不是很明显。如果数据的所有处理都在Hive中进行,那么更倾向于选择内部表。但是如果Hive和其它工具针对相同的数据集做处理,那么外部表更合适。一种常见的模式

        是使用外部表访问存储的HDFS(通常由其它工具创建)中 的初始数据,然后使用Hive转换数据并将其结果放在内部表中,相反,外部表也可以用于将Hive的处理结果导出供其它应用使用。使用外部表另一种场景是针对一个数据集,

        关联多个Schema。

        3.1.3、分区和桶

          Hive 将表划分为分区(partition),partition根据分区字段进行。分区可以让数据的部分查询变得更快。表或者分区可以进一步被划分为桶(bucket)。桶通常在原始数据中加入一些额外的结构,这些结构可以用于高效查询。

        例如,基于用户ID的分桶可以使用基于用户的查询非常快。

        分区:

          假设日志数据中,每条记录都带有时间戳。如果根据时间来分区,那么同一天的数据将被划分到同一个分区中。针对某一天或某几天数据的查询将会变得很高效,因为只需要扫描对应分区的文件。分区并不会导致跨度的的查询

        变得低效。

          分区可以通过多个维度来进行。例如,通过日期划分后,还可以根据国家进一步划分。

          分区在创建表的时候使用PARTITIONED BY从句定义,该从句接收一个字段列表:

          CREATE TABLE logs (ts BIGINT, line STRING) PARTITIONED BY (dt STRING, country STRING); 

          当导入数据到分区表时,分区的值被显式指定:

          LOAD DATA INPATH '/user/root/path'

          INTO TABLE logs 

          PATITION(dt='2001-01-01', country='GB');

          文件系统上,分区作为表目录的下一级目录存在,如下图:

          

          在实际的SQL中,灵活指定分区将大大提高其效率,如下代码将仅会扫描2001-01-01目录下的GB目录:

          select ts, dt, line from logs where dt = '2001-01-01'  and country='GB'

        分桶:

          在表或者分区中使用桶通常由两个原因:

          一个是为了高效查询。桶在表中加了特殊的结构,Hive在查询的时候可以利用这些结构提高效率。例如,如果两个表根据相同的字段进行分桶,则在对这两个表进行关联的时候,可以

        使用map-side关联高效实现,前提是关联的字段在分桶中出现。

          二是可以高效地进行抽样。在分析大数据集时,经常需要对部分抽样数据进行观察和分析,分桶有利于高效实现抽象。

          为了让Hive对表进行分桶,通过CLUSTERED BY 从句在创建表的时候指定:

          CREATE TABLE bucketed_users(id INT, name STRING)

          CLUSTERED BY (id) INTO 4 BUCKETS;

          指定表根据id字段进行分桶,并且分为4个桶。分桶时,Hive根据字段哈希后取余数来决定数据应该放哪个桶,因此每个桶都是整体数据的随机抽样。

          在map-side的关联中,两个表根据相同的字段进行分桶,因此处理左边表的bucket时,可以直接从外表对应的bucket中提取数据进行关联操作。map-side关联的两个表不一定需要完全相同bucket数量,只要成倍数即可。

          需要注意的是,Hive并不会对数据是否满足表定义中的分桶进行校验,只有在查询时出现异常才会报错。因此,一种更好的方式是将分桶的工作交给Hive来完成(设置hive.enforce.bucketing属性为true即可)。

       3.2、Hive数据库

           创建数据库

            创建数据库的完整语法如下:

            CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name

               [COMMENT database_name]

               [LOCATION hdfs_path]

               [WITH DBPROPERTIES(property_name=property_value,...)];

            例如:

            hive> create database my_hive_test if not exists

              commit 'this is my first hive database'

              with dbproperties(‘creator’ ='mike', 'date' = '2018-08-10');

          切换数据库

            hive> use my_hive_test;

          查看数据库

            hive> describe database my_hive_test;

          删除数据库

            hive> drop database my_hive_test;

               默认情况下,Hive不允许用户删除一个包含表的数据库。用户要么先删除数据库中的表,再删除数据库;要么在删除命令的最后加上关键字CASCADE,这样Hive会先删除数据库中的表,再删除数据库,

            命令如下(务必谨慎使用此命令):

            hive>drop database my_hive_test CASCADE;

          查看所有数据库

            hive>show databases;

       4、Hive函数列表

          

          参考资料:《离线和实时大数据开发实战》

        

  • 相关阅读:
    win7每天出现taskeng.exe进程的解决方案
    hibernate插入中文字段时,无法插入数据库
    本页面用来演示如何通过JS SDK,创建完整的QQ登录流程,并调用openapi接口
    不同项目之间的通信
    404错误、405错误、500错误出错原因
    linux 下启动tomcat 时没有执行权限
    webservice文件上传下载(byte[] 实现方式)
    文件路径获取
    单个文件复制
    myeclipse svn重新定位 本地文件 svn 重新定位
  • 原文地址:https://www.cnblogs.com/shaosks/p/9454628.html
Copyright © 2020-2023  润新知