Hive是一个基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析。在本质上,Hive与Pig一样,都是将相应的查询语句转换为MapReduce程序,简化数据处理过程。不过相比Pig来说,Hive使用的HiveQL语言很接近SQL语言,因此对于开发人员来说更容易上手,使用频率也更高。
1、基本概念
Hive是一个建立在Hadoop之上的数据仓库分析工具,可以通过类似SQL的查询语言HiveQL对存储在Hadoop中的大规模数据进行存储、查询和分析操作。除了某些带*的查询操作不通过MapReduce执行外(例如语句:select * from t1,可直接查询HDFS,不会生成MR任务),几乎其他所有的HiveQL查询操作会被转化为优化后的MapReduce程序执行。
本质上分析,Hive其实是一个SQL解析引擎,能够将SQL语句解析并转换为MapReduce任务来执行。hive有一套映射工具,可以把SQL转换为MapReduce中的job,可以把SQL中的表、字段转换为HDFS中的文件(夹)以及文件中的列。这套映射工具称之为metastore,一般存放在derby、mysql中。
Hive与传统的关系型数据库有以下区别:①数据存储不同。Hive存储基于Hadoop的HDFS,而关系数据库则基于本地操作系统的文件系统;②计算模型不同。Hive基于Hadoop的MapReduce,而关系数据库则基于索引的内存计算模型;③应用场景不同。Hive适用于海量数据查询,实时性很差,而关系数据库使用普通数据查询,实时性较高;④扩展性不同。Hive基于Hadoop之上,很容易通过分布式的节点增加来扩大存储能力和计算能力,而关系数据库水平扩展很难,只能不断增加单机的性能。
2、数据模型
Hive包含四中数据模型,分别是:表(Table)、分区(partition)、桶(Bucket)和外部表(External Table)。
1) 表(Table):与关系数据库中的表在概念上是类似的,包含行和列。每一个Hive表都有一个HDFS对应的文件与之对应,表数据就存储在该文件中。
2) 分区(partition):数据表的分区,一个分区对应一个HDFS目录文件。可根据指定列进行分区,例如按天(day)和小时(hour)对大数据量的销售表进行分区,那么不同分区对应的HDFS文件路径分别为.../day={day}/hour={hour}。分区表在查询时可指定查询,而不必全表扫描,大大提高了效率。
3) 桶(Bucket):对指定列计算hash,根据不同hash值切分数据,每个bucket对应一个文件,可以实现并行操作。例如将一个表分为16个bucket,那么存储位置分布范围从.../TableName/part-00000到.../TableName/part-00015。
4) 外部表(External Table):与表结构和用法是一致的,区别在于对应的文件存储位置不同以及表删除操作时对应文件是否会被删除。除了外部表,其余三种模型的表数据都是存储于HDFS的指定Hive存储目录下,该目录由配置文件hive-site.xml中的${hive.metastore.warehouse.dir}指定,默认值/user/hive/warehouse。在其他三种模型的数据加载过程中,对应的数据会被同时移动到上述Hive存储目录中,同时在删除记录或销毁表时,对应的数据也会被删除。但是外部表对应的HDFS文件可以不受Hive的控制,也即是外部表可以直接加载已经存在的HDFS文件,而不用移动到指定存储目录中,同时在删除外部表后,对应的数据也不会被删除。
此外,还可以创建外部分区表,由于外部分区表元数据不存在分区信息,因此创建表后需要手动添加分区信息,才可以查询到数据。
需要注意的是,hive的元数据表中只存储关于表结构的一些信息,记录都是存储于hdfs中,因此直接操作hdfs文件内容,等同于通过HiveQL语句操作记录;
3、元数据表
配置mysql保存元数据表后,可以在hive库中看到许多元数据表,如DBS、TBS、SDS等。重要元数据表说明如下:
▶ DBS:记录了hive表存储于HDFS中的位置;
▶ TBS:记录了表的名称、表所属的数据库id,以及表的类型(外部表EXTERNAL_TABLE,其他MANAGED_TABLE);
▶ SDS:记录了表对应于HDFS的路径,可根据TBS中SD_ID字段关联;
▶ COLUMNS_V2:记录表字段信息,与SDS表中的CD_ID字段关联;
▶ PARTITIONS:记录分区表的分区信息,与TBS中的TBL_ID字段关联。当创建一个外部分区表后,需要手动添加分区,否则查询不到数据;
1、安装步骤
Hive就是一个客户端,因此安装时不必考虑集群模式或伪分布模式。本实例安装版本:apache-hive-1.2.0-bin.tar.gz。
如果使用默认的Derby数据库来存储元数据,不需要修改任何配置就可以启动hive客户端,启动命令:/usr/local/hive/bin/hive
2、MySQL集成元数据配置
Hive中的元数据包括表的名字、表的列、表的分区、表分区的属性、表的属性(是否为外部表等)、表的数据所在目录等。
Hive的元数据默认保存在内嵌的Derby数据库中,存在一个很大的问题,Derby数据库是独占式的,也就是说同时只能允许一个会话连接,多个会话无法同时共享数据。而且,Derby数据文件产生的位置由当前运行Hive命令所在的目录决定,因此使用默认的Derby保存元数据很不方便,只适合简单的测试。
默认的Derby数据库存储位于为当前运行hive命令所在的目录(pwd),并且每次切换目录后运行hive都会在当前目录下生成元数据目录。如在/root中通过命令:/usr/local/hive/bin/hive运行hive客户端,则会在/root下生成metastore_db元数据存储文件目录,然后切换目录到/usr下,仍然通过命令:/usr/local/hive/bin/hive运行hive客户端,则还会在/usr下生成一个metastore_db目录。并且对于每一个metastore_db目录,都只能同时允许一个客户端使用,多个ssh客户端切换到同一目录,然后运行hive,则第二个客户端就无法启动。对于这种设计,也是醉了~
Hive的元数据存储数据库metastore目前只支持mysql和derby。Hive中的元数据包括表的名字、表的列和分区及其属性、表的属性(是否为外部表等)、表的数据所在目录等。
通常在安装Hive后,为支持多个会话连接,都会将元数据配置保存于MySQL中,需要做如下配置:
1) 在Linux上正确安装MySQL(官方下载:http://ftp.kaist.ac.kr/mysql/Downloads/),本实验安装版本为:MySQL-server-5.1.73-1.glibc23.x86_64.rpm、MySQL-client-5.1.73-1.glibc23.x86_64.rpm;
2) 使用rpm命令正确安装server与client后,通过/usr/bin/mysql_secure_installation命令对mysql进行初始化,设置删除匿名用户、允许远程连接等;
3) 将MySQL连接驱动文件mysql-connector-java-xxx.jar(本实验:mysql-connector-java-5.1.34-bin.jar)拷贝至Hive的lib目录下;
4) 修改Hive的hive-site.xml配置文件(如果hive-site.xml不存在,将hive-default.xml.template重命名),修改内容如下所示:
<property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true</value> <description>JDBC connect string for a JDBC metastore</description> </property> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>com.mysql.jdbc.Driver</value> <description>Driver class name for a JDBC metastore</description> </property> <property> <name>javax.jdo.option.ConnectionUserName</name> <value>root</value> <description>username to use against metastore database</description> </property> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>123456</value> <description>password to use against metastore database</description> </property>