外部 Apache Hive メタストア (レガシ)
この記事では、既存の外部 Apache Hive メタストアに接続するために Azure Databricks クラスターを設定する方法について説明します。 ここでは、推奨されるメタストア セットアップとクラスター構成の要件について説明し、その後に、外部メタストアに接続するようにクラスターを構成するための手順を示します。 Databricks Runtime に含まれる Hive ライブラリのバージョンについては、該当する Databricks Runtime バージョンのリリース ノートを参照してください。
重要
- Hive 2.0 以降では SQL Server が基になるメタストア データベースとして動作しますが、この記事全体の例では Azure SQL Database を使います。
- HDInsight との Hive メタストアの互換性については、「Azure HDInsight での外部メタデータ ストアの使用」を参照してください。
- 外部メタストアとして Azure Database for MySQL を使用している場合、サーバー側のデータベース構成で
lower_case_table_names
プロパティの値を 1 (既定値) から 2 に変更する必要があります。 詳細については、識別子での大文字と小文字の区別に関する説明を参照してください。
Note
外部メタストアの使用は、レガシのデータ ガバナンス モデルです。 Databricks では、Unity Catalog にアップグレードすることをお勧めします。 Unity Catalog では、アカウントの複数のワークスペースにまたがってデータ アクセスを管理および監査するための一元的な場所を提供することで、データのセキュリティとガバナンスが簡素化されます。 「Unity Catalog とは」を参照してください。
Hive メタストアのセットアップ
クラスター内で実行されているメタストア クライアントは、JDBC を使用して、基になるメタストア データベースに直接接続します。
クラスターからメタストアへのネットワーク接続をテストするには、ノートブック内で次のコマンドを実行できます。
%sh
nc -vz <DNS name> <port>
where
<DNS name>
は、Azure SQL Database のサーバー名です。<port>
は、データベースのポートです。
クラスター構成
クラスターを外部メタストアに接続するには、次の 2 つの構成オプション セットを設定する必要があります。
- Spark オプションでは、メタストア クライアントに対して Hive メタストア バージョンと JAR を使用して Spark を構成します。
- Hive オプションでは、外部メタストアに接続するようにメタストア クライアントを構成します。
Spark 構成オプション
Hive メタストアのバージョンの spark.sql.hive.metastore.version
と spark.sql.hive.metastore.jars
を次のように設定します。
Hive 0.13:
spark.sql.hive.metastore.jars
を設定しないでください。注意
Hive 1.2.0 と 1.2.1 は Databricks Runtime 7.0 以降の組み込みメタストアではありません。 Databricks Runtime 7.0 以降で Hive 1.2.0 または 1.2.1 を使用する場合は、「メタストア jar をダウンロードしてポイントする」で説明されている手順に従います。
Hive 2.3.7 (Databricks Runtime 7.0 - 9.x) または Hive 2.3.9 (Databricks Runtime 10.0 以降):
spark.sql.hive.metastore.jars
をbuiltin
に設定します。その他すべての Hive バージョンでは、「メタストア jar をダウンロードしてポイントする」で説明されている手順に従って、メタストア JAR をダウンロードし、ダウンロードした JAR をポイントするように構成
spark.sql.hive.metastore.jars
を設定することが、Azure Databricks で推奨されています。
メタストア jar をダウンロードしてポイントする
spark.sql.hive.metastore.jars
をmaven
に設定し、メタストアのバージョンと一致するようにspark.sql.hive.metastore.version
を設定して、クラスターを作成します。クラスターが実行中の場合は、ドライバー ログを検索して、次のような行を見つけます。
17/11/18 22:41:19 INFO IsolatedClientLoader: Downloaded metastore jars to <path>
ディレクトリ
<path>
は、クラスターのドライバー ノードでダウンロードされた JAR の場所です。別の方法として、次のコードを Scala ノートブックで実行して、JAR の場所を出力することもできます。
import com.typesafe.config.ConfigFactory val path = ConfigFactory.load().getString("java.io.tmpdir") println(s"\nHive JARs are downloaded to the path: $path \n")
ドライバー ノードの DBFS クライアントを通じて、
%sh cp -r <path> /dbfs/hive_metastore_jar
を (<path>
をクラスターの情報に置き換えて) 実行し、このディレクトリをhive_metastore_jar
という DBFS ルート内のディレクトリにコピーします。ノードのローカル ファイルシステムに
/dbfs/hive_metastore_jar
をコピーする init スクリプトを作成します。このとき、DBFS クライアントにアクセスする前に、init スクリプトが数秒でスリープ状態になるようにします。 これで、クライアントの準備が完了します。このディレクトリを使用するように
spark.sql.hive.metastore.jars
を設定します。 init スクリプトによって/dbfs/hive_metastore_jar
が/databricks/hive_metastore_jars/
にコピーされる場合は、spark.sql.hive.metastore.jars
を/databricks/hive_metastore_jars/*
に設定します。 場所には、末尾の/*
を含める必要があります。クラスターを再起動します。
Hive 構成オプション
このセクションでは、Hive に固有のオプションについて説明します。
ローカル モードを使用して外部メタストアに接続するには、次の Hive 構成オプションを設定します。
# JDBC connect string for a JDBC metastore
javax.jdo.option.ConnectionURL <mssql-connection-string>
# Username to use against metastore database
javax.jdo.option.ConnectionUserName <mssql-username>
# Password to use against metastore database
javax.jdo.option.ConnectionPassword <mssql-password>
# Driver class name for a JDBC metastore
javax.jdo.option.ConnectionDriverName com.microsoft.sqlserver.jdbc.SQLServerDriver
where
<mssql-connection-string>
は、JDBC 接続文字列です (Azure portal で取得できます)。 接続文字列にユーザー名とパスワードを含める必要はありません。これらはjavax.jdo.option.ConnectionUserName
とjavax.jdo.option.ConnectionDriverName
によって設定されるためです。<mssql-username>
また<mssql-password>
は、データベースへの読み取り/書き込みアクセス権を持つ Azure SQL Database アカウントのユーザー名とパスワードを指定します。
注意
運用環境では、hive.metastore.schema.verification
を true
に設定することをお勧めします。 これにより、メタストア クライアントのバージョンがメタストア データベースのバージョンと一致しない場合に Hive メタストア クライアントがメタストア データベース スキーマを暗黙的に変更するのを防ぐことができます。 Hive 1.2.0 よりも前のバージョンのメタストア クライアントでこの設定を有効にする場合は、メタストア クライアントがメタストア データベースに対する書き込みアクセス許可を持っていることを確認します (HIVE-9749 で説明されている問題を回避するため)。
- Hive メタストア 1.2.0 以降では、
hive.metastore.schema.verification.record.version
をtrue
に設定してhive.metastore.schema.verification
を有効にします。 - Hive メタストア 2.1.1 以降では、
hive.metastore.schema.verification.record.version
をtrue
に設定します。これは、既定でfalse
に設定されているためです。
UI を使用して外部メタストアを設定する
Azure Databricks UI を使用して外部メタストアを設定するには、次のようにします。
サイドバーの [クラスター] ボタンをクリックします。
[クラスターの作成] をクリックします。
次の Spark 構成オプションを入力します。
# Hive-specific configuration options. # spark.hadoop prefix is added to make sure these Hive specific options propagate to the metastore client. # JDBC connect string for a JDBC metastore spark.hadoop.javax.jdo.option.ConnectionURL <mssql-connection-string> # Username to use against metastore database spark.hadoop.javax.jdo.option.ConnectionUserName <mssql-username> # Password to use against metastore database spark.hadoop.javax.jdo.option.ConnectionPassword <mssql-password> # Driver class name for a JDBC metastore spark.hadoop.javax.jdo.option.ConnectionDriverName com.microsoft.sqlserver.jdbc.SQLServerDriver # Spark specific configuration options spark.sql.hive.metastore.version <hive-version> # Skip this one if <hive-version> is 0.13.x. spark.sql.hive.metastore.jars <hive-jar-source>
「クラスター構成リファレンス」の手順に従って、クラスター構成を続けます。
[クラスターの作成] をクリックしてクラスターを作成します。
init スクリプトを使用して外部メタストアを設定する
init スクリプトを使用すると、必要な構成を手動で設定することなく、既存の Hive メタストアに接続できます。
- 存在しない場合は、init スクリプトを保存するベース ディレクトリを作成します。
dbfs:/databricks/scripts
の使用例を次に示します。 - ノートブックで次のスニペットを実行します。 このスニペットは、init スクリプト
/databricks/scripts/external-metastore.sh
を Databricks File System (DBFS) に作成します。 または、DBFS REST API の put 操作を使用して、init スクリプトを作成することもできます。 この init スクリプトでは、クラスターの各ノード内の/databricks/driver/conf/
にある JSON に似た形式の00-custom-spark.conf
という名前の構成ファイルに、必要な構成オプションが書き込まれます。これは、<cluster-name>
として名前が指定されたクラスターが起動するたびに行われます。 Azure Databricks では、/databricks/driver/conf/spark-branch.conf
ファイルに既定の Spark 構成が提供されます。/databricks/driver/conf
ディレクトリ内の構成ファイルは、アルファベット順とは逆に適用されます。00-custom-spark.conf
ファイルの名前を変更する場合は、spark-branch.conf
ファイルの前に引き続き適用されるようにします。
Scala
dbutils.fs.put(
"/databricks/scripts/external-metastore.sh",
"""#!/bin/sh
|# Loads environment variables to determine the correct JDBC driver to use.
|source /etc/environment
|# Quoting the label (i.e. EOF) with single quotes to disable variable interpolation.
|cat << 'EOF' > /databricks/driver/conf/00-custom-spark.conf
|[driver] {
| # Hive specific configuration options.
| # spark.hadoop prefix is added to make sure these Hive specific options will propagate to the metastore client.
| # JDBC connect string for a JDBC metastore
| "spark.hadoop.javax.jdo.option.ConnectionURL" = "<mssql-connection-string>"
|
| # Username to use against metastore database
| "spark.hadoop.javax.jdo.option.ConnectionUserName" = "<mssql-username>"
|
| # Password to use against metastore database
| "spark.hadoop.javax.jdo.option.ConnectionPassword" = "<mssql-password>"
|
| # Driver class name for a JDBC metastore
| "spark.hadoop.javax.jdo.option.ConnectionDriverName" = "com.microsoft.sqlserver.jdbc.SQLServerDriver"
|
| # Spark specific configuration options
| "spark.sql.hive.metastore.version" = "<hive-version>"
| # Skip this one if <hive-version> is 0.13.x.
| "spark.sql.hive.metastore.jars" = "<hive-jar-source>"
|}
|EOF
|""".stripMargin,
overwrite = true
)
Python
contents = """#!/bin/sh
# Loads environment variables to determine the correct JDBC driver to use.
source /etc/environment
# Quoting the label (i.e. EOF) with single quotes to disable variable interpolation.
cat << 'EOF' > /databricks/driver/conf/00-custom-spark.conf
[driver] {
# Hive specific configuration options.
# spark.hadoop prefix is added to make sure these Hive specific options will propagate to the metastore client.
# JDBC connect string for a JDBC metastore
"spark.hadoop.javax.jdo.option.ConnectionURL" = "<mssql-connection-string>"
# Username to use against metastore database
"spark.hadoop.javax.jdo.option.ConnectionUserName" = "<mssql-username>"
# Password to use against metastore database
"spark.hadoop.javax.jdo.option.ConnectionPassword" = "<mssql-password>"
# Driver class name for a JDBC metastore
"spark.hadoop.javax.jdo.option.ConnectionDriverName" = "com.microsoft.sqlserver.jdbc.SQLServerDriver"
# Spark specific configuration options
"spark.sql.hive.metastore.version" = "<hive-version>"
# Skip this one if <hive-version> is 0.13.x.
"spark.sql.hive.metastore.jars" = "<hive-jar-source>"
}
EOF
"""
dbutils.fs.put(
file = "/databricks/scripts/external-metastore.sh",
contents = contents,
overwrite = True
)
- init スクリプトを使用してクラスターを構成します。
- クラスターを再起動します。
トラブルシューティング
クラスターが起動しない (init スクリプトの設定が正しくないため)
外部メタストアを設定するための init スクリプトによってクラスターの作成エラーが発生する場合は、ログを記録するように init スクリプトを構成し、ログを使用して init スクリプトをデバッグします。
SQL ステートメントのエラー: InvocationTargetException
完全な例外スタック トレースのエラー メッセージ パターン:
Caused by: javax.jdo.JDOFatalDataStoreException: Unable to open a test connection to the given database. JDBC url = [...]
外部メタストアの JDBC 接続情報が正しく構成されていません。 構成されているホスト名、ポート、ユーザー名、パスワード、JDBC ドライバー クラス名を確認します。 また、ユーザー名に、メタストア データベースにアクセスする適切な特権が付与されている必要があります。
完全な例外スタック トレースのエラー メッセージ パターン:
Required table missing : "`DBS`" in Catalog "" Schema "". DataNucleus requires this table to perform its persistence operations. [...]
外部メタストア データベースが正しく初期化されていません。 メタストア データベースを作成し、JDBC 接続文字列に正しいデータベース名を入力していることを確認します。 次の 2 つの Spark 構成オプションを使用して新しいクラスターを起動します。
datanucleus.schema.autoCreateTables true datanucleus.fixedDatastore false
このようにすることで、Hive クライアント ライブラリでは、メタストア データベースのテーブルにアクセスしようとしてそれらが見つからない場合に、自動的に作成と初期化を試みます。
SQL ステートメントのエラー: AnalysisException: org.apache.hadoop.hive.metastore.HiveMetastoreClient をインスタンス化できない
完全な例外スタックトレースのエラー メッセージ:
The specified datastore driver (driver name) was not found in the CLASSPATH
クラスターが、誤った JDBC ドライバーを使用するように構成されています。
dataschus.autoCreateSchema を true に設定しても、期待した通り動作しない
既定では、Databricks では datanucleus.fixedDatastore
も true
に設定されます。これにより、メタストア データベースに対して、誤って構造に変更が加えられることが防止されます。 そのため、datanucleus.autoCreateSchema
を true
に設定した場合でも、Hive クライアント ライブラリはメタストア テーブルを作成できません。 この戦略は、一般に、メタストア データベースが誤ってアップグレードされるのを防ぐため、実稼働環境で安全です。
メタストア データベースの初期化に datanucleus.autoCreateSchema
を使用しない場合は、必ず、datanucleus.fixedDatastore
を false
に設定します。 また、メタストア データベースを初期化した後に両方のフラグを反転して、実稼働環境の保護を強化することができます。