読者です 読者をやめる 読者になる 読者になる

clojure から hive へ接続する

jdbc を利用して hiveserver2 へ接続してみたメモ。
hive のバージョンと hive-jdbc のバージョンが問題に。。。

まず

ライブラリ類のバージョンをとりあえず新しい物を探してきて

[org.clojure/java.jdbc "0.4.2"]
[org.apache.hive/hive-jdbc "0.13.0"]
[org.apache.hadoop/hadoop-core "1.0.3"]

と指定して

(def hive-db {:subprotocol "hive2"
              :classname "org.apache.hive.jdbc.HiveDriver"
              :subname "//xxxxxxx:10000/xxx"
              :user "aaa"
              :password "bbb"})

と設定して接続すると、

java.sql.SQLException: Could not establish connection to jdbc:hive2://xxxxxxx:10000/xxx: Required field 'client_protocol' is unset!
Struct:TOpenSessionReq(client_protocol:null)

となって失敗。
hive のバージョンと hive-jdbc のバージョンが違うと起こるらしい。

[HIVE-6050] Newer versions of JDBC driver does not work with older HiveServer2 - ASF JIRA
https://issues.apache.org/jira/browse/HIVE-6050

hiveserver2 のバージョンを調べるため

ps -ef | grep HiveServer2

とプロセスから調べてみると、
使っている hive のバージョンは 0.10 なので
hive-jdbc 0.13.0 では動かず?

hive-jdbc 0.10.0 (失敗)

hive-jdbc のバージョンを hive と揃えてみた。

[org.clojure/java.jdbc "0.4.2"]
[org.apache.hive/hive-jdbc "0.10.0"]
[org.apache.hadoop/hadoop-core "1.0.3"]

これで実行すると今度は

Could not find artifact javax.jdo:jdo2-api:jar:2.3-ec in central (https://repo1.maven.org/maven2/)
Could not find artifact javax.jdo:jdo2-api:jar:2.3-ec in clojars (https://clojars.org/repo/)
Could not find artifact sqlline:sqlline:jar:1_0_2 in central (https://repo1.maven.org/maven2/)
Could not find artifact sqlline:sqlline:jar:1_0_2 in clojars (https://clojars.org/repo/)

と依存性が解決できず。。

解決できなかった jar は spring のリポジトリにあったので
ひとまず

:repositories {"spring" "http://repo.spring.io/libs-milestone/"}

を追加して再実行。

Exception in thread "main" java.sql.SQLException: No suitable driver found for jdbc:hive2://xxxxxxx:10000/xxx,
compiling:(C:\msys64\tmp\form-init2223412939380166071.clj:1:85)

0.10 には

:subprotocol "hive"
:classname "org.apache.hadoop.hive.jdbc.HiveDriver"

と指定するものらしい。

hive-jdbc 0.11.0

接続を

:subprotocol "hive2"
:classname "org.apache.hive.jdbc.HiveDriver"

に戻して
利用する hive-jdbc を 0.11.0 とするために

[org.apache.hive/hive-jdbc "0.11.0"]

を指定。

すると

(ns testtesttest.main
  (:require [clojure.java.jdbc :as j]))

  (def hive-db {:subprotocol "hive2"
                :classname "org.apache.hive.jdbc.HiveDriver"
                :subname "//xxxxxxx:10000/xxx"
                :user "aaa"
                :password "bbb"})

(defn tables []
  (j/query hive-db
    [(str "show tables")]
   :row-fn println))

   (defn -main [& args]
     (tables))

を実行すると

WARNING!!! version ranges found for:
[org.apache.hive/hive-jdbc "0.11.0"] -> [org.apache.hive/hive-cli "0.11.0"] -> [org.apache.hive/hive-service "0.11.0"] -> [org.apache.hive/hive-exec "0.11.0"] -> [org.apache.hive/hive-metastore "0.11.0"] -> [org.datanucleus/datanucleus-enhancer "2.0.3"] -> [asm "[3.0,4.0)"]
Consider using [org.apache.hive/hive-jdbc "0.11.0" :exclusions [asm]].

依存性の警告が出ますが

{:tab_name zzz}
{:tab_name yyy}
.
.
.

と結果が取得できました。

念のため 0.12.0

0.13.0 同様に
client_protocol が指定されていないエラーで失敗しました。

まとめ

hive 0.10 で hiveserver2 を起動しているときは
hive-jdbc 0.11.0 で接続。

(いろいろ試した結果からの答えなので
セオリーや王道があれば教えていただけると助かります。。)

さて次は取得したデータをエクセルへ出力……