一、Hive概念
    (1)概念
    Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。 其优点是学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析。
    Hive是建立在 Hadoop 上的数据仓库基础构架。它提供了一系列的工具,可以用来进行数据提取转化加载(ETL),这是一种可以存储、查询和分析存储在 Hadoop 中的大规模数据的机制。Hive 定义了简单的类 SQL 查询语言,称为 HQL,它允许熟悉 SQL 的用户查询数据。同时,这个语言也允许熟悉 MapReduce 开发者的开发自定义的 mapper 和 reducer 来处理内建的 mapper 和 reducer 无法完成的复杂的分析工作。
    (2)自定义函数
    Hive设计的初衷是:对于大量的数据,使得数据汇总,查询和分析更加简单。它提供了SQL,允许用户更加简单地进行查询,汇总和数据分析。同时,Hive的SQL给予了用户多种方式来集成自己的功能,然后做定制化的查询,例如用户自定义函数(User Defined Functions,UDF、UDAF、UDTF).

    • UDF:操作单个数据行,产生单个数据行;
    • UDAF:操作多个数据行,产生一个数据行。
    • UDTF:操作一个数据行,产生多个数据行一个表作为输出。

    (3)适用场景
    Hive 构建在基于静态批处理的Hadoop 之上,Hadoop 通常都有较高的延迟并且在作业提交和调度的时候需要大量的开销。因此,Hive 并不能够在大规模数据集上实现低延迟快速的查询,例如,Hive 在几百MB 的数据集上执行查询一般有分钟级的时间延迟。
    因此,Hive 并不适合那些需要低延迟的应用,例如,联机事务处理(OLTP)。Hive 查询操作过程严格遵守Hadoop MapReduce 的作业执行模型,Hive 将用户的HiveQL 语句通过解释器转换为MapReduce 作业提交到Hadoop 集群上,Hadoop 监控作业执行过程,然后返回作业执行结果给用户。Hive 并非为联机事务处理而设计,Hive 并不提供实时的查询和基于行级的数据更新操作。Hive 的最佳使用场合是大数据集的批处理作业,例如,网络日志分析。
    (4)设计特征
    Hive 在加载数据过程中不会对数据进行任何的修改,只是将数据移动到HDFS 中Hive 设定的目录下,因此,Hive 不支持对数据的改写和添加,所有的数据都是在加载的时候确定的。Hive 的设计特点如下。

    • 支持创建索引,优化数据查询。
    • 不同的存储类型,例如,纯文本文件、HBase 中的文件。
    • 将元数据保存在关系数据库中,大大减少了在查询过程中执行语义检查的时间。
    • 可以直接使用存储在Hadoop 文件系统中的数据。
    • 内置大量用户函数UDF 来操作时间、字符串和其他的数据挖掘工具,支持用户扩展UDF 函数来完成内置函数无法实现的操作。
    • 类SQL 的查询方式,将SQL 查询转换为MapReduce 的job 在Hadoop集群上执行。

    二、Hive架构
    9.1 Hive - 图1
    该组件图包含不同的单元。下表详细的描述每个单元:

    单元名称 操作
    用户接口/界面 Hive是一个数据仓库基础工具软件,可以创建用户和HDFS之间互动。用户界面,Hive支持是Hive的Web UI,Hive命令行,HiveHD洞察(在Windows服务器)。
    元存储 Hive选择各自的数据库服务器,用以储存表,数据库,列模式或元数据表,它们的数据类型和HDFS映射。
    HiveQL处理引擎 HiveQL类似于SQL的查询上Metastore模式信息。这是传统的方式进行MapReduce程序的替代品之一。相反,使用Java编写的MapReduce程序,可以编写为MapReduce工作,并处理它的查询。
    执行引擎 HiveQL处理引擎和MapReduce的结合部分是由Hive执行引擎。执行引擎处理查询并产生结果和MapReduce的结果一样。它采用MapReduce方法。
    HDFS 或 HBASE Hadoop的分布式文件系统或者HBASE数据存储技术是用于将数据存储到文件系统。

    三、Hive工作原理
    下图描述了Hive 和Hadoop之间的工作流程。
    9.1 Hive - 图2
    下表定义Hive和Hadoop框架的交互方式:

    步骤 操作
    1 Hive接口,如命令行或Web UI发送查询驱动程序(任何数据库驱动程序,如JDBC,ODBC等)来执行。
    2 在驱动程序帮助下查询编译器,分析查询检查语法和查询计划或查询的要求。
    3 编译器发送元数据请求到Metastore(任何数据库)。
    4 Metastore发送元数据,以编译器的响应。
    5 编译器检查要求,并重新发送计划给驱动程序。到此为止,查询解析和编译完成。
    6 驱动程序发送的执行计划到执行引擎。
    7 在内部,执行作业的过程是一个MapReduce工作。执行引擎发送作业给JobTracker,在名称节点并把它分配作业到TaskTracker,这是在数据节点。在这里,查询执行MapReduce工作。
    7.1 与此同时,在执行时,执行引擎可以通过Metastore执行元数据操作。
    8 执行引擎接收来自数据节点的结果。
    9 执行引擎发送这些结果值给驱动程序。
    10 驱动程序将结果发送给Hive接口。

    四、Hive安装
    1、准备阶段
    hadoop、mysql、mysql驱动包(mysql-connector-java-5.1.27.jar),
    hive的安装包(apache-hive-2.3.5-bin.tar.gz):下载地址http://mirror.bit.edu.cn/apache/hive/
    9.1 Hive - 图3
    apache-hive-2.3.5-bin.tar.gz:安装包
    apache-hive-2.3.5-src.tar.gz:可视化web包
    2、创建目录并解压
    mkdir -p /usr/local/hive-2.3.5
    tar -zxvf apache-hive-2.3.5-bin.tar.gz -C /usr/local/hive-2.3.5
    ln -s /usr/local/hive-2.3.5 /usr/local/hive
    3、配置环境变量

    1. vim /etc/profile
    2. export HIVE_HOME=/usr/local/hive
    3. export PATH=$PATH:$HIVE_HOME/bin
    4. source /etc/profile #使环境变量生效

    4、设置配置文件
    cd /usr/local/hive/conf
    cp hive-default.xml.template hive-site.xml #原conf下是没有hive-site.xml文件
    vim hive-site.xml #主要是mysql的连接信息

    <configuration>
            <property>
                    <name>javax.jdo.option.ConnectionURL</name>
                    <value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true</value>(mysql地址localhost)
            </property>
            <property>
                    <name>javax.jdo.option.ConnectionDriverName</name>(mysql的驱动)
                    <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>123456</value>
            </property>
            <property>
                    <name>hive.metastore.schema.verification</name>
                    <value>false</value>
            </property>
    </configuration>
    

    5、将mysql驱动放在lib下
    cp mysql-connector-java-5.1.27.jar /usr/local/hive/lib
    6、初始化数据库
    schematool -dbType mysql -initSchema
    7、进入hive客户端
    hive #输出hive就可以直接进入hive客户端进行操作
    五、hive可视化图形页面(hwi)
    1、下载安装包http://mirror.bit.edu.cn/apache/hive/hive-2.3.5/
    apache-hive-2.3.5-src.tar.gz
    2、解压并打成war包
    tar -zxvf apache-hive-2.3.5-src.tar.gz -C /usr/local/hive
    cd /usr/local/hive/hwi #hwi文件中的web就是我们需要的文件
    jar cvfM0 hive-hwi-2.3.5.war -C web/ . #-C指定要打包的目录
    3、将包放在lib下:
    cp hive-hwi-2.3.5.war /usr/local/hive/lib
    cp tools.jar /usr/local/hive/lib #tools.jar为jdk的包,否则会出500错误
    4、修改配置文件hive-site.xml

    <property>  
        <name>hive.hwi.listen.host</name>  
        <value>0.0.0.0</value>  
    </property>  
    <property>  
        <name>hive.hwi.listen.port</name>  
        <value>9999</value>  
    </property>  
    
    <property>  
        <name>hive.hwi.war.file</name>  
        <value>/lib/hive-hwi-2.3.5.war</value>  
    </property>
    

    5、启动服务:
    hive —service hwi
    6、访问web ui:
    http://ip:9999/hwi/
    六、Hive基本操作
    1、Hive的数据类型

    基本数据类型
    类型 描述 示例
    TINYINT 1个字节(8位)有符号整数 1
    SMALLINT 2字节(16位)有符号整数 1
    INT 4字节(32位)有符号整数 1
    BIGINT 8字节(64位)有符号整数 1
    FLOAT 4字节(32位)单精度浮点数 1.0
    DOUBLE 8字节(64位)双精度浮点数 1.0
    BOOLEAN true/false true
    STRING 字符串 ‘xia’,”xia”
    复杂数据类型
    类型 描述 示例
    ARRAY 一组有序字段。字段的类型必须相同 Array(1,2)
    MAP 一组无序的键/值对。键的类型必须是原子的,值可以是任何类型,同一个映射的键的类型必须相同,值得类型也必须相同 Map(‘a’,1,’b’,2)
    STRUCT 一组命名的字段。字段类型可以不同 Struct(‘a’,1,1,0)

    2、内部表与外部表
    (1)创建外部表(关键字external):
    create external table exter_table(
    id int,
    name string,
    age int,
    tel string)
    location ‘/home/wyp/external’;
    这里需要指定外部表存放数据的路径(当然,你也可以不指定外部表的存放路径,这样Hive将在HDFS上的/user/hive/warehouse/文件夹下以外部表的表名创建一个文件夹,并将属于这个表的数据存放在这里)
    (2)Hive中内部表与外部表的区别:
    1、加载数据
    1)hive内部表,上传数据时:
    如果数据是hdfs的文件,那么会将hdfs的文件移动到hive所在的hdfs路径下
    如果数据是linux的文件,那么是拷贝到hive所在的hdfs路径下
    2) hive外部表,上传数据时:
    数据是hdfs的文件,那么仅仅是针对hdfs的文件创建一个快捷链接而已,
    如果数据是linux的文件,那么是拷贝到hive外表所在的hdfs路径下
    3)加载数据的时候,普通表不会检查数据的格式(如果格式不正确,就会存储为null),而外部表会检查源数据的格式(如果格式不正确,加载失败)。
    那么,应该如何选择使用哪种表呢?在大多数情况没有太多的区别,因此选择只是个人喜好的问题。但是作为一个经验,如果所有处理都需要由Hive完成,那么你应该创建内部表,否则使用外部表。原文链接:http://blog.csdn.net/sunlei1980/article/details/46572679
    2、在删除表的时候,Hive将会把属于内部表的元数据和数据全部删掉;而删除外部表的时候,Hive仅仅删除外部表的元数据,数据是不会删除的!
    3、排序order by 和 sort by
    1)order by为全局排序,只有一个reduce的输出
    select from baidu_click order by click desc;
    2)sort by局部排序,常和distribute by搭配使用:被distribute by设定的字段为KEY,数据会被HASH分发到不同的reducer机器上,然后sort by会对同一个reducer机器上的每组数据进行局部排序。
    select
    from baidu_click distribute by product_line sort by click desc;
    9.1 Hive - 图4
    3)文章地址:http://www.crazyant.net/1456.html
    4、hive计算的三种引擎(可以在客户端直接设置)
    —使用mapreduce计算
    set hive.execution.engine=mr;
    —使用spark计算
    set hive.execution.engine=spark;
    —使用tez计算引擎
    set hive.execution.engine=tez;
    (Tez+Hive)仍采用MapReduce计算框架,但对DAG(有向无环图)的作业依赖关系进行了裁剪,并将多个小作业合并成一个大作业,这样,不仅计算量减少,而且写HDFS次数也会大大减少。
    5、hive非交互式模式运行的命令参数:

    • hive -f test.sql # -f 可以运行脚本文件
    • hive -e “select * from testTable” # -e 运行简短的hql命令
    • hive -S -e “select * from testTable” # -S 强制不显示执行过程,只输出结果

    【注意】
    (1)、Hive的行级更新和删除
    Hive从0.14版本开始支持事务和行级更新,但缺省是不支持的,需要一些附加的配置。要想支持行级insert、update、delete,需要配置Hive支持事务。配置hive-site.xml文件
    如果一个表要实现update和delete功能,该表就必须支持ACID,而支持ACID,就必须满足以下条件:
    1、表的存储格式必须是ORC(STORED AS ORC);
    2、表必须进行分桶(CLUSTERED BY (col_name, col_name, …) INTO num_buckets BUCKETS);
    3、Table property中参数transactional必须设定为True(tblproperties(‘transactional’=’true’));
    创建满足条件表的样例:

    create table if not exists tablename (
      id bigint,
      sex tinyint  COMMENT '性别',
      name String COMMENT '姓名'
    ) COMMENT '用户表'
    partitioned by (year string)
    clustered by (id) into 2 buckets
    row format delimited fields terminated by '\t'
    stored as orc TBLPROPERTIES('transactional'='true');
    

    4、以下配置项必须被设定(hive-site.xml):

    <property>
        <name>hive.support.concurrency</name>
        <value>true</value>
      </property>
        <property>
        <name>hive.enforce.bucketing</name>
        <value>true</value>
      </property>
        <property>
        <name>hive.exec.dynamic.partition.mode</name>
        <value>nonstrict</value>
      </property>
      <property>
        <name>hive.txn.manager</name>
        <value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value>
      </property>
        <property>
        <name>hive.compactor.initiator.on</name>
        <value>true</value>
      </property>
      <property>
        <name>hive.compactor.worker.threads</name>
        <value>1</value>
      </property>
      <property>
        <name>hive.in.test</name>
        <value>true</value>
      </property>
    

    修改表样例:

    -- 修改数据
    INSERT INTO TABLE t2 PARTITION (country, state) VALUES (5,'刘','DD','DD');
    UPDATE t2 SET name='张' WHERE id=1;
    DELETE FROM t2 WHERE name='李四';
    

    (2)在mysql中配置hive连接的密码
    **

    #hive连接mysql,在mysql中的操作
    给mysql设置密码:mysqladmin -u root password 'mysql'
    create user 'hive' identified by 'mysql';
    grant all privileges on *.* to 'hive'@'%' with grant option;
    grant all privileges on *.* to 'hive'@'%' identified by 'mysql';
    grant all privileges on *.* to 'hive'@'jun110' identified by 'mysql';
    grant all privileges on *.* to 'hive'@'localhost' identified by 'mysql';
    flush privileges;