HiveServer3.1.3をローカルデバッグする
今回、Hive3.1.3をDocker上で立ち上げ、HiveServerにリモートデバッガをアタッチしてHiveServerの処理を詳細にデバッグする環境をセットアップします。開発環境はIntelliJを前提としてます。
公式にHive用のDockerImageを提供するIssueがHive4.0.0で導入されており、この周辺のコードを流用します。
- [HIVE-26400] Provide docker images for Hive - ASF JIRA
- hive/packaging/src/docker at dd3fd775406c2d621c42ef1adce2fa0f3b9acd39 · apache/hive · GitHub
まず、試しに現時点でのmasterをcloneしてきて、README.mdに従ってビルドします。
cd packaging/src/docker ./build.sh -hive 3.1.3
Docker上で動作するHiveServerにデバッガをアタッチするため、HADOOP_OPTSにデバッグエージェンを起動するための環境変数を設定します。HiveServerはJava8で動作するため、address=*:8888
のような表記ではなくaddress=8888
と記述しないとエラーが起きることに注意してください。
docker run -d -p 10000:10000 -p 10002:10002 -p 8888:8888 --env SERVICE_NAME=hiveserver2 --env HADOOP_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8888" --name hiveserver2-standalone apache/hive:${HIVE_VERSION}
ここで、起動直後に Schema initialization failed!
のエラーが発生してしまうため、修正する必要があります。
hive3.1.3時点でのschematoolの引数と、最新のmasterのschematoolの引数が異なるため、Metastoreの初期化に失敗してしまいます。
上記の行を、以下の行に変更し、Docker Imageを再度ビルドする必要があります。
$HIVE_HOME/bin/schematool -dbType $DB_DRIVER -initSchema
ビルドが完了したら、以下のコマンドを再度実行し、HiveServerを起動します。
docker run -d -p 10000:10000 -p 10002:10002 -p 8888:8888 --env SERVICE_NAME=hiveserver2 --env HADOOP_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8888" --name hiveserver2-standalone apache/hive:${HIVE_VERSION}
コンテナログを確認すると、Metastoreのschemaの初期化に成功し、デバッグエージェントが8888でListenし、正常にHiveServerが起動したことを確認できます。
+ : derby + SKIP_SCHEMA_INIT=false + export HIVE_CONF_DIR=/opt/hive/conf + HIVE_CONF_DIR=/opt/hive/conf + '[' -d '' ']' + export 'HADOOP_CLIENT_OPTS= -Xmx1G ' + HADOOP_CLIENT_OPTS=' -Xmx1G ' + [[ false == \f\a\l\s\e ]] + initialize_hive + /opt/hive/bin/schematool -dbType derby -initSchema SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/opt/hive/lib/log4j-slf4j-impl-2.17.1.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/opt/hadoop/share/hadoop/common/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory] Listening for transport dt_socket at address: 8888 Metastore connection URL: jdbc:derby:;databaseName=metastore_db;create=true Metastore Connection Driver : org.apache.derby.jdbc.EmbeddedDriver Metastore connection User: APP Starting metastore schema initialization to 3.1.0 Initialization script hive-schema-3.1.0.derby.sql ... Initialization script completed schemaTool completed [WARN] Failed to create directory: /home/hive/.beeline No such file or directory + '[' 0 -eq 0 ']' + echo 'Initialized schema successfully..' Initialized schema successfully.. + '[' hiveserver2 == hiveserver2 ']' + export 'HADOOP_CLASSPATH=/opt/tez/*:/opt/tez/lib/*:' + HADOOP_CLASSPATH='/opt/tez/*:/opt/tez/lib/*:' + exec /opt/hive/bin/hive --skiphadoopversion --skiphbasecp --service hiveserver2 2023-05-14 06:01:05: Starting HiveServer2 Listening for transport dt_socket at address: 8888 SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/opt/tez/lib/slf4j-log4j12-1.7.10.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/opt/hive/lib/log4j-slf4j-impl-2.17.1.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/opt/hadoop/share/hadoop/common/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory] Hive Session ID = cbff1bee-ddb2-476b-8912-6b8c02f49266 Hive Session ID = d4327ad9-227c-4fe7-a9ec-cceb6bb26c62 OK
デバッガをアタッチするにあたり、ローカルのコードを動作中のコードと一致させる必要があるので、rel/release-3.1.3
をチェックアウトしておきます。
git fetch origin rel/release-3.1.3 git checkout rel/release-3.1.3
準備ができたので、以下のような設定でIntelliJでデバッガを起動します。
問題なくデバッガがアタッチできることを確認してください。
beelineで接続しても良いですが、IntelliJのDatabase ToolはHiveも対応しているのでIntelliJから接続します。
適当にREADME.mdのサンプルクエリを使ってテーブルを初期化し、クエリが動作することを確認します。
show tables; create table hive_example(a string, b int) partitioned by(c int); alter table hive_example add partition(c=1); insert into hive_example partition(c=1) values('a', 1), ('a', 2),('b',3); select count(distinct a) from hive_example;
あとは、実際にブレークポイントを設定し、クエリを実行してみるだけです。
試しに、org.apache.hadoop.hive.ql.Driver
のcompile
メソッドにブレークポイントを設定して、 select count(distinct a) from hive_example;
を実行してみると、そのポイントからデバッグが可能であることがわかります。