最近用到了Hive Hook的一些功能,每次打包后都要将jar包拷贝到CDH集群中,还要重启Hive,很麻烦。且传入Hook类中的HookContext对象用Json工具类转换成Json时某些情况下有问题,想看其中的具体内容很不方便。尝试用alibaba的arthas工具attach到hiveserver2上通过monitor方法查看参数,发现该工具无法打印层次太深的成员变量。So,研究了一下Hive源码调试方法,这样在调试Hive Hook这类应用比较方便,如果后续要看Hive内部原理之类的,也方便通过调试学习。
本文介绍的方法通过搭建一个单节点hadoop,然后编译Hive源码,通过hive启动相关hive服务时,在要调试的hive服务的启动命令中添加–debug选项,通过远程调试的方式来调试Hive的相关服务。(不知道网上有些地方说的不需要hadoop能否运行哈,反正我没试成功)
使用的Hive版本为CDH6.3.0对应的hive版本。
简单配置一个可用的单节点hadoop即可。
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
fs.default.name
hdfs://kali:9000
hadoop.tmp.dir
file:///root/tool/BD/hadoop.data.dir/tmp
hadoop.proxyuser.sqoop2.hosts
*
hadoop.proxyuser.sqoop2.groups
*
hadoop.proxyuser.root.hosts
*
hadoop.proxyuser.root.groups
*
fs.file.impl
org.apache.hadoop.fs.LocalFileSystem
fs.hdfs.impl
org.apache.hadoop.hdfs.DistributedFileSystem
dfs.replication
1
dfs.namenode.name.dir
file:///root/tool/BD/hadoop.data.dir/dfs/name
dfs.datanode.data.dir
file:///root/tool/BD/hadoop.data.dir/dfs/data
dfs.namenode.secondary.http-address
kali:9001
mapreduce.framework.name
yarn
mapreduce.jobhistory.address
kali:10020
mapreduce.map.memory.mb
1024
mapreduce.reduce.memory.mb
2048
yarn.app.mapreduce.am.env
HADOOP_MAPRED_HOME=/root/tool/BD/hadoop-3.0.0
mapreduce.map.env
HADOOP_MAPRED_HOME=/root/tool/BD/hadoop-3.0.0
mapreduce.reduce.env
HADOOP_MAPRED_HOME=/root/tool/BD/hadoop-3.0.0
yarn.acl.enable
0
yarn.resourcemanager.hostname
kali
yarn.nodemanager.aux-services
mapreduce_shuffle
yarn.log-aggregation-enable
true
yarn.log-aggregation.retain-seconds
604800
yarn.nodemanager.vmem-check-enabled
false
yarn.app.mapreduce.am.resource.mb
1024
yarn.scheduler.minimum-allocation-mb
1024
yarn.scheduler.maximum-allocation-mb
4096
yarn.nodemanager.resource.memory-mb
16384
# 启动hive时提示需要配置
export HADOOP_HOME=/root/tool/BD/hadoop-3.0.0
# 用root用户启动hadoop提示需要配置用户
export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root
export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export HADOOP_YARN_HOME=$HADOOP_HOME
export PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin
$HADOOP_HOME/sbin/hdfs namenode -format
$HADOOP_HOME/sbin/start-all.sh
确保yarn的ResourceManager、NodeManager,hdfs的NameNode、SecondaryNameNode、DataNode服务启动即可。
克隆cloudera/hive仓库,切换到cdh6.3.0分支(当前使用的版本),可以设置一下项目根目录下的pom.xml中的仓库地址,换成比较快的仓库,然后在项目根目录下执行mvn clean package -DskipTests -Pdist
,构建可发布的tar包。运行完后生成的文件在packagine [hive-package]
模块中,如下为相关文件列表:
drwxrwxrwx 1 root root 0 Mar 17 08:58 apache-hive-2.1.1-cdh6.3.0-bin
-rwxrwxrwx 1 root root 207735011 Mar 17 08:58 apache-hive-2.1.1-cdh6.3.0-bin.tar.gz
-rwxrwxrwx 1 root root 25238408 Mar 17 08:59 apache-hive-2.1.1-cdh6.3.0-jdbc.jar
-rwxrwxrwx 1 root root 19744989 Mar 17 08:59 apache-hive-2.1.1-cdh6.3.0-src.tar.gz
打包后,packaging/target/apache-hive-2.1.1-cdh6.3.0-bin/apache-hive-2.1.1-cdh6.3.0-bin
目录下是未压缩的相关hive文件,后续操作可以都在这个目录下执行,所以后面以该目录为当前目录。
拷贝一个配置文件,cp conf/hive-default.xml.template conf/hive-site.xml
,在conf/hive-site.xml
中修改或添加一些必要的配置:
system:java.io.tmpdir
/tmp/hive/java
system:user.name
${user.name}
javax.jdo.option.ConnectionURL
jdbc:mysql://localhost:3306/hive_debug?createDatabaseIfNotExist=true&characterEncoding=utf8
javax.jdo.option.ConnectionUserName
root
javax.jdo.option.ConnectionPassword
goodluck
javax.jdo.option.ConnectionDriverName
com.mysql.jdbc.Driver
(tips:可以提前将scripts/metastore/upgrade/mysql/hive-schema-2.1.0.mysql.sql
中的建表语句编码改成utf8,可以避免后续为了解决中文注释、表名、列名再来修改,不过有几个表改成utf8编码会报主键太长的错误,还是要保持latin1编码,可以在改成utf8后运行初始化语句,遇到报错的表时,将那个表的编码再改回latin1编码再执行初始化语句)
bin/schematool -dbType mysql -initSchema
目前已经可以开始调试hive源码,采用远程调试的方式。
hive.exec.post.hooks
tech.xxx.HiveHook
Comma-separated list of post-execution hooks to be invoked for each statement.
A post-execution hook is specified as the name of a Java class which implements the
org.apache.hadoop.hive.ql.hooks.ExecuteWithHookContext interface.
bin/hive --service metastore
;# bin/hive --debug --service hiveserver2
Listening for transport dt_socket at address: 8000
localhost
,Port填写为8000
,然后点击调试,则idea连接上hivesever2,hiveserver2会继续启动并运行。再打上断点,实践后发现调用post hook的位置在org.apache.hadoop.hive.ql.Driver
类1960行的((ExecuteWithHookContext) peh).run(hookContext);
处,可以在这里打个断点(当然可以在其他想打的位置打断点,比如先配置一个Hive已实现的Hook类,在run方法打断点);bin/beeline -u jdbc:hive2://localhost:10000 -n root
然后执行sql,断点则会触发,即可以在idea中调试hive源码,若想调试metastore或beeline,也可在启动这些功能时加上--debug
,仍然使用远程的方式进行调试。