Hive:源码解析之本地环境搭建

在使用了hive一段时间后,对简单的hive基本原理和操作有了一些了解。hive构建与hadoop之上,是非常流行的数据仓库工具。hive将结构化的数据映射为数据文件存储在hdfs上,并提供SQL查询功能对数据进行检索和处理。最终,hive将SQL查询转换为MapReduce任务。

面对hive强大的功能,总有一些冲动想搞清其“庐山真面目”,弄懂其运行的基本流程和原理。于是开启了hive源码的学习之路。

在这里将学习过程中的经历和心得记录下来,希望对想学习hive的同学提供一些帮助。

如果想学习hive的源码,个人感觉最好的方式就是在本地机器上搭建hive环境,以代码跟踪的方式学习其运行流程。自己在搭建hive本地环境时参考了很多网上的教程,但也走了很多弯路。不是说网上的教程不对,参考别人的教程难免会遇到一些“意外的障碍”,这些障碍别人没有遇到,但自己遇到了,于是费了很多时间去解决这些障碍,但最终还是无法把环境搭建好。在这里把自己搭建hive本地环境的过程记录下来,希望对大家有所帮助。

1. 准备

建议大家在linux系统或者mac上运行hadoop和hive.

1.1 hadoop

由于hive运行在hadoop之上,所以需要在本地机器上安装并启动hadoop服务。hadoop的安装过程这里不在赘述,大家自行按照网上的教程安装。

本地必须安装hadoop。

1.2 IntelliJ

IntelliJ是一款综合的Java集成开发环境,使用范围非常广泛。之前本人使用eclipse作为集成开发环境,但在搭建hive本地环境的时候遇到很多困难。这里强烈推荐IntelliJ作为学习hive源码的集成开发环境。

不要把精力浪费在集成开发环境的选择上,就选择IntelliJ吧。

1.3 MySQL

hive默认将元数据存储在Derby数据库上,但其只允许一个会话连接。在实际生产过程中,一般选用MySQL作为hive元数据存储的数据库。

1.4 其他工具

此外,需要使用maven来构建和管理hive项目,建议安装maven。

对于以上工具,大家请自行安装,安装过程较为简单,不在一一叙述。

下面,假设大家把上面的环境已经安装完成。

2. 搭建hive本地环境

2.1 下载hive源码

我们可以选择直接下载hive的源码包,这里选定的版本1.2.1,其源码包为:apache-hive-1.2.1-src.tar.gz ,解压。

2.2 编译hive源码

进入解压目录,运行以下命令,采用maven对hive源码进行编译:

mvn clean package -DskipTests -Phadoop-2 -Pdist

编译过程会下载jar包,可能较慢,请耐心等待。

当出现下面的索引时,恭喜,hive源码编译完成。

hive编译完成

编译完成后的hive在哪呢??

编译完成后的hive位于“packaging/target/apache-hive-1.2.1-bin/apache-hive-1.2.1-bin”目录下。

2.2 启动hive

因为hive建立在hadoop之上,所以必须首先启动hadoop

假定hadoop服务已经启动。进入编译后hive所在的目录,即:HIVE_SOURCE_DIR/packaging/target/apache-hive-1.2.1-bin/apache-hive-1.2.1-bin,其中HIVE_SOURCE_DIR代表hive源码解压的目录。

进入上述目录后,运行一下命令:

bin/hive

此时就进入hive的命令行,界面如下图所示:

hive-cli

2.3 导入IntelliJ

2.3.1 打开IntelliJ,如下图所示,点击”Open”

IntelliJ

2.3.2 从hive的解压目录中选择pom.xml文件,如图所示:

pom.xml

稍等片刻,IntelliJ就会导入hive所有的Project:

pom.xml

2.3.3 调试代码

进入编译后hive所在的目录,即:HIVE_SOURCE_DIR/packaging/target/apache-hive-1.2.1-bin/apache-hive-1.2.1-bin,运行如下命令启动hive:

bin/hive --debug -hiveconf hive.root.logger=DEBUG,console

此时,界面会出现:

Listening for transport dt_socket at address: 8000

JVM会监听8000端口,等待客户端调试连接。

下面我们转到IntelliJ中进入如下配置,依次点击”Run”->”Debug…”->”Edit Configurations…“,然后点击左上角的”+”,选择”Remote”,会出现如下界面:

hive-debugger

在上图中,最重要的是配置Host和Port,记住Port为8000,想想为什么是8000呢??(废话,因为后台jvm监听8000端口!!!)。并为我们配置的调试器起个响亮的名字:hive-debugger,最后点击右下角的”Debug”,就可以进行调试了。

hive的CLI的入口类为:cli/src/java/org.apache.hadoop.hive.cli/CliDriver.java。我们在该类的主函数中设置断点,并执行我们上面配置的hive-debugger(注意,此时后台必须执行:bin/hive –debug hive.root.logger=DEBUG,console),则出现下面的界面:

debug1

我们输入的参数“hive.root.logger=DEBUG,console”,出现在debug的界面中,如上图最下方的红框内所示。

在后台输入SQL语句,就可以进行代码跟踪了。

至此,我们完成了hive源码导入IntelliJ的所有工作。

2.4 配置MySQL环境

Hive默认将元数据存储在Derby数据库中,但Derby只能允许一个会话连接,只适合简单的测试。在实际的生产环境中,一般选择MySQL作为hive存储元数据的数据库。

2.4.1 建立hive_meta数据库和hive_user用户

这里我们需要以管理员的身份登陆MySQL,并建立hive_meta数据库。

建好hive_meta数据库后,在MySQL中建立hive连接使用的用户和密码,并赋予该用户所有权限,最后刷新权限:

mysql> CREATE USER 'hive_user' IDENTIFIED BY 'hive_user_password';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'hive_user'@'localhost' IDENTIFIED BY 'hive_user_password' WITH GRANT OPTION;
mysql> flush privileges;

即: 数据库:hive_meta 用户名:hive_user 密码:hive_user_password

2.4.2 复制JDBC驱动包

本文中使用的MySQL JDBC驱动包为:mysql-connector-java-5.0.8-bin.jar。JDBC包可能需要和自己机器上的MySQL版本相对应,如果上述版本不对,请尝试其他版本。

将mysql-connector-java-5.0.8-bin.jar复制到hive编译后所在目录的lib子目录下,即HIVE_SOURCE_DIR/packaging/target/apache-hive-1.2.1-bin/apache-hive-1.2.1-bin/lib。

2.4.3 配置hive-site.xml

在hive的conf子目录下包含hive-default.xml.template文件,将该文件拷贝一份并重命名为hive-site.xml,这样我们就有了文件:HIVE_SOURCE_DIR/packaging/target/apache-hive-1.2.1-bin/apache-hive-1.2.1-bin/hive-site.xml。

这一点非常关键,因为不同机器上会有不同的结果:查看MySQL的端口号。

mysql> show global variables like 'port'

注:也可以使用下面的shell命令查看MySQL的端口:

ps -ef | grep mysqld

虽然MySQL的默认端口号为3306,网上很多教程在配置hive-site.xml时也使用3306端口。但在我的机器上,运行上述MySQL命令后得到的端口号为3307。所以大家需要根据自己的实际情况来选择,避免走弯路!!!

修改或增加hive-site.xml中下面的内容:

    <property>
        <name>javax.jdo.option.ConnectionURL</name>
        <value>jdbc:mysql://localhost:3307/hive_meta?=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_user</value>
    </property>
    <property>
        <name>javax.jdo.option.ConnectionPassword</name>
        <value>hive_user_password</value>
    </property>

解释:

“jdbc:mysql://localhost:3307/hive_meta?=createDatabaseIfNotExist=true”: hive_meta就是我们创建的数据库的名字 hive_user:用户名 hive_user_password:密码

之后,启动hive:

bin/hive

这里,可能会遇到如下错误:

Exception in thread "main" java.lang.RuntimeException: java.lang.IllegalArgumentException: java.net.URISyntaxException: Relative path in absolute URI: ${system:java.io.tmpdir%7D/$%7Bsystem:user.name%7D
    at org.apache.hadoop.hive.ql.session.SessionState.start(SessionState.java:522)
    at org.apache.hadoop.hive.cli.CliDriver.run(CliDriver.java:677)
    at org.apache.hadoop.hive.cli.CliDriver.main(CliDriver.java:621)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.hadoop.util.RunJar.main(RunJar.java:212)
Caused by: java.lang.IllegalArgumentException: java.net.URISyntaxException: Relative path in absolute URI: ${system:java.io.tmpdir%7D/$%7Bsystem:user.name%7D
    at org.apache.hadoop.fs.Path.initialize(Path.java:206)
    at org.apache.hadoop.fs.Path.<init>(Path.java:172)
    at org.apache.hadoop.hive.ql.session.SessionState.createSessionDirs(SessionState.java:563)
    at org.apache.hadoop.hive.ql.session.SessionState.start(SessionState.java:508)
    ... 7 more
Caused by: java.net.URISyntaxException: Relative path in absolute URI: ${system:java.io.tmpdir%7D/$%7Bsystem:user.name%7D
    at java.net.URI.checkPath(URI.java:1804)
    at java.net.URI.<init>(URI.java:752)
    at org.apache.hadoop.fs.Path.initialize(Path.java:203)
    ... 10 more

解决方法为:(参考:http://blog.csdn.net/zwx19921215/article/details/42776589 )

1.查看hive-site.xml配置,会看到配置值含有”system:java.io.tmpdir”的配置项 2.新建文件夹/home/grid/hive-0.14.0-bin/iotmp 3.将含有”system:java.io.tmpdir”的配置项的值修改为如上地址

2.4.4 查看hive_meta数据库

启动hive后,hive_meta数据库中自动创建多个表,这些就是存储hive元数据的表:

mysql> use hive_meta;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+---------------------------+
| Tables_in_hive_meta       |
+---------------------------+
| BUCKETING_COLS            |
| CDS                       |
| COLUMNS_V2                |
| DATABASE_PARAMS           |
| DBS                       |
| FUNCS                     |
| FUNC_RU                   |
| GLOBAL_PRIVS              |
| PARTITIONS                |
| PARTITION_KEYS            |
| PARTITION_KEY_VALS        |
| PARTITION_PARAMS          |
| PART_COL_STATS            |
| ROLES                     |
| SDS                       |
| SD_PARAMS                 |
| SEQUENCE_TABLE            |
| SERDES                    |
| SERDE_PARAMS              |
| SKEWED_COL_NAMES          |
| SKEWED_COL_VALUE_LOC_MAP  |
| SKEWED_STRING_LIST        |
| SKEWED_STRING_LIST_VALUES |
| SKEWED_VALUES             |
| SORT_COLS                 |
| TABLE_PARAMS              |
| TAB_COL_STATS             |
| TBLS                      |
| VERSION                   |
+---------------------------+

至此,hive本地环境搭建的工作就完成了。希望对大家有所帮助,谢谢。

----EOF-----

Categories: hive Tags: hive MySQL