一、说明
Hive默认情况下使用derby作为元数据库,derby元数据库只允许单连接,如果两个会话在相同目录去连接hive,会导致第二个连上的用户做相同操作报错,如下图:
A用户连接到hive,并创建一个表,创建完成后只需show tables操作
[root@hadoop-server01 hive-0.12.0-bin]# bin/hive
hive> create table t_user(id int,name string) row format delimited fields terminated by ',';
hive> show tables;
OK
t_user
可以看出该会话正常输出用户表t_user
B用户在相同目录连接到hive,并执行show tables操作
[root@hadoop-server01 hive-0.12.0-bin]# bin/hive
hive> show tables;
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.metastore.HiveMetaStoreClient
报错,不能实例化HiveMetaStoreClient客户端
C用户在另外的目录连接hive,并只需show tables操作
[root@hadoop-server01 tmp]# pwd
/tmp
[root@hadoop-server01 tmp]# /usr/local/apps/hive-0.12.0-bin/bin/hive
hive> show tables;
OK
Time taken: 3.371 seconds
可以看出,C用户可以正常连接hive并只需show tables操作,但是C用户执行结果和A用户完全不一样,看到的信息完全不一样
原因在于如果使用hive自带的derby元数据库,则每个用户连接hive时都会在当前目录维护一个metastore_db,每个hive连接客户端都会将自己产生的信息存放到自己目录下的metastore_db,这就导致了不同客户端连接看到的信息不一致。这种情况下需要使用外部数据库作为其元数据库可以解决此问题
[root@hadoop-server01 tmp]# ll
drwxr-xr-x. 2 root root 4096 Jul 8 23:45 hsperfdata_root
drwxr-xr-x. 5 root root 4096 Jul 8 23:44 metastore_db
drwx------. 2 gdm gdm 4096 Jul 8 18:22 orbit-gdm
[root@hadoop-server01 tmp]#
二、Hive外部元数据库配置
这里使用mysql数据库作为hive的外部元数据库,因此在进行hive元数据库连接配置前需要安装mysql数据库
1、安装mysql
安装介质:
[root@hadoop-server03 mysql]# ll
total 910036
-rw-r--r--. 1 root root 461608960 Sep 8 2016 mysql-5.7.15-1.el6.x86_64.rpm-bundle.tar
-rw-r--r--. 1 root root 23848332 Aug 25 2016 mysql-community-client-5.7.15-1.el6.x86_64.rpm
-rw-r--r--. 1 root root 335156 Aug 25 2016 mysql-community-common-5.7.15-1.el6.x86_64.rpm
-rw-r--r--. 1 root root 3738016 Aug 25 2016 mysql-community-devel-5.7.15-1.el6.x86_64.rpm
-rw-r--r--. 1 root root 39068680 Aug 25 2016 mysql-community-embedded-5.7.15-1.el6.x86_64.rpm
-rw-r--r--. 1 root root 134926080 Aug 25 2016 mysql-community-embedded-devel-5.7.15-1.el6.x86_64.rpm
-rw-r--r--. 1 root root 2174796 Aug 25 2016 mysql-community-libs-5.7.15-1.el6.x86_64.rpm
-rw-r--r--. 1 root root 1722992 Aug 25 2016 mysql-community-libs-compat-5.7.15-1.el6.x86_64.rpm
-rw-r--r--. 1 root root 150695776 Aug 25 2016 mysql-community-server-5.7.15-1.el6.x86_64.rpm
-rw-r--r--. 1 root root 105088968 Aug 25 2016 mysql-community-test-5.7.15-1.el6.x86_64.rpm
-rw-r--r--. 1 root root 8652406 Nov 1 2016 mysql-connector-java-5.0.8.tar.gz
开始安装:
[root@hadoop-server03 mysql]# rpm -ivh *.rpm --force --nodeps
Preparing... ########################################### [100%]
1:mysql-community-common ########################################### [ 11%]
2:mysql-community-libs ########################################### [ 22%]
3:mysql-community-client ########################################### [ 33%]
4:mysql-community-server ########################################### [ 44%]
5:mysql-community-devel ########################################### [ 56%]
6:mysql-community-embedde########################################### [ 67%]
7:mysql-community-embedde########################################### [ 78%]
8:mysql-community-test ########################################### [ 89%]
9:mysql-community-libs-co########################################### [100%]
备注:我这里由于已经安装了所有的依赖包,所以使用了 --force --nodeps选项,不推荐使用这一的方法安装,建议在安装前把所有的依赖包都安装全了之后再执行mysql的安装。
启动mysql数据库
[root@hadoop-server03 mysql]# service mysqld start
Initializing MySQL database: [ OK ]
Installing validate password plugin: [ OK ]
Starting mysqld: [ OK ]
为此mysql安装完成,这里我们创建一个hive账号来管理hive的元数据
mysql> create database hive;
GRANT ALL PRIVILEGES ON *.* TO 'hive'@'%' IDENTIFIED BY 'hive#2018' WITH GRANT OPTION;
FLUSH PRIVILEGES;
为此存放hive元数据的数据库hive也创建完成,且允许远程连接。
2、修改hive配置文件
要使hive连接外部元数据库,只需要修改hive-site.xml即可
[root@hadoop-server01 conf]# cd /usr/local/apps/hive-0.12.0-bin/conf/
[root@hadoop-server01 conf]# vi hive-site.xml
<configuration>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://hadoop-server03:3306/hive?createDatabaseIfNotExist=true</value>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>hive</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>hive#2018</value>
</property>
</configuration>
只需要修改标红部分即可,也就是连接mysql数据库的信息
3、上传mysql jdbc连接驱动包
这里使用mysql-connector-java-5.0.8.tar.gz
将mysql-connector-java-5.0.8.tar.gz上传到hive的lib目录,上传后如下:
[root@hadoop-server01 lib]# ll mysql-connector-java-5.0.8-bin.jar
-rw-r--r--. 1 root root 540852 Nov 21 2016 mysql-connector-java-5.0.8-bin.jar
[root@hadoop-server01 lib]#
4、测试验证
在任意位置执行hive命令连接hive
A用户执行
hive> show tables;
OK
Time taken: 3.545 seconds
hive>
创建一个表
hive> create table t_test (id int,name string) row format delimited fields terminated by ',';
OK
Time taken: 0.225 seconds
hive>
hive> show tables;
OK
t_test
B用户在相同目录连接hive
hive> show tables;
OK
t_test
Time taken: 1.821 seconds, Fetched: 1 row(s)
B用户获取的内容同A用户相同
C用户在不同目录连接hive
hive> show tables;
OK
t_test
C用户在不同目录看到的信息同AB用户完全一致
因此使用外部的关系型数据库作为hive元数据后,可以解决hive使用默认的derby数据库存在问题,且保障了元数据存放的一致性。
查看hive数据库中存放的元数据记录,通过查询得知hive的元数据建表信息主要存放在TBLS表中,如下图:
mysql> desc TBLS
-> ;
+--------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+---------+-------+
| TBL_ID | bigint(20) | NO | PRI | NULL | |
| CREATE_TIME | int(11) | NO | | NULL | |
| DB_ID | bigint(20) | YES | MUL | NULL | |
| LAST_ACCESS_TIME | int(11) | NO | | NULL | |
| OWNER | varchar(767) | YES | | NULL | |
| RETENTION | int(11) | NO | | NULL | |
| SD_ID | bigint(20) | YES | MUL | NULL | |
| TBL_NAME | varchar(128) | YES | MUL | NULL | |
| TBL_TYPE | varchar(128) | YES | | NULL | |
| VIEW_EXPANDED_TEXT | mediumtext | YES | | NULL | |
| VIEW_ORIGINAL_TEXT | mediumtext | YES | | NULL | |
+--------------------+--------------+------+-----+---------+-------+
11 rows in set (0.00 sec)
mysql> select TBL_ID,TBL_NAME,TBL_TYPE from TBLS;
+--------+----------+---------------+
| TBL_ID | TBL_NAME | TBL_TYPE |
+--------+----------+---------------+
| 1 | t_test | MANAGED_TABLE |
+--------+----------+---------------+
1 row in set (0.00 sec)
如果要删除hive在mysql中定义的表,可以通过mysql语句去删除,通过hive删除会报错。
hive> show tables;
OK
t_t
t_t1
t_t5
现在通过mysql删除t_t5表
mysql> delete from tbls where tbl_id = 3;
Query OK, 1 row affected (0.11 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
hive> show tables;
OK
t_t
t_t1
现在t_t5表已经被删除