Hive基础使用

Hive

Hive介绍

概述

hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。 其优点是学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析。
Hive基础使用

Hive是建立在 Hadoop 上的数据仓库基础构架。它提供了一系列的工具,可以用来进行数据提取转化加载(ETL),这是一种可以存储、查询和分析存储在 Hadoop 中的大规模数据的机制。Hive 定义了简单的类 SQL 查询语言,称为 HQL,它允许熟悉 SQL 的用户查询数据。同时,这个语言也允许熟悉MapReduce 开发者的开发自定义的 mapper 和 reducer 来处理内建的 mapper 和 reducer 无法完成的复杂的分析工作。Hive 没有专门的数据格式。 Hive 可以很好的工作在 Thrift 之上,控制分隔符,也允许用户指定数据格式。

适用场景

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

特点

Hive 是一种底层封装了Hadoop 的数据仓库处理工具,使用类SQL 的HiveQL 语言实现数据查询,所有Hive 的数据都存储在Hadoop 兼容的文件系统例如(HDFS)

Hive 在加载数据过程中不会对数据进行任何的修改,只是将数据移动到HDFS 中Hive 设定的目录下,因此,Hive 不支持对数据的改写和添加,所有的数据都是在加载的时候确定的。

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

数据存储

首先Hive 没有专门的数据存储格式,也没有为数据建立索引,用户可以非常自由的组织 Hive 中的表,只需要在创建表的时候告诉 Hive 数据中的列分隔符和行分隔符,Hive 就可以解析数据。其次Hive 中所有的数据都存储在 HDFS 中,Hive 中包含以下数据模型:表(Table),外部表(External Table),分区(Partition),桶(Bucket)。

  • Hive 中的 Table 和数据库中的 Table 在概念上是类似的,每一个 Table 在 Hive 中都有一个相应的目录存储数据。
  • Partition 对应于数据库中的 Partition 列的密集索引,但是 Hive 中 Partition 的组织方式和数据库中的很不相同。在 Hive 中,表中的一个 Partition 对应于表下的一个目录,所有的 Partition 的数据都存储在对应的目录中。
  • Buckets 对指定列计算 hash,根据 hash 值切分数据,目的是为了并行,每一个 Bucket 对应一个文件。将 user 列分散至 32 个 bucket,首先对 user 列的值计算 hash,对应 hash 值为 0 的 HDFS 目录为:/wh/pvs/ds=20090801/ctry=US/part-00000;hash 值为 20 的 HDFS 目录为:/wh/pvs/ds=20090801/ctry=US/part-00020

Hive安装搭建

1.必须配置HADOOP_HOME环境变量
2.必须保证HDFS、YARN服务正常运行
3.需要本机安装MySQL服务 latin编码 默认
Hive HQL解析引擎 – MapReduce程序
逻辑表 元数据(数据路径,数据格式) 需要存在 MySQL中

  • 解压/apache-hive-1.2.1-bin.tar.gz文件到/usr目录下
tar -zxvf apache-hive-1.2.1-bin.tar.gz -C /Usr
  • 配置conf/hive-site.xml文件

hive-site.xml(该文件不存在,需要手动创建)

<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
        <property>
                <name>javax.jdo.option.ConnectionURL</name>
                #hive的元数据是存在Mysql中的所以需要连接mysql
                # 这里使用本地的mysql数据库 172.16.11.19 本地的ip4地址
                <value>jdbc:mysql://172.16.11.19:3306/test</value>
                <!--使用linux中安装的mysql数据库
                <value>jdbc:mysql://hadoop:3306/test</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>my
                <value>123456</value>
         </property>
</configuration>

  • 拷贝MySQL的驱动jar文件到hive的lib 目录

    [[email protected] apache-hive-1.2.1-bin]# mv /usr/mysql-connector-jar-5.1.6.jar /usr/apache-hive-1.2.1-bin/lib
    
  • 拷贝hive安装lib目录下jline-2.12.jar到hadoop的share/Hadoop/yarn/lib目录下

    [[email protected] apache-hive-1.2.1-bin]# cp lib/jline-2.12.jar /usr/hadoop-2.6.0/share/hadoop/yarn/lib/
    
  • 删除低版本的Jline

    [[email protected] apache-hive-1.2.1-bin]# rm -rf lib/jline-0.9.94.jar
    
  • 修改hdfs文件的权限

     [[email protected] apache-hive-1.2.1-bin]# hdfs dfs -chmod -R 777 /
    
  • 启动

    方案1:(老版本 hive-cli连接)缺点:单用户访问操作

    [[email protected] apache-hive-1.2.1-bin]# ./bin/hive
    

    方案2:

    1.启动服务

    [[email protected] apache-hive-1.2.1-bin]# ./bin/hiveserver2
    

Hive基础使用

2.链接服务

[[email protected] apache-hive-1.2.1-bin]# ./bin/beeline -u jdbc:hive2://localhost:10000

也可以在linux系统中安装的mysql启动时如果出现问题:Exception in thread “main” java.lang.RuntimeException: java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient`

原因是mysql数据库没有开启远程服务配置MySQL服务,开启MySQL的远程访问

[[email protected] ~]# yum install -y mysql-server
[[email protected] ~]# service start mysqld
[[email protected] ~]# mysqladmin -u root password 'root'
[[email protected] ~]# mysql -u root -proot
   mysql> use mysql
   mysql> delete from user where user='' or password='';
   mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
   mysql> FLUSH PRIVILEGES;
   mysql> exit
[[email protected] ~]# chkconfig mysqld on
说明 指令
启动MySQL service mysqld start
指定用户 mysqladmin -u root password ‘root’
开启远程访问 mysql –u root –prootuse mysql;delete from user where user=’’ or password=’’;GRANT ALL PRIVILEGES ON . TO ‘root’@’%’ IDENTIFIED BY ‘root’ WITH GRANT OPTION;FLUSH PRIVILEGES;exit;

权限不足错误

#修改hdfs文件的权限
[[email protected] apache-hive-1.2.1-bin]# hdfs dfs -chmod -R 777 /

重新启动服务

[[email protected] apache-hive-1.2.1-bin]# ./bin/beeline -u jdbc:hive2://localhost:10000

Hive基础使用

测试

查询数据库

Hive基础使用

创建数据库

Hive基础使用

HIVE常见操作

数据库相关

  • 创建数据库: create database 数据库名;
  • 删除库表: drop database 数据库名 [cascade];
  • 查看库表信息 : desc database 数据库名;
  • 切换数据库: use 数据库;

数据类型

数据类型(primitive,array,map,struct)
①primitive(原始类型)

  • 整数:TINYINT、SMALLINT、INT、BIGINT

  • 布尔:BOOLEAN

  • 小数:FLOAT、DOUBLE

  • 字符:STRING、CHAR、VARCHAR

  • 二进制:BINARY

  • 时间类型:TIMESTAMP、DATE

②array(数组类型): ARRAY < data_type >
③map(key-value类型):MAP < primitive_type, data_type >
④struct(结构体类型):STRUCT <col_name:data_type, …>

Hive默认分隔符

分隔符 描述
\n 对于文本来说,每一行都是一条记录。因此\n可以分割记录。
^A(Ctrl+a) 用于分割字段(列),在create table中可以使用\001表示。
^B(Ctrl+b) 用于分割array或者是struct中 的元素或者用于map结构中的k-v对的分隔符,在create table中可以使用\002表示。
^C(Ctrl+c) 用于Map中k-v的分隔符,在create table中可以使用\003表示。

表相关

Hive基础使用

  • 查看表:desc formatted t_user;

  • 创建表:

     #创建表t_user
     create table t_user(
     id int ,
     name varchar(32),
     sex boolean,
     birth date
     );
     #附注: 这里的^A 在VI编辑器下按住Ctrl+v ,Ctrl+a实现
     #本地创建t_user数据文件
     1^Ajiangzz^Atrue^A1990-12-13
     2^Azhangsan^Afalse^A1989-10-10
     #加载数据到t_user表
     load data local inpath '/root/t_user' overwrite into table t_user;
    

    创建表t_order

    create table t_order(
        id int,name varchar(32),
        num int,
        price double,
        tags array<string>,
        user_id int
    );
    #附注: 这里的^A 在VI编辑器下按住Ctrl+v ,Ctrl+a实现
    #本地创建t_order数据文件
    1^A苹果^A2^A3.5^A水果^B实惠^A1
    2^A哈密瓜^A1^A6.5^A水果^B很贵哦^A1
    #加载数据到表
    load data local inpath '/root/t_order' overwrite into table t_order;
    

    创建t_location

    create table t_location(
          id int ,
          name varchar(64),
         address struct<country:string,city:string>
    );
    #附注: 这里的^A 在VI编辑器下按住Ctrl+v ,Ctrl+a实现,其他依次类推
    #本地创建t_location数据文件
    1^A国际大厦^A中国^B北京
    2^A东北楼^A中国^B海淀区
    #加载数据到表
    load data local inpath '/root/t_location' overwrite into table t_order;
    

    以上案例使用的是指定的数据格式,hive还支持持自定义数据格式,正则匹配,json匹配、CSV/TSV等格式数据的分析。

    自定义分隔符数据

    # 在建表是声明自定义分隔符
    create table t_user(
        id int,
        name varchar(32),
        sex boolean,
        birth date
    )
    row format delimited 
    fields terminated by ','
    lines terminated by '\n';
    #本地创建数据文件
    1,zs,true,1991-09-08
    2,ls,true,1991-09-08
    
    
    # 在建表是声明自定义分隔符
    create table t_order(
       id int,
       name varchar(32),
       num int,
       price double,
       tags array<string>,
       user_id int
    )
    row format delimited 
    fields terminated by ','
    collection items terminated by '|'
    lines terminated by '\n';
    # 本地数据
    1,苹果,2,3.5,水果|好吃|实惠,1
    2,哈密瓜,1,6.5,水果|小贵,1
    #附注:如果含有map类型 则使用 map keys terminated by '分隔符'限定。
    

    正则数据 regex101.com

    # 建表时创建声明
    create table t_user(
         id int,
         name varchar(32),
         sex boolean,
         birth date
    )
    ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
    WITH SERDEPROPERTIES (
      "input.regex"="(^[0-9]*) ([a-z]*) (true|false) ([0-9]{4}-[0-9]{2}-[0-9]{2})"
    )
    # 创建本地数据
    1 zhangsan true 1992-02-08
    2 lisi false 1989-02-03
    

    JSON数据

    create table t_user_json(
    	id int,
    	name varchar(32),
    	sex boolean,
    	birth date
    )ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe';
    #ADD JAR /usr/apache-hive-1.2.1-bin/hcatalog/share/hcatalog/hive-hcatalog-core-1.2.1.jar ;
    
  • 加载数据到指定表

    • hdfs shell 将数据加载到指定的表所在的目录即可

      - hdfs dfs -put t_user.data /user/hive/warehouse/baizhi.db/t_user
      
    • Hive脚本命令

      load data [local] inpath '/root/t_user.data' [overwrite] into table t_user;
      

      [local]:表示从OS系统拿,如果去掉表示从HDFS[overwrite]:是否覆盖原有数据

表分类

HIVE的表按类型 分为 管理表、外部表、分区表。

  • 管理表: 前面章节案例中所创建的表都称为管理表,有时候也称为内部表。因为这种表hive会控制数据的生命周期(在删除表的同时也会删除dhfs上的文本数据)因此管理表不方便和其他工作共享数据。

  • 外部表: 和管理表比较外部表在创建的时候多一个中external关键字告诉Hive这是外部表,而后面的location则是告诉hive数据位于哪个位置或者路径下。因为是外部表hive并非完全拥有这些数据,因此在删除外部表的时候并不会删除location参数指定路径的数据。

    #外部表,不管理数据,删除表并不会删除数据。
    create external table if not exists t_user(
       name string ,
       salary float ,
       subordinates array<string> ,
       deductions map<string,float> ,
       address struct<country:string,state:string> 
      )
      row format delimited 
      fields terminated by ','
      collection items terminated by '|' 
      map keys terminated by '>' 
      lines terminated by '\n' 
      stored as textfile 
      location '/hive/database/baizhi.db/t_user'  
      tblproperties ('creator'='jiangzz')
    
    
  • 分区表: 无论外部表还是管理表都可以在创建的时候指定分区,对于这种指定分区的表称为分区表。数据库分区的概念已经纯在很久,其可以有多种形式,但是通常是使用分区来水平分散压力,将数据从物理上转移和使用最频繁的用户更接近的地方,以及实现其他目的。

    # 特点:分区来水平分散压力
    create external table if not exists t_user(
        name string comment 'this is name',
        salary float comment 'salary of user',
        subordinates array<string> comment 'names of  suordinates',
        deductions map<string,float> comment 'names>percentage'
    )comment 'user table'  
    partitioned by (country string,state string) 
    row format delimited 
    fields terminated by ',' 
    collection items terminated by '|' 
    map keys terminated by '>' 
    lines terminated by '\n' 
    stored as textfile 
    location '/hive/database/baizhi.db/t_user'  
    tblproperties ('creator'='jiangzz');
    
    
  • 分区操作

    • 查看分区:show partitions t_user;
    • 删除分区:alter table t_user drop partition(country=‘china’,state=‘beijing’);
      附注:对于管理表删除分区也会将数据删除,但是外部表再删除分区的时候分区的数据不会被删除。
    • 添加分区 :alter table t_user add partition(country=‘china’,state=‘beijing’);
      附注添加多个分区数据:
    alter table t_user add if not exists partition(country='china',state='beijing') location 'hive/database/baizhi.db/t_user/country=china/state=beijing' partition(country='china',state='shanghai') location 'hive/database/baizhi.db/t_user/country=china/state=shanghai'
    
  • Drop表

    DROP TABLE [IF EXISTS] table_name [PURGE];
    

    DROP TABLE 删除 metadata 如果配置了Trash该表的数据数据实际上移动到.Trash/Current 目录( 此时不可指定PURGE 参数). 当删除的是EXTERNAL表,系统的数据不会被删除。

    其中PURGE 选项是version 0.14.0添加的一个选项,如果加入了 该参数,数据是不会移动到回收站的因此如果表被误删后数据是无法恢复。

  • Truncate Table

    TRUNCATE TABLE table_name [PARTITION partition_spec];
    partition_spec:
      : (partition_column = partition_col_value, partition_column = partition_col_value, ...)
    
    

    删除表(指定分区)的数据,数据将会被移动到Trash中去。默认只可以truncate 管理表|native表,不可以对external表做截断。如果不指定 分区信息默认会将所有分区数据截断。

Hive On Hbase

将HBase中的数据存到Hive中的数据仓库中并计算
  • 开启HBase服务(需要依赖zookeeper服务)确保HBase服务正常运行

    # 启动zookeepr服务
    [[email protected] zookeeper-3.4.6]# bin/zkServer.sh conf/zoo.cfg 
    # 启动HBase服务
    [[email protected] ~]# start-hbase.sh
    
  • 开启服务

    [[email protected] apache-hive-1.2.1-bin]# ./bin/hiveserver2
    
  • 启动连接服务

    [[email protected] apache-hive-1.2.1-bin]# ./bin/beeline -u jdbc:hive2://localhost:10
    
  • 在连接服务窗口创建Hive表根据HBase中数据进行映射

    create external table t_user(id string,name string,age int,sex boolean) stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' with serdeproperties('hbase.columns.mapping'=':key,cf1:name,cf1:age,cf1:sex') tblproperties('hbase.table.name'='baizhi:t_user');
    
    

集成Api

maven依赖

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-client</artifactId>
    <version>2.6.0</version>
</dependency>
<dependency>
    <groupId>org.apache.hive</groupId>
    <artifactId>hive-jdbc</artifactId>
    <version>1.1.0</version>
</dependency>

测试代码

package com.baizhi;

import java.sql.*;

/**
 * 注意:
 *      hive的java api操作符合jdbc的六步骤
 *      只需要修改 驱动类和url地址
 */
public class HiveJDBCDemo {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        String driverClassName = "org.apache.hive.jdbc.HiveDriver";
        Class.forName(driverClassName);

        // -u
        Connection connection = DriverManager.getConnection("jdbc:hive2://192.168.11.131:10000/baizhi");

        String sql = "select avg(salary) from t_user";

        PreparedStatement pstm = connection.prepareStatement(sql);

        ResultSet resultSet = pstm.executeQuery();

        while (resultSet.next()) {
            double avg = resultSet.getDouble(1);
            System.out.println("用户的平均工资:"+avg);
        }

        resultSet.close();
        pstm.close();
        connection.close();
    }
}