Azure HDInsight 3.6 Hive ワークロードを Hive HDInsight 4.0 に移行する
HDInsight 4.0 には、HDInsight 3.6 よりも優れた点がいくつかあります。 こちらに HDInsight 4.0 の新機能の概要があります。
この記事では、Hive ワークロードを HDInsight 3.6 から 4.0 に移行する手順について説明します。以下が含まれます。
- Hive メタストアのコピーとスキーマのアップグレード
- ACID 互換性のための安全な移行
- Hive セキュリティ ポリシーの保持
新旧の HDInsight クラスターは、同じストレージ アカウントにアクセスできる必要があります。
Hive テーブルの新しいストレージ アカウントへの移行は、別の手順として実行する必要があります。 ストレージ アカウント間での Hive の移行に関する記事を参照してください。
Hive 3 の変更点と新機能:
Hive クライアントの変更
Hive 3 では、コマンド ラインからクエリと Hive 管理コマンドを実行するためのシン クライアント Beeline のみがサポートされます。 Beeline は HiveServer への JDBC 接続を使用して、すべてのコマンドを実行します。 解析、コンパイル、および実行操作は HiveServer で行われます。
Hive ユーザーとして Hive キーワード (keyword) を使用して Beeline を呼び出すか、beeline -u <JDBC URL>
を使用して beeline を呼び出して、サポートされている Hive CLI コマンドを入力します。 JDBC URL は、Ambari Hive ページから取得できます。
(サポートされなくなったシック クライアント Hive CLI の代わりに) Beeline を使用すると、次のような利点が得られます。
- Hive コード ベース全体を維持する代わりに、JDBC クライアントを維持するだけですみます。
- Hive コード ベース全体が含まれていないため、Beeline を使用すると、スタートアップのオーバーヘッドが減少します。
"/usr/bin" ディレクトリにある Hive スクリプトを実行し、JDBC URL を使用して beeline 接続を呼び出すこともできます。
シン クライアント アーキテクチャを使用すると、次のようにセキュリティ保護が容易になります。
- セッション状態、内部データ構造、パスワードなどがサーバーではなくクライアント上に存在します。
- クエリの実行に必要なデーモンの数が少なくなり、監視とデバッグが簡単になります。
HiveServer では、許可リストとブロックリストの設定が適用され、SET
コマンドを使用して変更できます。 ブロックリストを使用すると、Hive サーバーが不安定にならないようにメモリ構成を制限できます。 異なる許可リストとブロックリストを使用する複数の HiveServer インスタンスを構成して、さまざまなレベルの安定性を確立できます。
Hive メタストアの変更
Hive では、埋め込みメタストア (HS2 JVM 内) ではなくリモート メタストアのみがサポートされるようになりました。 Hive メタストアは、HDInsight スタックの一部として Ambari によって管理されるクラスター内のノードに存在します。 クラスター外のスタンドアロン サーバーはサポートされていません。 Hive メタストアを構成するために、コマンド ラインで key=value コマンドを設定する必要がなくなりました。 "hive.metastore.uris=' ' で構成された値に基づいて、HMS サービスが使用され、接続が確立されます。
実行エンジンの変更
Apache Tez は、既定の Hive 実行エンジンとして MapReduce を置き換えます。 MapReduce は、Hive 2.0 Refer HIVE-12300 以降では非推奨です。 有向非巡回グラフ (DAG) とデータ転送プリミティブの式を使用すると、Tez での Hive クエリの実行のパフォーマンスが向上します。 Hive に送信する SQL クエリは、次のように実行されます。
- Hive がクエリをコンパイルします。
- Tez がクエリを実行します。
- YARN はクラスター全体でアプリケーションのリソースを割り当て、YARN キュー内の Hive ジョブの承認を有効にします。
- Hive は、ABFS または WASB のデータを更新します。
- Hive は、JDBC 接続経由でクエリの結果を返します。
レガシ スクリプトまたはアプリケーションで実行のために MapReduce が指定されている場合、次のように例外が発生します。
注意
ほとんどのユーザー定義関数 (UDF) では、MapReduce ではなく Tez で実行するように変更する必要はありません。
ACID トランザクションと CBO の変更:
ACID テーブルは HDInsight 4.x の既定のテーブルの種類であり、パフォーマンスや操作上のオーバーロードはありません。
アプリケーション開発の簡素化、トランザクションの保証が強化された操作、SQL コマンドのセマンティクスの簡素化
Hive 内部で、HDInsight 4.1 の ACID テーブルのバケット処理が行われることで、メンテナンスのオーバーヘッドが解消されます。
高度な最適化 – CBO でのアップグレード
自動クエリ キャッシュ。 クエリ キャッシュを有効にするために使用される プロパティは
hive.query.results.cache.enabled
です。 このプロパティを true に設定する必要があります。 Hive はクエリ結果キャッシュを既定で/tmp/hive/__resultcache__/.
に格納します。Hive はクエリ結果キャッシュに 2 GB を割り当てます。 この設定を変更するには、次のパラメーターをバイト単位で構成します:hive.query.results.cache.max.size
詳細については、「Azure HDInsight 4.0 に移行する利点」を参照してください。
具体化されたビューの書き換え
詳細については、「Hive - 具体化されたビュー」を参照してください
Apache Hive 3 へのアップグレード後の変更
アップグレード後に Apache Hive 3 テーブルを見つけて使用するには、アップグレード プロセス中に発生する変更を理解する必要があります。 テーブルの管理と場所、テーブル ディレクトリに対するアクセス許可、テーブルの種類の変更、および ACID 準拠に関する考慮事項。
Hive のテーブルの管理
Hive 3 は Hive 2 よりも厳密にテーブルを制御し、マネージド テーブルは厳密な定義に従う必要があります。 Hive がテーブルを引き継ぐ制御レベルは、従来のデータベースと同じになります。 Hive は、データに対する差分変更を自己認識しています。このコントロール フレームワークにより、パフォーマンスが向上します。
たとえば、クエリの解決のためにデーブルで新しいデータをスキャンする必要がないことを Hive が認識している場合、Hive は Hive クエリ結果キャッシュから結果を返します。 具体化されたビューの基になるデータが変更された場合、Hive は具体化されたビューを再構築する必要があります。 ACID プロパティを使用すると、どの行が、変更され、処理して具体化されたビューに追加する必要があるかを正確に表示できます。
ACID プロパティに対する Hive の変更
Hive 2.x と 3.x には、トランザクション (マネージド) テーブルと非トランザクション (外部) テーブルの両方があります。 トランザクション テーブルには、アトミックで一貫性のある分離と持続 (ACID) のプロパティがあります。 Hive 2.x では、ACID トランザクション処理の初期バージョンは ACID v1 です。 Hive 3.x では、既定のテーブルは ACID v2 になります。
ネイティブ ストレージ形式と非ネイティブ ストレージ形式
ストレージ形式は、テーブルの種類に対するアップグレードの変更の要因です。 Hive 2.x と 3.x では、次の Hadoop ネイティブ ストレージ形式と非ネイティブ ストレージ形式がサポートされています
ネイティブ: 次のファイル形式の Hive での組み込みサポートを含むテーブル
- Text
- シーケンス ファイル
- RC ファイル
- AVRO ファイル
- ORC ファイル
- Parquet ファイル
非ネイティブ: ストレージ ハンドラーを使用するテーブル (DruidStorageHandler や HBaseStorageHandler など)
テーブルの種類に対する HDInsight 4.x のアップグレードの変更
次の表は、HDInsight 3.x からのアップグレード前と HDInsight 4.x へのアップグレード後の Hive テーブルの種類と ACID 操作を比較したものです。 Hive テーブル ファイルの所有権は、アップグレード後にテーブルの種類と ACID 操作を決定する要因です。
HDInsight 3.x と HDInsight 4.x のテーブルの種類の比較
HDInsight 3.x | - | - | - | HDInsight 4.x | - |
---|---|---|---|---|---|
テーブルの種類 | ACID v1 | Format | Hive テーブル ファイルの所有者 (ユーザー) | テーブルの種類 | ACID v2 |
外部 | いいえ | ネイティブまたは非ネイティブ | Hive または Hive 以外 | 外部 | いいえ |
マネージド | はい | ORC | Hive または Hive 以外 | マネージド、更新可能 | はい |
マネージド | いいえ | ORC | Hive | マネージド、更新可能 | はい |
マネージド | いいえ | ORC | Hive 以外 | 外部 (データ削除あり) | NO |
マネージド | いいえ | ネイティブ (ただし、ORC 以外) | Hive | マネージド、挿入のみ | はい |
マネージド | いいえ | ネイティブ (ただし、ORC 以外) | Hive 以外 | 外部 (データ削除あり) | いいえ |
マネージド | いいえ | 非ネイティブ | Hive または Hive 以外 | 外部 (データ削除あり) | いいえ |
Hive の偽装
Hive 2 では Hive の偽装が既定で有効になっており (doAs=true)、Hive 3 では既定で無効になっています。 Hive の偽装では、エンド ユーザーとして実行するかどうかに関係なく Hive が実行されます。
その他の HDInsight 4.x のアップグレードの変更
- Hive ユーザーが所有していないマネージド ACID テーブルは、アップグレード後もマネージド テーブルのままですが、Hive が所有者になります。
- アップグレード後、Hive テーブルの形式はアップグレード前と同じです。 たとえば、ネイティブ テーブルまたは非ネイティブ テーブルは、それぞれネイティブまたは非ネイティブのままです。
場所の変更
次のいずれかの条件が該当する場合、アップグレード後にマネージド テーブルまたはパーティションの場所は変更されません。
- アップグレード前に、古いテーブルまたはパーティション ディレクトリが既定の場所 /apps/hive/warehouse になかった。
- 古いテーブルまたはパーティションが、新しいウェアハウス ディレクトリとは異なるファイル システムにある。
- 古いテーブルまたはパーティションのディレクトリが、新しいウェアハウス ディレクトリとは異なる暗号化ゾーンにある。
それ以外の場合、マネージド テーブルまたはパーティションの場所は変更されます。 アップグレード プロセスは、マネージド ファイルを /hive/warehouse/managed
に移動します。 既定では、Hive は、HDInsight 4.x で作成した新しい外部テーブルを /hive/warehouse/external
に配置します。
Hive 2.x ウェアハウスの以前の場所である /apps/hive directory
は、HDInsight 4.x に存在する場合と存在しない場合があります。
場所の変更に関しては、次のシナリオが存在します
シナリオ 1
テーブルが HDInsight-3.x のマネージド テーブルで、場所 /apps/hive/warehouse
に存在し、HDInsight-4.x で外部テーブルとして変換されている場合、その場所 /apps/hive/warehouse
は HDInsight 4.x でも同じです。 場所は変更されません。 この手順の後、alter table コマンドを実行して、マネージド (acid) テーブルとして変換し、その時点で同じ場所 /apps/hive/warehouse
に存在している場合。
シナリオ 2
テーブルが HDInsight-3.x のマネージド テーブルで、場所 /apps/hive/warehouse
に存在し、HDInsight 4.x でマネージド (ACID) テーブルに変換された場合、場所は /hive/warehouse/managed
になります。
シナリオ 3 HDInsight-4.x で場所を指定せずに外部テーブルを作成した場合は、場所 /hive/warehouse/external
に存在します。
テーブル変換
アップグレード後、非トランザクション テーブルを ACID v2 トランザクション テーブルに変換するには、ALTER TABLE
コマンドを使用し、テーブルのプロパティを以下に設定します。
transaction'='true' and 'EXTERNAL'='false
- HDInsight-3.x の Hive 以外のユーザーが所有しているマネージド テーブル、非 ACID、ORC 形式は、HDInsight-4.x では外部の非 ACID テーブルに変換されます。
- ユーザーが外部テーブル (非 ACID) を ACID に変更する場合は、外部テーブルをマネージドおよび ACID にも変更する必要があります。 HDInsight-4.x では、既定ではすべてのマネージド テーブルが厳密に ACID であるためです。 外部テーブル (非 ACID) を ACID テーブルに変換することはできません。
注意
テーブルは ORC テーブルである必要があります。
外部テーブル (非 ACID) をマネージド (ACID) テーブルに変換するには、次の手順を実行します。
- 次のコマンドを使用して、外部テーブルをマネージド テーブルに変換し、acid を true に設定します。
alter table <table name> set TBLPROPERTIES ('EXTERNAL'='false', 'transactional'='true');
- 外部テーブルに対して次のコマンドを実行しようとすると、次のエラーが発生します。
シナリオ 1
テーブル rt
は外部テーブル (非 ACID) であるとします。 テーブルが ORC 以外のテーブルの場合は、次のエラーになります。
alter table rt set TBLPROPERTIES ('transactional'='true');
ERROR : FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Unable to alter table. The table must be stored using an ACID compliant format (such as ORC): work.rt
The table must be ORC format
シナリオ 2
>>>> alter table rt set TBLPROPERTIES ('transactional'='true'); If the table is ORC table.
ERROR:
Error: Error while processing statement: FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Unable to alter table. work.rt can't be declared transactional because it's an external table (state=08S01,code=1)
このエラーは、テーブル rt
が外部テーブルであり、外部テーブルを ACID に変換できないために発生しています。
シナリオ 3
>>>> alter table rt set TBLPROPERTIES ('EXTERNAL'='false');
ERROR:
Error: Error while processing statement: FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Unable to alter table. Table work.rt failed strict managed table checks due to the following reason: Table is marked as a managed table but isn't transactional. (state=08S01,code=1)
ここでは、最初に外部テーブルをマネージド テーブルに変更しようとしています。 HDInsight 4.x では、厳格なマネージド テーブルにする必要があります (つまり、ACID である必要があります)。 そのため、ここでデッドロックが発生します。 外部テーブル (NON_ACID) をマネージド (ACID) に変換する唯一の方法は、次のコマンドに従うことです。
alter table rt set TBLPROPERTIES ('EXTERNAL'='false', 'transactional'='true');
構文とセマンティクス
テーブルの作成。使いやすさと機能を向上させるために、Hive 3 でテーブルの作成が変更されました。 Hive では次のようにテーブルの作成を変更しました
- HDP の既定値である ACID 準拠テーブルの作成
- 単純な書き込みと挿入のサポート
- 複数のパーティションへの書き込み
- 1 つの SELECT ステートメントで複数のデータ更新を挿入
- バケットの必要性を解消
Hive でテーブルを作成する ETL パイプラインがある場合、テーブルは ACID として作成されます。 Hive がアクセスを厳密に制御し、テーブルに対して定期的に圧縮を実行するようになりました
アップグレード前 HDInsight 3.x では、既定で CREATE TABLE によって非 ACID テーブルが作成されました。
アップグレード後 既定では、CREATE TABLE によって、ORC 形式の完全な ACID トランザクション テーブルが作成されます。
アクションが必要 Spark から Hive ACID テーブルにアクセスするには、Hive Warehouse Connector (HWC) を使用して Hive に接続します。 Spark から Hive に ACID テーブルを書き込むには、HWC と HWC API を使用します。
db.table
参照のエスケープdb.table 参照を使用するクエリを変更して、Hive が db.table 文字列全体をテーブル名として解釈しないようにする必要があります。 Hive 3.x は SQL クエリで
db.table
を拒否します。 テーブル名にドット (.) を使用することはできません。 データベース名とテーブル名をバッククォートで囲みます。 問題のあるテーブル参照を含むテーブルを見つけます。 CREATE TABLE ステートメントに表示されるmath.students
。 データベース名とテーブル名をバッククォートで囲みます。TABLE `math`.`students` (name VARCHAR(64), age INT, gpa DECIMAL(3,2));
CAST TIMESTAMPS。数値をタイムスタンプにキャストするアプリケーションの結果は、Hive 2 と Hive 3 で異なります。 Apache Hive は、タイム ゾーンを TIMESTAMP 型に関連付けない SQL Standard に準拠するように CAST の動作を変更しました。
アップグレード前 数値型の値をタイムスタンプにキャストすることで、クラスターのタイム ゾーンを反映した結果を生成することができました。 たとえば、1597217764557 は 2020-08-12 00:36:04 PDT です。 次のクエリを実行すると、数値が PDT のタイムスタンプにキャストされます。
SELECT CAST(1597217764557 AS TIMESTAMP);
| 2020-08-12 00:36:04 |アップグレード後 数値型の値をタイムスタンプにキャストすると、クラスターのタイム ゾーンではなく UTC を反映した結果が生成されます。 クエリを実行すると、数値が UTC のタイムスタンプにキャストされます。
SELECT CAST(1597217764557 AS TIMESTAMP);
| 2020-08-12 07:36:04.557 |アクションが必要 アプリケーションを変更します。 ローカル タイム ゾーンを取得するために数字からキャストしないでください。 組み込みの関数 from_utc_timestamp と to_utc_timestamp を使用して、アップグレード前の動作を模倣できます。
列変更の互換性の確認。既定の構成変更により、列の型を変更するアプリケーションが失敗する可能性があります。
アップグレード前 HDInsight 3.x では、Hive.metastore.disallow.incompatible.col.type.changes は、既定では false であり、互換性のない列の型への変更を許可します。 たとえば、STRING 列を、MAP<STRING、STRING> などの互換性のない型の列に変更できます。 エラーは発生しません。
アップグレード後 hive.metastore.disallow.incompatible.col.type.changes は既定で true です。 Hive は、互換性のない列の型への変更を防止します。 INT、STRING、BIGINT などの互換性のある列の型の変更はブロックされません。
アクションが必要 互換性のない列の型の変更を禁止するようにアプリケーションを変更して、データ破損の可能性を防ぎます。
パーティションの削除
パーティションを削除するための CASCADE 句の OFFLINE キーワードと NO_DROP のキーワードは、パフォーマンスの問題を引き起こすため、サポートされなくなりました。
アップグレード前 CASCADE 句で OFFLINE キーワードと NO_DROP キーワードを使用して、パーティションの読み取りまたは削除を防ぐことができました。
アップグレード後 OFFLINE と NO_DROP は CASCADE 句ではサポートされません。
アクションが必要 CASCADE 句から OFFLINE と NO_DROP を削除するようにアプリケーションを変更します。 Ranger などの承認スキームを使用して、パーティションの削除または読み取りを防ぎます。
テーブルの名前の変更。アップグレード後は、テーブルが
LOCATION
句なしで作成され、そのデータベース ディレクトリの下にある場合にのみ、マネージド テーブルの名前を変更すると、その場所が移動されます。
CBO に関する制限事項
選択出力では、いくつかの列で末尾にゼロが付くことがわかります。 たとえば、データ型が decimal(38,4) のテーブル列があり、データを 38 として挿入すると、末尾のゼロが追加され、結果が 38.0000 として提供されます。https://issues.apache.org/jira/browse/HIVE-12063 および https://issues.apache.org/jira/browse/HIVE-24389 の説明のように、10 進数列でラッパーを実行する代わりに、スケールと精度を維持するという考え方です。 これは、Hive 2 からの既定の動作です。 この問題を解決するには、次のオプションに従います。
- ソース レベルでデータ型を変更して、精度を col1(decimal(38,0)) として調整します。 この値は、末尾のゼロがない場合は 38 として結果を提供します。 ただし、データを 35.0005 として挿入すると、それは .0005 になり、値は 38 1 としてのみ提供されます。問題がある列の末尾のゼロを削除し、文字列にキャストします。
- select TRIM(cast(<column_name> AS STRING))+0 FROM <table_name>; を使用します。
- 正規表現を使用します。
- ソース レベルでデータ型を変更して、精度を col1(decimal(38,0)) として調整します。 この値は、末尾のゼロがない場合は 38 として結果を提供します。 ただし、データを 35.0005 として挿入すると、それは .0005 になり、値は 38 1 としてのみ提供されます。問題がある列の末尾のゼロを削除し、文字列にキャストします。
クエリで UNIX_TIMESTAMP を使用すると、Hive クエリが "Unsupported SubQuery Expression (サポートされていないサブクエリ式)" で失敗します。 たとえば、クエリを実行すると、"Unsupported SubQuery Expression (サポートされていないサブクエリ式)" というエラーがスローされます。
select * from (SELECT col_1 from table1 where col_2 >= unix_timestamp('2020-03-07','yyyy-MM-dd'));
この問題の根本原因は、現在の HIVE コードベースが UNIX_TIMESTAMP を解析する例外をスローすることです。これは、Calcite が
BIGINT
として認識するUNIX_TIMESTAMP
の精度に対する精度マッピングがHiveTypeSystemImpl.java code
にないためです。 ただし、次のクエリは正常に動作します。select * from (SELECT col_1 from table1 where col_2 >= 1);
col_2 は整数であるため、このコマンドは正常に実行されます。 上記の問題は、hdi-3.1.2-4.1.12 (4.1 スタック) と hdi-3.1.2-5.0.8 (5.0 スタック) で修正されました
アップグレードの手順
1.データを準備する
既定では、HDInsight 3.6 では ACID テーブルがサポートされていません。 ただし、ACID テーブルが存在する場合は、それらに対して "主要な" 圧縮が実行されます。 圧縮の詳細については、Hive 言語マニュアルを参照してください。
プロパティ 値 Bash スクリプト URI https://hdiconfigactions.blob.core.windows.net/linuxhivemigrationv01/hive-adl-expand-location-v01.sh
ノードの種類 Head パラメーター
2.SQL データベースをコピーする
クラスターで既定の Hive メタストアを使用する場合は、こちらのガイドに従って、外部メタストアにメタデータをエクスポートします。 次に、アップグレードのためにその外部メタストアのコピーを作成します。
クラスターで外部の Hive メタストアを使用する場合は、そのコピーを作成します。 オプションとしては、エクスポートおよびインポートとポイントインタイム リストアがあります。
3.メタストア スキーマをアップグレードする
この手順では、HDInsight 4.0 の Hive Schema Tool
を使用して、メタストア スキーマをアップグレードします。
警告
この手順は元に戻せません。 これは、メタストアのコピーに対してのみ実行してください。
HDInsight 4.0 の一時クラスターを作成し、4.0 Hive
schematool
にアクセスします。 この手順では、既定の Hive メタストアを使用できます。HDInsight 4.0 クラスターから、
schematool
を実行して、ターゲットの HDInsight 3.6 メタストアをアップグレードします。 次のシェル スクリプトを編集して、SQL サーバー名、データベース名、ユーザー名、パスワードを追加します。 ヘッドノードで SSH セッションを開き、実行します。SERVER='servername.database.windows.net' # replace with your SQL Server DATABASE='database' # replace with your 3.6 metastore SQL Database USERNAME='username' # replace with your 3.6 metastore username PASSWORD='password' # replace with your 3.6 metastore password STACK_VERSION=$(hdp-select status hive-server2 | awk '{ print $3; }') /usr/hdp/$STACK_VERSION/hive/bin/schematool -upgradeSchema -url "jdbc:sqlserver://$SERVER;databaseName=$DATABASE;trustServerCertificate=false;encrypt=true;hostNameInCertificate=*.database.windows.net;" -userName "$USERNAME" -passWord "$PASSWORD" -dbType "mssql" --verbose
Note
このユーティリティでは、クライアント
beeline
を使用して、/usr/hdp/$STACK_VERSION/hive/scripts/metastore/upgrade/mssql/upgrade-*.mssql.sql
で SQL スクリプトを実行します。これらのスクリプトの SQL 構文は、必ずしも他のクライアント ツールと互換性があるとは限りません。 たとえば、SSMS と Azure portal のクエリ エディターでは、各コマンドの後にキーワード
GO
が必要です。リソースの容量またはトランザクションのタイムアウトが原因でスクリプトが失敗した場合は、SQL データベースをスケールアップします。
クエリ
select schema_version from dbo.version
を使用して最終バージョンを確認します。出力は、HDInsight 4.0 クラスターからの次の bash コマンドの出力と一致しているはずです。
grep . /usr/hdp/$(hdp-select --version)/hive/scripts/metastore/upgrade/mssql/upgrade.order.mssql | tail -n1 | rev | cut -d'-' -f1 | rev
HDInsight 4.0 の一時クラスターを削除します。
4.新しい HDInsight 4.0 クラスターをデプロイする
新しい HDInsight 4.0 クラスターを作成し、アップグレードされた Hive メタストアおよび同じストレージ アカウントを選択します。
新しいクラスターでは、同じ既定のファイルシステムを持つ必要はありません。
メタストアに、複数のストレージ アカウントに存在するテーブルが含まれている場合は、それらのストレージ アカウントを新しいクラスターに追加して、これらのテーブルにアクセスする必要があります。 HDInsight へのストレージ アカウントの追加に関するページを参照してください。
ストレージにアクセスできないことが原因で Hive ジョブが失敗する場合は、テーブルの場所が、クラスターに追加されたストレージ アカウントにあることを確認します。
次の Hive コマンドを使用して、テーブルの場所を確認します。
SHOW CREATE TABLE ([db_name.]table_name|view_name);
5.ACID 準拠のテーブルを変換する
マネージド テーブルは、HDInsight 4.0 の ACID に準拠している必要があります。 HDInsight 4.0 で strictmanagedmigration
を実行して、すべての非 ACID マネージド テーブルを、プロパティ 'external.table.purge'='true'
を使用して外部テーブルに変換します。 次をヘッド ノードから実行します。
sudo su - hive
STACK_VERSION=$(hdp-select status hive-server2 | awk '{ print $3; }')
/usr/hdp/$STACK_VERSION/hive/bin/hive --config /etc/hive/conf --service strictmanagedmigration --hiveconf hive.strict.managed.tables=true -m automatic --modifyManagedTables
6. MultiDelimitSerDe
に関する "クラスが見つからない" というエラー
問題
特定の状況で Hive クエリを実行すると、org.apache.hadoop.hive.contrib.serde2.MultiDelimitSerDe
クラスが見つからないことを示す java.lang.ClassNotFoundException
を受け取る場合があります。 このエラーは、お客様が HDInsight 3.6 から HDInsight 4.0 に移行するときに発生します。 HDI-4.0 では、HDInsight 3.6 で hive-contrib-1.2.1000.2.6.5.3033-1.jar
の一部である SerDe クラス org.apache.hadoop.hive.contrib.serde2.MultiDelimitSerDe
は削除されました。HDI-4.0 では hive-exec jar
の一部である org.apache.hadoop.hive.serde2.MultiDelimitSerDe
クラスが使用されます。 hive-exec jar
は、サービスの開始時に既定で HS2 に読み込まれます。
トラブルシューティングの手順
- フォルダー内の JAR にこのクラスが含まれているかどうかを確認します。この JAR は、多くの場合、Hive ライブラリ フォルダー内にあります。HDInsight では、このフォルダーは
/usr/hdp/current/hive/lib
です。 - 解決策の説明に従い、クラス
org.apache.hadoop.hive.contrib.serde2.MultiDelimitSerDe
とorg.apache.hadoop.hive.serde2.MultiDelimitSerDe
を確認します。
ソリューション
JAR ファイルはバイナリ ファイルですが、次のような
-Hrni
スイッチを指定したgrep
コマンドを使用して、特定のクラス名を検索できますgrep -Hrni "org.apache.hadoop.hive.contrib.serde2.MultiDelimitSerDe" /usr/hdp/current/hive/lib
これでクラスが見つからない場合、出力は返されません。 これで JAR ファイル内のクラスが見つかると、出力が返されます
HDInsight 4.x クラスターから取得した例を次に示します
sshuser@hn0-alters:~$ grep -Hrni "org.apache.hadoop.hive.serde2.MultiDelimitSerDe" /usr/hdp/4.1.9.7/hive/lib/ Binary file /usr/hdp/4.1.9.7/hive/lib/hive-exec-3.1.0.4.1-SNAPSHOT.jar matches
上記の出力から、jar にクラス
org.apache.hadoop.hive.contrib.serde2.MultiDelimitSerDe
が含まれていないこと、hive-exec jar にorg.apache.hadoop.hive.serde2.MultiDelimitSerDe
が含まれていることを確認できます。ROW FORMAT SERDE org.apache.hadoop.hive.serde2.MultiDelimitSerDe
のように、行形式の DerDe を使用してテーブルを作成しますこのコマンドにより、問題が解決されます。 テーブルを既に作成している場合は、次のコマンドを使用してテーブル名を変更できます
Hive => ALTER TABLE TABLE_NAME SET SERDE 'org.apache.hadoop.hive.serde2.MultiDelimitSerDe' Backend DB => UPDATE SERDES SET SLIB='org.apache.hadoop.hive.serde2.MultiDelimitSerDe' where SLIB='org.apache.hadoop.hive.contrib.serde2.MultiDelimitSerDe';
update コマンドの目的は、バックエンド DB で詳細を手動で更新することです。alter コマンドを使用して、beeline または Hive からの新しい SerDe クラスによりテーブルを変更します。
Hive バックエンド DB スキーマ比較スクリプト
移行が完了したら、次のスクリプトを実行できます。
バックエンド DB でいくつかの列が見つからない可能性があるため、クエリ エラーが発生します。 スキーマのアップグレードが正しく行われなかった場合は、無効な列名の問題が発生する可能性があります。 次のスクリプトは、顧客バックエンド DB から列名とデータ型をフェッチし、列が見つからない列や正しくないデータ型がある場合に出力を提供します。
次のパスには、schemacompare_final.py ファイルと test.csv ファイルが含まれています。 スクリプトは schemacompare_final.py
ファイル内に存在し、ファイル "test.csv" には、Hive バックエンド DB 内のすべてのテーブルで存在するべきすべての列名とデータ型が含まれています。
https://hdiconfigactions2.blob.core.windows.net/hiveschemacompare/schemacompare_final.py
https://hdiconfigactions2.blob.core.windows.net/hiveschemacompare/test.csv
これらの 2 つのファイルをリンクからダウンロードします。 また、これらのファイルを、Hive サービスが実行されているヘッド ノードのいずれかにコピーします。
スクリプトを実行するための手順
"/tmp" ディレクトリの下に schemacompare
という名前のディレクトリを作成します。
"schemacompare_final.py" と "test.csv" をフォルダー "/tmp/schemacompare" に配置します。 "ls -ltrh /tmp/schemacompare/" を実行し、ファイルが存在するかどうかを確認します。
Python スクリプトを実行するには、コマンド "python schemacompare_final.py" を使用します。 このスクリプトはスクリプトの実行を開始し、完了するまでにかかる時間は 5 分未満です。 上記のスクリプトは、バックエンド DB に自動的に接続し、各テーブルから詳細をフェッチします。Hive でこの詳細を使用し、"return.csv" という名前の新しい csv ファイルの詳細を更新します。 ファイル return.csv の作成後に、データがファイル "test.csv" と比較され、テーブル名の下に何か見つからないものがある場合は、その列名またはデータ型が出力されます。
スクリプトを実行すると、次の行が表示されます。これは、テーブルの詳細がフェッチされ、スクリプトが進行中であることを示します
KEY_CONSTRAINTS
Details Fetched
DELEGATION_TOKENS
Details Fetched
WRITE_SET
Details Fetched
SERDES
Details Fetched
また、"DIFFERENCE DETAILS:” 行の下に差分の詳細が表示されます。 何らかの違いがある場合は、出力されます
PART_COL_STATS;
('difference', ['BIT_VECTOR', 'varbinary'])
The line with semicolon PART_COL_STATS; is the table name. And under the table name you can find the differences as ('difference', ['BIT_VECTOR', 'varbinary']) if there are any difference in column or datatype.
テーブルに違いがない場合、出力は次のようになります。
BUCKETING_COLS;
('difference', [])
PARTITIONS;
('difference', [])
この出力から、見つからない列名や正しくない列名を見つけることができます。 バックエンド DB で次のクエリを実行して、列が見つからないかどうかを 1 回確認できます。
SELECT * FROM INFORMATION_SCHEMA.columns WHERE TABLE_NAME = 'PART_COL_STATS';
テーブルの列が見つからない場合、たとえば、挿入や上書き挿入などのクエリを実行すると、統計が自動的に計算され、PART_COL_STATS や TAB_COL_STATS などの統計テーブルの更新が試行されます。 また、テーブルに "BIT_VECTOR" のような列がない場合は、"列名が無効です" というエラーで失敗します。 次のコマンドで説明されているように、列を追加できます。 回避策として、バックエンド データベースの統計を更新できない次のプロパティを設定することで、統計を無効にすることができます。
hive.stats.autogather=false;
hive.stats.column.autogather=false;
To Fix this issue, run the following two queries on backend SQL server (Hive metastore DB):
ALTER TABLE PART_COL_STATS ADD BIT_VECTOR VARBINARY(MAX);
ALTER TABLE TAB_COL_STATS ADD BIT_VECTOR VARBINARY(MAX);
この手順では、移行後に "列名が無効です" で失敗するクエリ エラーを回避します。
HDInsight バージョン間で Hive をセキュリティ保護する
HDInsight は、必要に応じて、HDInsight Enterprise セキュリティ パッケージ (ESP) を使用して Microsoft Entra ID と統合します。 ESP では、Kerberos と Apache Ranger を使用して、クラスター内の特定のリソースのアクセス許可が管理されます。 次の手順で、HDInsight 3.6 内で Hive に対してデプロイした Ranger ポリシーを HDInsight 4.0 に移行できます。
- HDInsight 3.6 クラスター内の Ranger Service Manager パネルに移動します。
- HIVE という名前のポリシーに移動し、json ファイルにポリシーをエクスポートします。
- エクスポートされたポリシーの json 内で参照されているすべてのユーザーが新しいクラスターに存在することを確認します。 ユーザーがポリシーの json 内で参照されているのに新しいクラスターに存在しない場合は、新しいクラスターにユーザーを追加するか、ポリシーから参照を削除します。
- HDInsight 4.0 クラスター内の Ranger Service Manager パネルに移動します。
- HIVE という名前のポリシーに移動し、手順 2 からの ranger ポリシーの json をインポートします。
アプリケーションの変更が必要になる場合がある HDInsight 4.0 での Hive の変更点
Spark と Hive の間で ACID テーブル用にメタストアを共有する方法については、Hive Warehouse Connector を使用した追加の構成に関するページを参照してください。
HDInsight 4.0 では、ストレージ ベースの承認が使用されます。 ファイルのアクセス許可を変更したり、Hive とは別のユーザーとしてフォルダーを作成したりすると、ストレージのアクセス許可に基づいて Hive エラーが発生する可能性があります。 修正するには、ユーザーに
rw-
アクセス権を付与します。 「HDFS アクセス許可ガイド」を参照してください。HiveCLI
がBeeline
に置き換えられます。
その他の変更内容については、HDInsight 4.0 に関するお知らせを参照してください。
移行後
移行が完了したら、必ず次の手順に従ってください。
テーブルのサニティ
- CTAS または IOW を使用して Hive 3.1 でテーブルを再作成し、テーブルのプロパティを変更する代わりにテーブルの種類を変更します。
- doA は false のままにします。
- マネージド テーブル/データの所有権が "hive" ユーザーであることを確認します。
- テーブル形式が ORC の場合はマネージド ACID テーブルを使用し、ORC 以外の型にはマネージド非 ACID を使用します。
- 移行によって誤った統計が発生した可能性があるため、再作成されたテーブルの統計を再生成します。
クラスターの正常性
複数のクラスターが同じストレージと HMS DB を共有する場合は、1 つのクラスターでのみ自動圧縮/圧縮スレッドを有効にし、他のすべての場所で無効にする必要があります。
メタストアを調整して CPU 使用率を減らします。
トランザクション イベント リスナーを無効にします。
注意
Hive レプリケーション機能が使用されていない場合にのみ、次の手順を実行します。
- Ambari UI から、hive.metastore.transactional.event.listeners の値を削除します。
- 既定値:
org.apache.hive.hcatalog.listener.DbNotificationListener
- 新しい値:
<Empty>
Hive PrivilegeSynchronizer を無効にします。
- Ambari UI から、hive.privilege.synchronizer = false を設定します。
- 既定値:
true
- 新しい値:
false
パーティション修復機能を最適化します。
パーティションの修復を無効にする - この機能は、ストレージの場所にある Hive テーブルのパーティションを Hive メタストアと同期するために使用されます。 データ インジェスト後に
msck repair
を使用する場合は、この機能を無効にすることができます。この機能を無効にするには、ALTER TABLE. を使用してテーブル プロパティの下に "discover.partitions=false" を追加します。 OR (機能を無効にできない場合)
パーティションの修復頻度を増やします。
Ambari UI から、"metastore.partition.management.task.frequency" (秒単位) の値を増やします。
注意
この変更により、ストレージに取り込まれる一部のパーティションの可視性が遅れる可能性があります。
- 既定値:
60
- 提案された値:
3600
- 既定値:
高度な最適化。運用環境に適用する前に、以下のオプションを下位 (非 prod) 環境でテストする必要があります。
- 具体化されたビューが使用されていない場合は、具体化されたビューに関連するリスナーを削除します。
- Ambari UI からカスタム プロパティ (カスタム hive-site.xml) を追加し、不要なバックグラウンド メタストア スレッドを削除します。
- プロパティ名: metastore.task.threads.remote
- 既定値:
N/A (it uses few class names internally)
- 新しい値:
org.apache.hadoop.hive.metastore.txn.AcidHouseKeeperService,org.apache.hadoop.hive.metastore.txn.AcidOpenTxnsCounterService,org.apache.hadoop.hive.metastore.txn.AcidCompactionHistoryService,org.apache.hadoop.hive.metastore.txn.AcidWriteSetService,org.apache.hadoop.hive.metastore.PartitionManagementTask
レプリケーションが無効になっている場合は、バックグラウンド スレッドを無効にします。
- Ambari UI からカスタム プロパティ (カスタム hive-site.xml) を追加し、不要なスレッドを削除します。
- プロパティ名: metastore.task.threads.always
- 既定値:
N/A (it uses few class names internally)
- 新しい値:
org.apache.hadoop.hive.metastore.RuntimeStatsCleanerTask
クエリのチューニング
- TPC-DS ワークロード用にチューニングされているクエリを実行するには、Hive の既定の構成を保持します。 クエリ レベルのチューニングが必要なのは、失敗した場合や実行速度が遅い場合のみです。
- 不適切な計画や間違った結果を避けるために、統計が最新であることを確認します。
- 結合の種類のクエリで外部テーブルとマネージド ACID テーブルを混在させないようにします。 このような場合は、再作成によって、外部テーブルをマネージド非 ACID テーブルに変換してみてください。
- Hive-3 では、ベクター化、CBO、ゾーン付きのタイムスタンプなどで多くの作業が行われ、製品のバグが存在する可能性があります。 そのため、クエリで間違った結果が得られた場合は、ベクター化、CBO、マップ結合などを無効にして、それが役立つかどうかを確認してください。
移行後に正しくない結果とパフォーマンスの低下を修正するために従うその他の手順
問題 Hive クエリによって正しくない結果が得られます。 select count(*) クエリでも、正しくない結果が得られます。
原因 既定で、プロパティ "hive.compute.query.using.stats" は true に設定されています。 これを true に設定すると、metastore に格納されている統計を使用してクエリが実行されます。 統計が最新でない場合は、正しくない結果になります。
解決策 テーブル レベルと列レベルで
alter table <table_name> compute statics;
コマンドを使用して、マネージド テーブルの統計を収集します。 参照リンク - https://cwiki.apache.org/confluence/display/hive/statsdev#StatsDev-TableandPartitionStatistics問題 Hive クエリの実行に時間がかかっています。
原因 クエリに結合条件がある場合、hive は、テーブルのサイズと結合条件に基づいて、マップ結合またはマージ結合のどちらかを使用するプランを作成します。 テーブルの 1 つに小さなサイズが含まれている場合は、そのテーブルをメモリに読み込み、結合操作を実行します。 これにより、マージ結合と比較してクエリの実行が高速になります。
解決策 既定値であるプロパティ "hive.auto.convert.join=true" を必ず設定してください。 false に設定すると、マージ結合が使用され、パフォーマンスが低下する可能性があります。 Hive は、クラスターで設定されている次のプロパティに基づいて、マップ結合を使用するかどうかを決定します
set hive.auto.convert.join=true; set hive.auto.convert.join.noconditionaltask=true; set hive.auto.convert.join.noconditionaltask.size=<value>; set hive.mapjoin.smalltable.filesize = <value>;
hive.auto.convert.join.noconditionaltask=true
の場合に、小さいテーブルの推定サイズがハイブよりも小さい場合、一般的な結合を自動的にマップ結合に変換できます。auto.convert.join.noconditionaltask.size
(既定値は 10000000 MB)。プロパティ
hive.auto.convert.join
を true に設定したために OOM に関連する問題に直面した場合は、クラスター レベルではなく、セッション レベルでその特定のクエリに対してのみ false に設定することをお勧めします。 この問題は、統計が間違っていて、Hive が統計に基づいてマップ結合を使用することに決定した場合に発生する可能性があります。
問題 クエリに結合条件があり、関連するテーブルに null 値または空の値がある場合、Hive クエリで正しくない結果が得られます。
原因 クエリに関連するテーブルに多数の null 値がある場合、null 値に関連する問題が発生することがあります。 Hive は、関連する null 値を使用してクエリの最適化を誤って実行し、そのために誤った結果になります。
解決策 正しくない結果が得られる場合は、セッション レベルで プロパティ
set hive.cbo.returnpath.hiveop=true
を設定することをお勧めします。 この構成では、結合キーに対して null 以外のフィルター処理が導入されています。 テーブルに多数の null 値がある場合は、複数のテーブル間の結合操作を最適化するために、この構成を有効にして、null 以外の値のみを考慮できます。問題 クエリに複数の結合条件がある場合、Hive クエリでは正しくない結果が得られます。
原因 Tez では、マップ結合を使用した同じ結合が複数回存在するたびに、不適切なランタイム計画が生成されることがあります。
解決策
hive.merge.nway.joins
を false に設定すると、正しくない結果になる可能性があります。 影響を受けたクエリでのみ true に設定してみてください。 これは、同じ条件で複数の結合を使用してクエリを実行し、結合を 1 つの結合演算子にマージするのに役立ちます。 この方法は、再シャッフル フェーズを回避するために大きなシャッフル結合が行われる場合に便利です。問題 以前の実行と比較して、クエリの実行時間が日に日に増加しています。
原因 この問題は、小さなファイルの数が増える場合に発生する可能性があります。 そのため、Hive はデータを処理するためにすべてのファイルの読み取りに時間がかかるため、実行時間が長くなります。
解決策 必ず、管理されているテーブルに対して圧縮を頻繁に実行してください。 この手順により、小さなファイルが回避され、パフォーマンスが向上します。
参照リンク: Hive トランザクション - Apache Hive - Apache Software Foundation。
問題 Hive クエリでは、お客様がマネージド ACID orc テーブルとマネージド非 ACID orc テーブルに対して結合条件を使用している場合、正しくない結果が得られます。
原因 HIVE 3 以降では、すべてのマネージド テーブルを ACID テーブルとして保持することが厳密に要求されます。 また、それを ACID テーブルとして保持する場合は、テーブル形式を orc にする必要があり、これが主要な条件です。 ただし、厳密なマネージド テーブル プロパティ "hive.strict.managed.tables" を false にして無効にした場合は、マネージド非 ACID テーブルを作成できます。 場合によっては、外部 ORC テーブルを作成するか、移行後にテーブルを外部テーブルに変換し、厳密なマネージド テーブル プロパティを無効にしてマネージド テーブルに変換します。 この時点で、テーブルは非 ACID マネージド orc 形式に変換されます。
解決策 非 ACID マネージド ORC テーブルのテーブルと ACID マネージド ORC テーブルを結合すると、Hive の最適化が正しく行われません。
外部テーブルをマネージド テーブルに変換する場合
- プロパティ "hive.strict.managed.tables" を false に設定しないでください。 設定した場合、非 ACID マネージド テーブルを作成できますが、それは HIVE-3 では要求されません
alter table <table_name> set TBLPROPERTIES ('EXTERNAL'='false');
の代わりに次の alter コマンドを使用して、外部テーブルをマネージド テーブルに変換します。
alter table rt set TBLPROPERTIES ('EXTERNAL'='false', 'transactional'='true');
トラブルシューティング ガイド
「HDInsight 3.6 to 4.0 troubleshooting guide for Hive workloads (HDInsight 3.6 から 4.0 の Hive ワークロードのトラブルシューティング ガイド)」では、HDInsight 3.6 から HDInsight 4.0 へ Hive ワークロードを移行する際に直面する一般的な問題に対する回答を示しています。