Hive踩坑日记

Hadoop 家族动物园里属这个蜜蜂配置过程中坑最多,得动动笔了。


前言

Hive 是个啥?移步 传送门

踩坑环境

软件 版本
虚拟机系统 Ubuntu Server 16.04.2
Hadoop Hadoop 2.6.0
MySQL MySQL 5.7

准备工作

MySQL 扮演的角色是存储 Hive 库的元数据,当然还可配置其它的方式存储,这里不多说。Hive 前期配置多数坑都在 MySQL 这,所以把 MySQL 整好会顺利许多。

1. 配置远程访问

$ sudo vim /etc/mysql/my.cnf

bind-address=127.0.0.1 改为 自己机器的 IP。

特别说明:Ubuntu 新版的 MySQL 中 my.cnf 里不直接显示属性了,默认属性值被移到 /etc/mysql/conf.d/mysql.cnf/etc/mysql/mysql.conf.d/mysql.cnf 里。所以可参考 /etc/mysql/mysql.conf.d/mysql.cnf 文件来进行配置。

# 在 /etc/mysql/my.cnf 文件末尾配置新值以覆盖默认值
[mysqld]
bind-address=your_machine_ip

[mysqld] 是属性组,不加不符合语法,会导致 MySQL 服务无法启动。

# 查看当前启动的 MySQL 的属性值
$ mysql --help

2. 新建 hive 用户来操作 MySQL
为 Hive 新建一个 MySQL 用户来专门操作 Hive 的元数据库。

$ mysql -uroot -p

mysql> grant all privileges on *.* to hive@"Master" identified by "hive";
mysql> flush privileges;

最好是仅赋予 Hive 用户操作元数据库的权限,我为了操作方便就权限全给了。”Master” 是我配置的机器主机名,用于 hadoop 等集群搭建的。

3. 准备好 JDBC 驱动包
将 jdbc 驱动包放到 ${HIVE_HOME}/lib/ 下,尽量用高本版驱动,驱动版本不对也会导致启动 Hive 时出错,这里我是选择了:mysql-connector-java-5.1.40-bin

坑来~

1. hive-site.xml 中 MySQL jdbc 连接地址出错

# 异常信息
The reference to entity "XXX" must end with the ';' delimiter

我当时写的是:
jdbc:mysql://Master:3306/metastore?createDatabaseIfNotExist=true&useSSL=false,后来在这篇博客中得知”&“这类特殊字符在 xml 文件中需要转义,写成”&“就OK了。

在 xml 文件中还有几个常见的字符需要转义替换:

原字符 转义字符
& &
< &lt;
> &gt;
&quot;
&apos;

2. hive 命令进入 Hive CLI(command line interface) 异常

$ hive

Exception in thread "main" java.lang.RuntimeException: java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient
at org.apache.hadoop.hive.ql.session.SessionState.start(SessionState.java:444)
at org.apache.hadoop.hive.cli.CliDriver.run(CliDriver.java:672)
at org.apache.hadoop.hive.cli.CliDriver.main(CliDriver.java:616)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

原因:没有正常启动 Hive 的 Metastore Server 服务。
解决方法:后台启动 Hive 的 Metastore Server服务:

$ hive --service metastore &

3. hiveserver 启动异常

$ hive --service hiveserver &

Exception in thread "main" java.lang.ClassNotFoundException: org.apache.hadoop.hive.service.HiveServer
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)

进入 Hive CLI 前需要先启两个服务一个是 (1) 中说的 metastore server,还有一个 hiveserver

这里的异常解决方法:

# 类是 hiveserver2 ... 额
$ hive --service hiveserver2 &

4. hive 命令进入 Hive CLI 异常

$ hive

[ERROR] Terminal initialization failed; falling back to unsupported
java.lang.IncompatibleClassChangeError: Found class jline.Terminal, but interface was expected
at jline.TerminalFactory.create(TerminalFactory.java:101)
at jline.TerminalFactory.get(TerminalFactory.java:158)
at jline.console.ConsoleReader.<init>(ConsoleReader.java:229)
at jline.console.ConsoleReader.<init>(ConsoleReader.java:221)
at jline.console.ConsoleReader.<init>(ConsoleReader.java:209)
at org.apache.hadoop.hive.cli.CliDriver.getConsoleReader(CliDriver.java:773)

这个异常原因在 Hive 官方文档里有说:

Hive has upgraded to Jline2 but jline 0.9x exists in the Hadoop lib.

解决方法:

# 删除老版本的 jline.jar
$ rm ${HADOOP_HOME}/share/hadoop/yarn/lib/jline-0.9.94.jar

# 拷贝新版本 jline.jar 到相应的 hadoop lib 目录下
$ cp ${HIVE_HOME}/lib/jline-2.12.jar ${HADOOP_HOME}/share/hadoop/yarn/lib/


继续踩坑中……


参考资料

[1] The reference to entity “characterEncoding” must end with the ‘;’ delimiter

[2] Hive常见问题汇总

[3] hive startup -[ERROR] Terminal initialization failed; falling back to unsupported

手滑了就鼓励一下吧~