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位于“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的命令行,界面如下图所示:
2.3 导入IntelliJ
2.3.1 打开IntelliJ,如下图所示,点击”Open”
2.3.2 从hive的解压目录中选择pom.xml文件,如图所示:
稍等片刻,IntelliJ就会导入hive所有的Project:
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”,会出现如下界面:
在上图中,最重要的是配置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),则出现下面的界面:
我们输入的参数“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本地环境搭建的工作就完成了。希望对大家有所帮助,谢谢。