Apache Hive / Kyuubi の概要

最終更新: 2026-07-27 21:28:09 +0800 +0800
原文は英語で書かれています。あなたはAI翻訳版を読んでいます。

Apache Hive は、分散ファイルシステムおよびオブジェクトストアに保存されたデータセットに対して SQL セマンティクスを提供します。Hive のデプロイメントは、1 つのデーモンでも、1 つのストレージ形式でもありません。SQL 言語、メタデータサービス、クエリコンパイル、実行エンジン、ウェアハウスストレージ、クライアントプロトコルを組み合わせたものです。

Hive に関連する複数の名称は、それぞれ異なるレイヤーを指します。

  1. Hive は、プロジェクト、HiveQL 言語、コンパイラー、オプティマイザー、ランタイム統合、および補助サービスです。
  2. Hive Metastore (HMS) は、テーブル、パーティション、スキーマ、ロケーション、統計情報、トランザクションのメタデータを保存・提供します。HMS が保存するのはテーブルデータではなくメタデータです。
  3. HiveServer2 (HS2) は、リモート JDBC および ODBC セッションを受け付け、HiveQL をコンパイルし、実行を調整して、結果を返します。
  4. hive CLI は、歴史的なシッククライアント型コマンドラインクライアントです。Hive のランタイムコードをローカルに読み込むため、HiveServer2 と混同しないでください。
  5. Beeline は JDBC コマンドラインクライアントです。共有デプロイメントでは、認証、設定、監査、リソース制御をサーバー側に維持できるため、HiveServer2 に対して Beeline を使用します。
  6. Apache Kyuubi は、HiveServer2 互換プロトコルを備えたマルチテナント SQL ゲートウェイです。Spark SQL などのエンジンを管理できますが、Kyuubi は HiveServer2 ではなく、Spark SQL を Hive の実行エンジンに変えるものでもありません。
  7. Kerberos は、Hadoop コンポーネント間でユーザーとサービスを認証します。Kerberos は、テーブルスキーマを定義したり、SQL を実行したり、SQL 権限を決定したりしません。
  8. Apache Kite SDK は、歴史的な Hadoop データセットツールエコシステムに属します。現在の Hive クエリパスの一部ではありません。

これらの区別は重要です。JDBC 接続が成功しても HMS が利用できない場合があり、HMS の検索が成功しても HDFS 権限によってクエリが拒否される場合があり、Kyuubi エンドポイントが HiveServer2 プロトコルを話していても Hive のコンパイラーやランタイムを実行しているとは限らないためです。

アーキテクチャ #

共有 Hive プラットフォームには、4 つの独立したプレーンがあります。

プレーンコンポーネント責務
クライアントBeeline、JDBC、ODBC、BI ツールセッションを開き、HiveQL を送信し、結果を取得する
SQL サービスHiveServer2認証、セッション管理、クエリコンパイル、作業の送信
メタデータHMS とそのリレーショナルデータベースカタログ、スキーマ、パーティション、統計、トランザクションのメタデータを保存する
データとコンピュートHDFS またはオブジェクトストレージ、YARN、Tez または他のサポート対象エンジンファイルの読み取り、データのシャッフル、出力の書き込み、結果のコミット

小規模なデプロイメントで同じプロセス内に実行される場合でも、HiveServer2 と HMS は別々のサービスです。責務も異なります。

  • HiveServer2 はクライアントセッションと SQL 操作を管理します。
  • HMS は永続的なメタデータ API を提供します。
  • Metastore RDBMS は HMS の実装詳細であり、アプリケーションから直接クエリまたは変更してはいけません。
  • ストレージシステムは、Metastore データベースから独立してテーブルファイルを保持します。
  • 実行エンジンは分散処理を実行します。クエリに回答するために HMS がテーブルファイルをスキャンすることはありません。

サービスを完全に分離し、Kyuubi を使用しない場合、Beeline は HiveServer2 に直接接続します。

text
Beeline
   | JDBC / HiveServer2 protocol
   v
HiveServer2
   |---- Thrift RPC -----------> Hive Metastore Service
   |                                  |
   |                                  v
   |                             Metastore RDBMS
   |
   |---- submit DAG -----------> YARN
   |                                  |
   |                                  v
   |                            Tez containers
   |
   `---------------------------> HDFS or object storage

代わりに Spark SQL が SQL サービスを提供する場合、Beeline は Spark Thrift Server に直接接続します。

text
Beeline
   | JDBC / HiveServer2 protocol
   v
Spark Thrift Server
   |---- Thrift RPC -----------> Hive Metastore Service
   |                                  |
   |                                  v
   |                             Metastore RDBMS
   |
   |---- Spark application ----> YARN
   |                                  |
   |                                  v
   |                            Spark executors
   |
   `---------------------------> HDFS or object storage

どちらのデプロイメントでも、クライアントは特定の 1 つの SQL サービスに接続します。そのサービスがクライアントセッションを管理し、実行エンジンを調整します。一方、別途デプロイされた HMS は Thrift API を通じてメタデータを提供します。クエリデータは実行コンテナとストレージの間を流れ、HMS や Metastore RDBMS を経由しません。

Kyuubi は、Beeline と独立して管理される SQL エンジンの間にゲートウェイを追加します。

text
Beeline
   | JDBC / HiveServer2 protocol
   v
Kyuubi server
   |---- launches or reuses ----> Per-user, group, or shared SQL engine
   |                                  |
   |                                  |----> YARN
   |                                  |----> Hive Metastore Service
   |                                  `----> HDFS or object storage
   |
   `---- authentication, routing, sessions, and high availability

Kyuubi はクライアント向けサービスとクエリ実行を分離します。ユーザーを分離型または共有型のエンジンアプリケーションにルーティングし、そのライフサイクルを管理しながら、HiveServer2 互換エンドポイントを提供できます。HMS、YARN、ストレージを置き換えるものではなく、Spark SQL などのエンジンが引き続きクエリセマンティクスとランタイムを提供します。

Docker-Based Hadoop/Spark/Hive Orchestration ページには、ローカルで複数サービスを実行するラボ環境があります。以下のセクションでは、データセマンティクス、クエリ動作、インストール、セキュリティ、運用について説明します。

エンドツーエンドのクエリを追跡する #

HiveServer2 に送信された Beeline クエリを考えます。

sql
SELECT customer_id, SUM(amount) AS revenue
FROM warehouse_demo.orders
WHERE order_date >= '2026-08-01'
GROUP BY customer_id;

リクエストは、次のような手順をたどります。

  1. 接続と認証。 Beeline は HiveServer2 への JDBC 接続を開きます。HiveServer2 は、設定された認証メカニズムを通じてセッション ID を確立します。
  2. 解析と分析。 Hive は HiveQL を抽象構文木に解析し、データベース、テーブル、カラム、関数、型を解決します。
  3. メタデータの読み取り。 コンパイラーは HMS に対して、テーブルのロケーション、ストレージ記述子、パーティション定義、統計情報、認可に関連するメタデータを要求します。
  4. 認可。 HiveServer2 と設定された認可プラグインは、認証済み ID と要求されたオブジェクトに対して操作を評価します。
  5. 論理プランの構築。 プランナーは、スキャン、フィルター、射影、集約、結合、書き込みを作成します。
  6. 最適化。 ルールベースおよびコストベースの処理により、メタデータとファイル形式が許す場合、パーティションとカラムの枝刈り、述語のプッシュダウン、結合順序の変更、結合実装の選択、ベクトル化オペレーターの有効化を行えます。
  7. 物理プランの構築。 Hive は最適化されたプランを、インストール済み Hive リリースがサポートする実行エンジン向けのタスクまたは有向非巡回グラフに変換します。
  8. 作業の送信。 HiveServer2 は、通常 YARN を通じて分散処理を送信し、ストレージやその他のサービスへのアクセスに必要な認証情報または委任トークンを伝播します。
  9. ストレージの読み書き。 タスクはテーブルの InputFormat、SerDe、ファイル形式リーダーを使用して行を生成します。出力タスクは対応するライターとコミットプロトコルを使用します。
  10. コミットとメタデータ更新。 書き込みに成功するとファイルを公開し、必要に応じてパーティションの追加、統計情報の更新、HMS へのトランザクション状態の記録を行います。
  11. 結果の返却。 HiveServer2 は JDBC クライアントに結果行をストリームまたはバッファーし、操作状態とログを記録します。

クエリ全体を通じて、HMS は補助サービスにとどまります。メタデータとトランザクション状態を提供しますが、データブロックは Metastore を経由せず、実行タスクとストレージの間を流れます。

データベース、テーブル、ロケーションを理解する #

Hive データベースは、デフォルトのストレージロケーションを持つメタデータ名前空間です。テーブルには、次の要素が含まれます。

  • データベースで修飾された名前
  • 通常のカラムとパーティションカラム
  • ストレージロケーション
  • SerDe、InputFormat、OutputFormat を含むストレージ記述子
  • テーブルプロパティ
  • オプションのバケット化、統計、制約、トランザクションメタデータ

名前空間を作成し、そのロケーションを調べます。

sql
CREATE DATABASE IF NOT EXISTS warehouse_demo
COMMENT 'Examples for the Hive overview';

DESCRIBE DATABASE EXTENDED warehouse_demo;
USE warehouse_demo;

ウェアハウスのデフォルト値は、選択した Hive リリースがサポートする managed および external warehouse の設定を含むサービス設定から取得されます。明示的なテーブル LOCATION は、派生したロケーションを上書きします。

sql
CREATE EXTERNAL TABLE inbound_events (
  event_id    BIGINT,
  event_type  STRING,
  payload     STRING
)
PARTITIONED BY (event_date STRING)
STORED AS PARQUET
LOCATION 'hdfs:///data/inbound/events';

DDL ファイルから推測するのではなく、DESCRIBE FORMATTED と SHOW CREATE TABLE を使用して実効メタデータを調べます。

sql
DESCRIBE FORMATTED inbound_events;
SHOW CREATE TABLE inbound_events;

Managed と External の所有権を選択する #

Managed テーブルと External テーブルは、クエリ構文ではなく所有権が異なります。

Managed テーブル #

Managed テーブルでは、ライフサイクル管理を Hive に委任します。

sql
CREATE TABLE customers (
  customer_id BIGINT,
  name        STRING,
  region      STRING
)
STORED AS ORC;

Managed テーブルを削除すると、メタデータと、アクティブな Hive およびファイルシステムのセマンティクスに従って、Managed データも削除されます。そのため、Managed ロケーションには Hive がライフサイクルを管理するファイルだけを配置してください。

External テーブル #

External テーブルは、ライフサイクルが別のプロセスまたはシステムに属するファイルを登録します。

sql
CREATE EXTERNAL TABLE application_logs (
  occurred_at STRING,
  level       STRING,
  message     STRING
)
PARTITIONED BY (log_date STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE
LOCATION 'hdfs:///shared/application-logs';

External テーブルを削除すると、通常はファイルを保持したままメタデータだけが削除されます。ただし、external.table.purge などのテーブルプロパティ、ストレージ固有の動作、リリース固有のセマンティクスによって結果が変わる場合があります。クリーンアップワークフローを採用する前に、プロパティを調べ、破棄可能なデータに対して削除動作をテストしてください。

所有権のルールから、次の運用要件が導かれます。

  1. Managed テーブルのロケーション配下に無関係なファイルを配置しない。
  2. External テーブルのメタデータを削除すればストレージもクリーンアップされると考えない。

テーブル作成後に EXTERNAL メタデータを変更しても、ファイルが自動的に移動したり、チーム間で所有権が移転したりすることはありません。

ファイルを行にマッピングする #

HMS は、テーブルの論理スキーマとストレージ記述子を保存します。リーダーは、次の 4 つの情報を組み合わせます。

  1. InputFormat はストレージオブジェクトを分割し、レコードリーダーを作成します。
  2. SerDe はレコードを Hive の値にデシリアライズし、出力用に値をシリアライズします。
  3. OutputFormat はレコードライターを作成し、出力処理に参加します。
  4. テーブルおよび SerDe プロパティ は、区切り文字、エンコーディングの詳細、圧縮設定、形式固有の動作を提供します。

STORED AS ORC、STORED AS PARQUET、STORED AS TEXTFILE は、適切なストレージクラスに展開されます。カスタム形式では、明示的なクラスが有用です。

sql
CREATE EXTERNAL TABLE csv_accounts (
  account_id BIGINT,
  email      STRING,
  active     BOOLEAN
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
WITH SERDEPROPERTIES (
  'separatorChar' = ',',
  'quoteChar' = '"',
  'escapeChar' = '\\'
)
STORED AS
  INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
  OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 'hdfs:///imports/accounts';

メタデータだけでは、すべてのファイルを検証できません。テーブルが 3 カラムを宣言していても、テキストファイルには 2 個、5 個、または不正なフィールドが含まれる可能性があります。SerDe と変換経路によって、互換性のない値は NULL になったり、エラーを発生させたり、誤解を招く行を生成したりします。

一般的なストレージ形式を比較する #

Text #

Text テーブルは、ファイルを容易に調査できるため、取り込み境界や診断に適しています。コストには次が含まれます。

  • 埋め込み型の信頼できるスキーマがない
  • 区切り文字とエスケープの曖昧さ
  • 型を考慮した統計情報が限られる
  • 行指向スキャン
  • 解析コストが高い
  • 述語およびカラムの枝刈りが弱い

圧縮によってストレージ容量を削減できますが、分割可能性に影響する場合があります。たとえば、単一の gzip ストリームは、標準的なテキストリーダーでは独立した範囲に分割できません。

ORC #

ORC は、型メタデータ、ストライプ、インデックス、圧縮、述語プッシュダウンに使用される統計情報を備えたカラムナー形式です。Hive のベクトル化リーダーと ACID 実装は ORC と緊密に統合されています。必要な ORC および Hive 機能を、参加するすべてのエンジンがサポートしている場合、Hive 管理の分析テーブルおよびトランザクションテーブルに ORC は適しています。

Parquet #

Parquet もカラムナー形式で、スキーマ、行グループ、エンコーディング、圧縮、統計情報を保存します。幅広いエンジンがサポートしているため、共有分析データセットで一般的です。ただし、互換性は論理型、タイムスタンプの解釈、decimal の精度、フィールドマッピング、ライターのバージョンに依存します。

どちらの形式も、誤ったテーブル定義を安全にするものではありません。HMS メタデータ、ファイルレベルのスキーマ、各リーダーのマッピング規則が一致している必要があります。

Schema-on-Read を契約として扱う #

Hive はファイルを読み取る際にテーブルメタデータを適用します。Schema-on-Read により、複数のテーブルで同じファイルを異なる方法で解釈できますが、互換性の制約がなくなるわけではありません。

比較的安全な変更には、互換性のあるリーダーが古いファイルでは存在しないものとして扱う nullable カラムの追加があります。より危険な変更には次があります。

  • カラムの順序変更
  • 数値幅または decimal 精度の変更
  • リーダーが名前でマッピングする場合のフィールド名変更
  • フィールド位置の削除と再利用
  • タイムスタンプまたは文字のセマンティクスの変更
  • パーティションカラム型の変更
  • 互換性のない論理型アノテーションで書き込まれたファイルの混在

ORC、Parquet、Hive、Spark、Trino は、設定とバージョンに応じて、位置、名前、または形式固有の識別子によってフィールドをマッピングできます。共有テーブルにスキーマ変更を適用する前に、意図したすべてのリーダーで変更をテストしてください。古いファイルのメタデータを繰り返し変更するよりも、新しいテーブルへデータを書き直す方が、明確な移行境界を提供します。

テーブルを意図的にパーティション化する #

パーティションカラムは、HMS に登録されたストレージプレフィックスへ、1 つの論理テーブルを分割します。

sql
CREATE TABLE orders (
  order_id     BIGINT,
  customer_id  BIGINT,
  order_ts     TIMESTAMP,
  amount       DECIMAL(18,2),
  status       STRING
)
PARTITIONED BY (order_date STRING)
STORED AS ORC;

典型的な HDFS レイアウトは次のようになります。

text
/warehouse/tablespace/managed/hive/warehouse_demo.db/orders/
├── order_date=2026-08-08/
│   └── 000000_0
└── order_date=2026-08-09/
    └── 000000_0

パーティション値はディレクトリ名と HMS メタデータに存在し、すべてのデータファイル内に含める必要はありません。クエリ述語によりパーティションプルーニングが可能になります。

sql
SELECT SUM(amount)
FROM orders
WHERE order_date BETWEEN '2026-08-01' AND '2026-08-09';

パーティションカラムへの直接述語が最も容易に枝刈りされます。カラムを関数でラップしたり、複雑な式を通じてフィルターを導出したりすると、オプティマイザーの機能によっては枝刈りが妨げられる場合があります。

パーティショニングは、過剰なメタデータを生成せず、一般的なフィルターに適合させる必要があります。

  • 大量のイベントデータには、時間単位のパーティションが適切な場合があります。
  • ユーザーごとに 1 パーティションを作成すると、HMS とファイルシステムに無制限の負荷がかかります。
  • 低ボリュームのパーティションでは、小さなファイルが大量に生成されることがあります。
  • オブジェクトストレージでのパーティション検出には、高コストの一覧取得が必要になる場合があります。

静的パーティションと動的パーティションを書き込む #

Text ステージングテーブルを作成します。

sql
CREATE TABLE staging_orders (
  order_id     BIGINT,
  customer_id  BIGINT,
  order_ts     TIMESTAMP,
  amount       DECIMAL(18,2),
  status       STRING,
  order_date   STRING
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE;

静的パーティションの挿入では、文中でパーティション値を固定します。

sql
INSERT OVERWRITE TABLE orders
PARTITION (order_date = '2026-08-09')
SELECT
  order_id,
  customer_id,
  order_ts,
  amount,
  status
FROM staging_orders
WHERE order_date = '2026-08-09';

動的パーティションの挿入では、最終射影カラムからパーティション値を取得します。

sql
SET hive.exec.dynamic.partition=true;
SET hive.exec.dynamic.partition.mode=nonstrict;

INSERT INTO TABLE orders
PARTITION (order_date)
SELECT
  order_id,
  customer_id,
  order_ts,
  amount,
  status,
  order_date
FROM staging_orders
WHERE order_date >= '2026-08-01';

動的挿入では、1 つの文で多数のパーティションを作成できます。動的パーティション数とファイル数について、リリースに適した制限を適用し、送信前に想定外のパーティションカーディナリティを拒否してください。

パーティションを登録し、メタデータを修復する #

External テーブル配下に配置したファイルが、HMS のパーティションレコードを常に作成するとは限りません。既知のパーティションを明示的に登録します。

sql
ALTER TABLE application_logs
ADD IF NOT EXISTS
PARTITION (log_date = '2026-08-09')
LOCATION 'hdfs:///shared/application-logs/log_date=2026-08-09';

登録された値を調べます。

sql
SHOW PARTITIONS application_logs;

MSCK REPAIR TABLE は、互換性のあるディレクトリ名をスキャンし、一部の欠落したメタデータを調整します。

sql
MSCK REPAIR TABLE application_logs;

修復の動作は、Hive のリリースとオプションによって異なります。修復には大規模な再帰一覧取得が必要になる場合があり、古いメタデータを削除せずにパーティションを追加することがあり、命名規則に一致するものの不正なファイルを含むディレクトリを登録することもあります。オブジェクトストレージでは、一覧取得コストと一貫性に関する懸念が増幅されます。取り込みパイプラインでは、プロデューサーがコミットしたパーティションをすでに把握しているため、明示的な ALTER TABLE ADD PARTITION 操作を優先してください。

Hive の外部でファイルを削除しても、古いパーティションメタデータは残ります。External テーブルからパーティションを削除しても、メタデータだけが削除される場合があります。一方、Managed テーブルの動作ではデータが削除されることがあります。次のコマンドを実行する前に、所有権セマンティクスを確認してください。

sql
ALTER TABLE application_logs
DROP IF EXISTS PARTITION (log_date = '2026-07-01');

バケット化を書き込み契約として使用する #

バケット化は、1 つ以上のカラムを宣言されたファイル数にハッシュします。

sql
CREATE TABLE bucketed_orders (
  order_id     BIGINT,
  customer_id  BIGINT,
  order_ts     TIMESTAMP,
  amount       DECIMAL(18,2)
)
CLUSTERED BY (customer_id)
SORTED BY (order_ts)
INTO 32 BUCKETS
STORED AS ORC;

バケットメタデータは、サンプリングや一部の結合・集約最適化をサポートできます。メリットを得るには、互換性のあるハッシュ関数、バケット数、ライター、実行設定が必要です。

HMS はバケット宣言を記録しますが、既存ファイルがそれに従っていることは証明しません。任意のファイルをバケット化テーブルのロケーションへコピーすると、32 バケットを宣言しているのに、誤ってハッシュまたは命名されたファイルを含むテーブルになる可能性があります。互換性のあるエンジンを通じてバケット化データを書き込み、物理出力を調べ、バケット対応最適化に依存する前に結果を検証してください。SORTED BY も想定される書き込みレイアウトを記述するだけであり、既存ファイルをソートするものではありません。

ファイルをロードするか、行を書き直す #

LOAD DATA と INSERT は異なる目的を持ちます。

LOAD DATA #

sql
LOAD DATA LOCAL INPATH '/srv/hive-import/orders.tsv'
OVERWRITE INTO TABLE staging_orders;

LOAD DATA は従来、すべての行を解析して書き直すことなく、テーブルまたはパーティションのロケーションへファイルをコピーまたは移動します。リモート Beeline セッションの場合、LOCAL は Beeline を実行しているワークステーションではなく、HiveServer2 ホストのファイルシステムを指します。リリース固有のチェックにより、特にパーティション化またはバケット化されたターゲットでは、一部のロードが書き換えられたり拒否されたりする場合があります。インストール済みリリースのドキュメントを確認してください。

ロードが成功しても、区切り文字、型、バケット割り当てが正しいとは限りません。その後にステージングテーブルをクエリして検証してください。

INSERT #

sql
INSERT INTO TABLE orders
PARTITION (order_date = '2026-08-09')
SELECT
  order_id,
  customer_id,
  order_ts,
  amount,
  status
FROM staging_orders
WHERE order_date = '2026-08-09';

INSERT はクエリを実行し、ターゲットテーブルのシリアライザーと出力形式を通じて書き込みます。計算コストは発生しますが、ターゲット射影を適用し、設定されたストレージ形式を生成します。

CTAS でテーブルを構築する #

Create-table-as-select は、スキーマの導出とデータ投入を組み合わせます。

sql
CREATE TABLE high_value_orders
STORED AS ORC
AS
SELECT
  order_id,
  customer_id,
  order_ts,
  amount,
  status,
  order_date
FROM orders
WHERE amount >= 1000.00;

CTAS は、マテリアライズされた中間データセットや形式変換に適しています。利用者が正確なカラムコメント、制約、パーティション化、バケット化、トランザクションプロパティ、ロケーション制御を必要とする場合は、明示的な DDL が適しています。

分析用 HiveQL を記述する #

結合と集約 #

sql
SELECT
  c.region,
  COUNT(*)      AS order_count,
  SUM(o.amount) AS revenue
FROM orders o
JOIN customers c
  ON o.customer_id = c.customer_id
WHERE o.order_date BETWEEN '2026-08-01' AND '2026-08-09'
  AND o.status = 'PAID'
GROUP BY c.region
ORDER BY revenue DESC;

共通テーブル式 #

sql
WITH paid_orders AS (
  SELECT customer_id, amount
  FROM orders
  WHERE order_date = '2026-08-09'
    AND status = 'PAID'
),
customer_totals AS (
  SELECT customer_id, SUM(amount) AS revenue
  FROM paid_orders
  GROUP BY customer_id
)
SELECT
  c.customer_id,
  c.name,
  t.revenue
FROM customer_totals t
JOIN customers c
  ON t.customer_id = c.customer_id
WHERE t.revenue >= 5000.00;

ウィンドウ関数 #

sql
SELECT
  customer_id,
  order_id,
  order_ts,
  amount,
  ROW_NUMBER() OVER (
    PARTITION BY customer_id
    ORDER BY order_ts DESC
  ) AS recency_rank,
  SUM(amount) OVER (
    PARTITION BY customer_id
    ORDER BY order_ts
    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  ) AS running_revenue
FROM orders
WHERE order_date BETWEEN '2026-08-01' AND '2026-08-09';

ウィンドウ関数は入力行の粒度を維持しながら、パーティション上で値を計算します。一方、GROUP BY は行を集約キーごとに 1 つの出力行へ縮約します。

EXPLAIN でプランを調べる #

コストの高い文を実行する前に、EXPLAIN を使用します。

sql
EXPLAIN FORMATTED
SELECT
  c.region,
  SUM(o.amount) AS revenue
FROM orders o
JOIN customers c
  ON o.customer_id = c.customer_id
WHERE o.order_date = '2026-08-09'
GROUP BY c.region;

プランでは次を確認します。

  • 選択されたパーティション
  • 射影されたカラム
  • プッシュダウンされた述語
  • 結合順序と結合実装
  • 推定行数
  • シャッフル境界
  • ベクトル化オペレーター
  • 実行ステージの数と種類

プランの構文と詳細は、Hive のリリースおよび実行エンジンによって異なります。プランテキストを安定した API とみなすのではなく、同じリリースと設定の下でプランを比較してください。

オプティマイザー用の統計情報を収集する #

コストベースオプティマイザーには、最新のテーブル、パーティション、カラム統計が必要です。

sql
ANALYZE TABLE customers
COMPUTE STATISTICS;

ANALYZE TABLE customers
COMPUTE STATISTICS FOR COLUMNS customer_id, region;

ANALYZE TABLE orders
PARTITION (order_date = '2026-08-09')
COMPUTE STATISTICS;

ANALYZE TABLE orders
PARTITION (order_date = '2026-08-09')
COMPUTE STATISTICS FOR COLUMNS customer_id, amount, status;

記録されたメタデータを調べます。

sql
DESCRIBE FORMATTED customers;
DESCRIBE FORMATTED orders PARTITION (order_date = '2026-08-09');

外部ファイルの変更、パーティションの置換、HMS を想定どおりに更新しないエンジンによる書き込み後は、統計情報が古くなります。行数が欠落していたり古かったりすると、結合順序やメモリ推定が不適切になる可能性があります。自動統計設定によって手作業は減りますが、網羅性と鮮度を監視する必要はなくなりません。

実行エンジンを選択して設定する #

Hive はクエリを実行バックエンド向けの作業にコンパイルします。サポート対象の選択肢は、正確な Hive ディストリビューションとリリースによって異なります。

  • MapReduce は Hive の歴史的な実行パスの一部であり、古いデプロイメントでは引き続き重要です。
  • Tez は多くの Hive デプロイメントでサポートされ、クエリステージを DAG として実行します。
  • Spark は一部のリリース系列で Hive の実行エンジンとして利用できましたが、サポート、パッケージング、保守状況はバージョンによって異なります。
  • Spark または Kyuubi を通じた Spark SQL は、同じ HMS カタログを読み取る場合でも別の SQL エンジンです。

別のクラスタコンポーネントがインストールされているという理由だけで、エンジン名を設定してはいけません。まず Hive リリースのドキュメント、エンジンアーティファクト、Hadoop 互換性、サービス設定、運用ツールを確認してください。

変更可能なセッションプロパティを調べて変更します。

sql
SET hive.execution.engine;
SET hive.execution.engine=tez;
SET hive.execution.engine;

設定ソースは、スコープと優先順位が高くなります。

  1. Hive の組み込みデフォルトが基本値を提供します。
  2. hive-site.xml がサービス全体のデプロイメント値を設定します。
  3. --hiveconf などのサービス起動引数が、そのプロセスの設定値を上書きします。
  4. セッション SET は、HiveServer2 がクライアントによる変更を許可するプロパティを上書きできます。
  5. 文のヒントは、1 つのクエリに対してサポートされるオプティマイザーの判断に影響を与えます。

HiveServer2 は、セッションから変更できるプロパティを制限またはホワイトリスト化できます。サーバー専用設定、セキュリティ制御、静的初期化値では、SET の変更が拒否されたり、再起動が必要になったりする場合があります。hivevar 値はクエリ置換を行うもので、設定とは同等ではありません。

sql
SET hivevar:run_date=2026-08-09;

SELECT COUNT(*)
FROM orders
WHERE order_date = '${hivevar:run_date}';

クライアントパスがサポートする場合は、アプリケーションコードでバインドパラメーターを使用してください。テキスト置換は一般的な SQL インジェクション対策ではありません。

主な最適化を理解する #

パーティションと述語の枝刈り #

パーティションプルーニングは、関係のないパーティションロケーションの一覧取得とオープンを回避します。述語プッシュダウンは、互換性のあるフィルターを ORC または Parquet リーダーへ渡し、統計情報に基づいてストライプ、行グループ、ページをスキップできるようにします。

不透明な UDF、キャスト、互換性のない型、フィルター対象カラムを囲む式は、プッシュダウンを妨げる可能性があります。述語がファイルリーダーへ到達したと仮定せず、EXPLAIN で動作を確認してください。

カラムプルーニング #

カラムナーリーダーは、参照されていないカラムをスキップできます。

sql
SELECT customer_id, amount
FROM orders
WHERE order_date = '2026-08-09';

SELECT * は、I/O、デシリアライズ、ネットワーク転送、スキーマ結合リスクを増加させます。永続的なジョブでは必要なカラムだけを射影してください。

ベクトル化 #

ベクトル化実行は、1 行ずつオブジェクトを処理するのではなく、カラム値のバッチを処理します。ORC と互換性のあるオペレーターが最も恩恵を受けます。サポートされていない型、UDF、SerDe、式、実行パスでは、行モードへフォールバックすることがあります。ベクトル化による性能変化と判断する前に、インストール済みリリースのプランとランタイムカウンターを確認してください。

コストベース最適化 #

コストベースオプティマイザーは、行数、データサイズ、個別値の推定、カラム分布を使用してプランを比較します。CBO は、統計情報がない場合や誤解を招く場合を補正できません。大きな変更後は統計情報を更新し、EXPLAIN で結合順序を検証してください。

結合戦略 #

小さなディメンションはブロードキャストまたは map join して、大きい側のシャッフルを回避できます。

sql
SELECT /*+ MAPJOIN(c) */
  o.order_id,
  c.region,
  o.amount
FROM orders o
JOIN customers c
  ON o.customer_id = c.customer_id
WHERE o.order_date = '2026-08-09';

ヒントは統計情報の代替ではなく、計測された例外を記録するものにしてください。タスクメモリを超えるテーブルをブロードキャストすると、障害や長時間のガベージコレクション停止が発生します。

大規模な結合には、互換性のあるパーティショニングと十分なシャッフル容量が必要です。バケット対応結合は、メタデータと物理ファイルの両方が必要なバケット契約を満たす場合にのみ、処理を削減できます。

データの偏り #

少数の高頻度キーによって、レコードが 1 つの reducer またはタスクに集中することがあります。症状には、他のタスクより大幅に長く実行されるタスクや、不均衡なシャッフル入力があります。対応には次が含まれます。

  • 結合前にフィルターまたは集約する
  • 既知の高負荷キーを分離する
  • キーにソルトを付け、結果を再結合する
  • サポートされる skew join 最適化を使用する
  • 本当に小さい側をブロードキャストする
  • 小さな出力ファイルを過剰に生成しない範囲で並列性を高める

ボトルネックはデータ分布とクエリ形状によって決まるため、すべての偏りパターンを単一の設定で修正することはできません。

小さなファイル #

小さなファイルは、次のコストを増加させます。

  • NameNode および HMS 関連のメタデータ負荷
  • オブジェクトストレージの一覧取得とリクエストコスト
  • タスク起動のオーバーヘッド
  • リーダー初期化
  • 出力コミット操作

小さなファイルは、過剰なパーティションカーディナリティ、過度なタスク並列性、頻繁なマイクロバッチ、上流パーティションごとの 1 ライターなどから発生します。より大きなバッチ書き込み、制限されたパーティション数、定期的な書き直しを優先してください。コンパクションクエリで 1 つのパーティションを書き直せます。

sql
INSERT OVERWRITE TABLE orders
PARTITION (order_date = '2026-08-09')
SELECT
  order_id,
  customer_id,
  order_ts,
  amount,
  status
FROM orders
WHERE order_date = '2026-08-09';

選択したテーブル型と実行エンジンで、上書きのセマンティクスをテストしてください。トランザクションテーブルでは、非トランザクションの書き直しを同等とみなすのではなく、コンパクションサブシステムを使用します。

Hive ACID テーブルを理解する #

Hive ACID テーブルは、行レベルのトランザクションメタデータとスナップショット対応リーダーを追加します。正確な要件とサポートされる操作は、リリース、ストレージバックエンド、テーブル型、相互運用するエンジンによって異なります。すべてのライターとリーダーについて、トランザクションのドキュメントを確認してください。

保守的な full-ACID 定義では、ORC と明示的なバケット化を使用します。

sql
CREATE TABLE account_balances (
  account_id BIGINT,
  balance    DECIMAL(18,2),
  updated_at TIMESTAMP
)
CLUSTERED BY (account_id) INTO 16 BUCKETS
STORED AS ORC
TBLPROPERTIES (
  'transactional' = 'true'
);

トランザクション DML を実行します。

sql
INSERT INTO account_balances
VALUES
  (1001, 125.50, CURRENT_TIMESTAMP),
  (1002, 980.00, CURRENT_TIMESTAMP);

UPDATE account_balances
SET balance = balance + 25.00,
    updated_at = CURRENT_TIMESTAMP
WHERE account_id = 1001;

DELETE FROM account_balances
WHERE account_id = 1002;

MERGE INTO account_balances AS target
USING balance_updates AS source
ON target.account_id = source.account_id
WHEN MATCHED THEN UPDATE SET
  balance = source.balance,
  updated_at = source.updated_at
WHEN NOT MATCHED THEN INSERT VALUES (
  source.account_id,
  source.balance,
  source.updated_at
);

MERGE、update、delete、insert-only テーブル、External transactional テーブル、非 ORC の組み合わせには、リリース固有の制限があります。DDL の解析だけからサポートを推測せず、並行性、再起動、コンパクション、クロスエンジンのテストを実行してください。

Base ファイルと Delta ファイル #

トランザクションストレージには、論理的な世代が含まれます。

  • base_WRITEID ディレクトリには、write ID までコンパクションされたスナップショットが含まれます。
  • delta_MIN_MAX ディレクトリには、write ID 範囲の挿入または更新行が含まれます。
  • delete_delta_MIN_MAX ディレクトリには、古いファイル内の行に対する削除イベントが含まれます。

リーダーはトランザクションシステムから有効な write ID リストを取得し、可視の base、delta、delete-delta の内容をスナップショットへマージします。そのため、ファイル一覧は現在のテーブル行を直接表しません。

ロックとトランザクション状態 #

HMS は、オープントランザクション、write ID、ロック、コンパクション状態を RDBMS に保存します。代表的なトランザクションマネージャー設定は次のとおりです。

xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
  <name>hive.support.concurrency</name>
  <value>true</value>
</property>
<property>
  <name>hive.txn.manager</name>
  <value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value>
</property>
</configuration>

サポートされる SQL コマンドを通じて状態を調べます。

sql
SHOW TRANSACTIONS;
SHOW LOCKS account_balances EXTENDED;
SHOW COMPACTIONS;

長時間実行中または放棄されたトランザクションは、スナップショットを保持し、cleaner の処理を遅延させ、古いファイルを保持する可能性があります。リリース固有の管理手順でトランザクションを中止する前に、所有するクエリまたはサービスを診断してください。

コンパクション #

Minor compaction は delta ファイルを結合します。Major compaction は delta を新しい base に書き直します。cleaner は、有効なリーダーが不要になった後にのみ古いファイルを削除します。

コンパクションを要求します。

sql
ALTER TABLE account_balances COMPACT 'minor';
ALTER TABLE account_balances COMPACT 'major';
SHOW COMPACTIONS;

Metastore 側の initiator、worker、cleaner プロセスは、インストール済みリリースに従って有効化する必要があります。ALTER TABLE ... COMPACT の要求が成功しても、作業がキューに追加されたことを示すだけであり、worker が実行されたことや古いファイルが削除されたことを証明しません。キュー滞留時間、失敗回数、オープントランザクション、ファイルシステムの増加を監視してください。

Hive をインストールして設定する #

Hive リリースは、選択した Java、Hadoop、Metastore データベース、実行エンジンのバージョンとの互換性を確認してから選択します。プロセスが正常に起動しても、すべてのクエリパスが互換性を持つことは証明されません。

サービスホストに Hive を展開し、安定したロケーションを定義します。

sh
export JAVA_HOME=/opt/java
export HADOOP_HOME=/opt/hadoop
export HIVE_HOME=/opt/hive
export HIVE_CONF_DIR=/etc/hive/conf
export PATH="$HIVE_HOME/bin:$HADOOP_HOME/bin:$JAVA_HOME/bin:$PATH"

リリースがテンプレートを提供している場合は、$HIVE_HOME/conf/hive-env.sh.template を設定ディレクトリへコピーします。サービス固有の JVM オプションと Hadoop パスは、$HIVE_HOME/bin 配下のスクリプトを変更するのではなく、そこに設定してください。

Hive には次が必要です。

  1. 対象のファイルシステムとリソースマネージャーを解決する Hadoop クライアント設定
  2. ウェアハウス、Metastore、HiveServer2、実行、セキュリティ設定を含む hive-site.xml
  3. 選択した Metastore RDBMS 用 JDBC ドライバーを、Metastore プロセスのクラスパスに配置すること
  4. ウェアハウス、scratch、ログ、ローカル作業ディレクトリへアクセスできるサービス ID

デプロイメントのサービスおよびグループモデルに合う権限で HDFS パスを準備します。

sh
hdfs dfs -mkdir -p /tmp /warehouse/tablespace/managed/hive
hdfs dfs -chmod 1777 /tmp
hdfs dfs -chown -R hive:hadoop /warehouse/tablespace/managed/hive
hdfs dfs -chmod -R 0770 /warehouse/tablespace/managed/hive

この例では、hive サービスと hadoop グループにウェアハウスアクセスを付与します。クラスタで使用する認可モデルに応じて、ID とモードを置き換えてください。

単一プロセスの実験では、Derby でローカル Metastore を初期化できます。

sh
mkdir -p "$HOME/hive-derby-lab"
cd "$HOME/hive-derby-lab"
schematool -dbType derby -initSchema --verbose
schematool -dbType derby -info
hiveserver2

設定と作業ディレクトリを別途指定しない限り、Derby はプロセスの設定および作業ディレクトリを基準に metastore_db を保存します。そのため、異なるロケーションからスキーマ初期化と HiveServer2 を実行すると、2 つの独立した Metastore が作成される可能性があります。Derby は単一所有者動作であるため、共有 HMS や複数の HiveServer2 インスタンスには適していません。

外部 RDBMS で HMS をデプロイする #

共有デプロイメントでは、Metastore 状態に PostgreSQL や MySQL などのサポート対象外部 RDBMS を使用します。組み込み Derby は 1 つの所有プロセスしか許可しないため、分離されたテストにのみ適しています。

Metastore プロセスを、JDBC ドライバーと次のようなプロパティで設定します。

xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
  <property>
    <name>javax.jdo.option.ConnectionURL</name>
    <value>jdbc:postgresql://metastore-db.example.com:5432/hive_metastore</value>
  </property>
  <property>
    <name>javax.jdo.option.ConnectionDriverName</name>
    <value>org.postgresql.Driver</value>
  </property>
  <property>
    <name>javax.jdo.option.ConnectionUserName</name>
    <value>hive_metastore</value>
  </property>
  <property>
    <name>hadoop.security.credential.provider.path</name>
    <value>jceks://file/etc/hive/conf/hive-metastore.jceks</value>
  </property>
  <property>
    <name>hive.metastore.warehouse.dir</name>
    <value>/warehouse/tablespace/managed/hive</value>
  </property>
  <property>
    <name>hive.metastore.warehouse.external.dir</name>
    <value>/warehouse/tablespace/external/hive</value>
  </property>
  <property>
    <name>hive.metastore.schema.verification</name>
    <value>true</value>
  </property>
</configuration>

デプロイされたリリースがサポートする Hadoop credential provider を使用して、対応するパスワードエイリアスを作成します。

sh
hadoop credential create javax.jdo.option.ConnectionPassword \
  -provider jceks://file/etc/hive/conf/hive-metastore.jceks

コマンドは値の入力を求めます。Hive サービス ID とプラットフォームの秘密情報配布制御で provider ファイルを保護してください。本番用の平文パスワードをソース管理へ配置しないでください。

新しいスキーマを 1 回だけ初期化します。

sh
export HIVE_CONF_DIR=/etc/hive/conf

schematool -dbType postgres -initSchema --verbose
schematool -dbType postgres -info

Thrift Metastore を起動します。

sh
hive --service metastore -p 9083

HiveServer2 と他の HMS クライアントには、Metastore URI が必要です。

xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
  <property>
    <name>hive.metastore.uris</name>
    <value>thrift://hive-metastore.example.com:9083</value>
  </property>
  <property>
    <name>hive.metastore.client.socket.timeout</name>
    <value>600</value>
  </property>
</configuration>

Hive をアップグレードする前に、次を行います。

  1. リリースのアップグレード手順に従って、ライターを停止またはフェンスする。
  2. Metastore RDBMS を、ネイティブバックアップツールでバックアップする。
  3. 現在のスキーマとソフトウェアバージョンを確認する。
  4. 文書化されたスキーマアップグレードを 1 回実行する。
  5. HMS を起動し、ライターを再開する前に読み取りを検証する。

代表的なスキーマコマンドは次のとおりです。

sh
schematool -dbType postgres -info
schematool -dbType postgres -upgradeSchema --verbose
schematool -dbType postgres -info

失敗した移行を回避するために、Metastore テーブルを手動で編集してはいけません。HMS スキーマの詳細は内部仕様であり、リリース間で変更される可能性があります。

HiveServer2 で SQL を提供する #

サービスマネージャーの監視下で、HiveServer2 をフォアグラウンドで起動します。

sh
hiveserver2 \
  --hiveconf hive.server2.thrift.bind.host=0.0.0.0 \
  --hiveconf hive.server2.thrift.port=10000

本番のプロセス監視では、再起動ポリシー、ログ、環境、リソース制限、認証情報を管理する必要があります。HMS を先に起動することは必要ですが十分ではありません。HiveServer2 が HMS、ストレージ、実行バックエンド、scratch ディレクトリへ到達できることを確認してください。

Beeline で接続します。

sh
beeline \
  -u 'jdbc:hive2://hiveserver2.example.com:10000/warehouse_demo' \
  -n alice

分散処理を送信する前に、小規模な DDL スモークテストを実行します。

sql
CREATE DATABASE IF NOT EXISTS demo;
USE demo;
CREATE TABLE IF NOT EXISTS greeting (id INT, name STRING);
SHOW TABLES;
DESCRIBE FORMATTED greeting;

スクリプトを非対話的に実行します。

sh
beeline \
  -u 'jdbc:hive2://hiveserver2.example.com:10000/warehouse_demo' \
  -n alice \
  --showHeader=true \
  --outputformat=tsv2 \
  -f report.sql

便利な Beeline コマンドには次があります。

text
!info
!tables
!describe orders
!set
!quit

Beeline コマンドは ! で始まり、HiveQL 文はセミコロンで終了します。

JDBC で接続する #

Java クライアントには、Hive JDBC ドライバーと互換性のある依存関係が必要です。

java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;

public final class HiveRevenueQuery {
    public static void main(String[] args) throws Exception {
        String url = System.getenv("HIVE_JDBC_URL");
        Properties properties = new Properties();
        properties.setProperty("user", System.getenv().getOrDefault("HIVE_USER", "alice"));

        try (Connection connection = DriverManager.getConnection(url, properties);
             PreparedStatement statement = connection.prepareStatement(
                 "SELECT customer_id, SUM(amount) AS revenue " +
                 "FROM warehouse_demo.orders " +
                 "WHERE order_date = ? " +
                 "GROUP BY customer_id")) {
            statement.setString(1, "2026-08-09");

            try (ResultSet rows = statement.executeQuery()) {
                while (rows.next()) {
                    System.out.printf(
                        "%d\t%s%n",
                        rows.getLong("customer_id"),
                        rows.getBigDecimal("revenue")
                    );
                }
            }
        }
    }
}

URL はソースコードの外部で設定します。

sh
export HIVE_JDBC_URL='jdbc:hive2://hiveserver2.example.com:10000/warehouse_demo'
java -cp 'app.jar:hive-jdbc.jar:lib/*' HiveRevenueQuery

依存関係の組み立ては、Hive のリリースとアプリケーションのビルドシステムに依存します。対象サーバー向けに文書化された JDBC アーティファクトを使用してください。任意のドライバーバージョンでは、認証、プロトコルネゴシエーション、型変換で失敗する可能性があります。

認証と認可を分離する #

セキュリティ上の判断は複数のレイヤーにまたがります。

Kerberos 認証 #

Kerberos は ID を証明します。保護されたクライアントはチケットを取得します。

sh
kinit alice@EXAMPLE.COM
klist

beeline \
  -u 'jdbc:hive2://hiveserver2.example.com:10000/warehouse_demo;principal=hive/hiveserver2.example.com@EXAMPLE.COM'

HiveServer2 自体は、サービスプリンシパルと保護された keytab を使用します。HMS、HDFS、YARN、その他のサービスには別のプリンシパルを設定できます。Kerberos 認証に成功しても、SELECT、DROP、HDFS 読み取り、YARN 送信の権限が付与されるわけではありません。

Kerberos Beeline-to-Kyuubi walkthrough では、チケット取得、SASL/GSSAPI 認証、TLS、Kyuubi セッション選択、完全な JDBC URL における Hadoop 委任について説明します。

SQL 認可 #

SQL 権限には、Hive 認可モードまたは Apache Ranger などの外部ポリシーシステムが必要です。デプロイメントとバージョンによって、ポリシー適用範囲には次が含まれます。

  • データベース、テーブル、カラム、URI へのアクセス
  • 行フィルターとカラムマスキング
  • 管理操作
  • 監査レコード

すべてのクエリパスで同等のポリシーを適用する必要があります。HiveServer2 で保護されたテーブルでも、ユーザーが HDFS ファイルを直接読み取れたり、認可の弱い別のエンジンへ到達できたりすると、情報が漏洩する可能性があります。

doAs とストレージ ID #

HiveServer2 の偽装を有効にすると、ストレージおよび実行操作を接続ユーザーとして実行できます。Hadoop の proxy-user ルール、委任トークン、ローカルユーザーマッピング、HDFS 権限が、そのモデルをサポートしている必要があります。

偽装を無効にすると、操作は Hive サービス ID として実行されます。この場合、HDFS は複数ユーザーに対して 1 つのサービスアカウントしか認識しないため、SQL 認可が不可欠です。1 つの ID モデルを意図的に選択し、HS2、YARN、ストレージ全体で監査をテストしてください。

HDFS 権限 #

HDFS 権限は、ウェアハウスディレクトリ、scratch パス、ステージングパス、直接ファイルアクセスを管理します。サービス ID で確認します。

sh
hdfs dfs -ls -d /warehouse/tablespace/managed/hive
hdfs dfs -test -w /warehouse/tablespace/managed/hive
hdfs dfs -ls -d /tmp/hive

誰でも書き込めるウェアハウスディレクトリは、重要な防御を失わせます。共有 scratch ディレクトリには sticky bit セマンティクスが必要になる場合があります。一方、テーブルデータでは、認可モデルに合ったサービス所有権、グループ、ACL、ポリシーを使用してください。

TLS と秘密情報 #

Kerberos は、すべての JDBC 転送を自動的に暗号化するわけではありません。ネットワーク上の機密性が必要な場合は、HiveServer2 の TLS と信頼検証を設定します。

sh
beeline \
  -u 'jdbc:hive2://hiveserver2.example.com:10000/warehouse_demo;ssl=true;sslTrustStore=/etc/security/truststore.jks'

トラストストアのパスワードは、コマンドライン履歴ではなく、保護されたクライアント設定または秘密情報メカニズムを通じて提供してください。Metastore データベースのパスワード、LDAP 認証情報、keytab、クラウドストレージ認証情報、秘密情報を含む JDBC URL にも同じ規則を適用します。

Kyuubi を適切に配置する #

Kyuubi は HiveServer2 互換インターフェースを公開し、ユーザーごとまたは共有の SQL エンジンを管理します。一般的な経路は次のとおりです。

text
Beeline or JDBC
    -> Kyuubi server
    -> Spark SQL engine
    -> HMS-compatible catalog
    -> HDFS or object storage

プロトコルは HiveServer2 に似ていても、セマンティクスは異なる場合があります。

  • Spark SQL が Hive ではなくクエリを解析・最適化します。
  • 実行は Spark 設定によって制御されます。
  • Hive 専用構文、認可フック、ACID 動作、UDF は引き継がれない場合があります。
  • HMS は共有カタログとして残ることがありますが、実行エンジンになるわけではありません。

すべての HiveServer2 プロトコルサービスを HiveServer2 と呼ぶのではなく、エンドポイントを Kyuubi として文書化してください。

Kite を歴史的な文脈として扱う #

Kite SDK は、データセット、スキーマ、Hadoop ストレージ統合のための Java API とコマンドラインツールを提供していました。既存システムには、Kite が作成したメタデータやコードが残っている場合がありますが、Hive に Kite は必要ありません。新しい Hive アーキテクチャへ Kite を追加するのではなく、それぞれの依存関係制約に従ってアプリケーションを移行または保守してください。

HiveServer2 と HMS を運用する #

クエリとセッションの状態を追跡する #

HiveServer2 は、セッションと操作を別々に管理します。切断されたクライアントは、タイムアウトまたはキャンセルポリシーによって削除されるまで、処理を実行し続ける場合があります。次を監視してください。

  • 開いているセッションとアイドルセッション
  • アクティブおよびキュー待ちの操作
  • クエリ ID と YARN アプリケーション ID
  • コンパイル、キュー待ち、実行、フェッチの時間
  • 結果セットと操作ログの保持
  • 認証および認可の失敗

インストール済みリリースが提供するサポート対象メトリクス、JMX、ログ、管理エンドポイントを使用してください。ログ形式と Web インターフェースは、すべてのリリースで安定しているわけではありません。

クライアントから見える診断情報を取得します。

sh
beeline \
  -u 'jdbc:hive2://hiveserver2.example.com:10000/warehouse_demo' \
  --verbose=true \
  -f failing-query.sql

Hive クエリ ID を HiveServer2 ログ、エンジンの DAG またはジョブ ID、YARN アプリケーションと関連付けます。

Metastore の健全性を確認する #

HMS のレイテンシーは、コンパイル、パーティション一覧取得、認可、トランザクション処理に影響します。次を監視してください。

  • RDBMS 接続と接続プールの飽和
  • Metastore データベースの低速クエリとロック待ち
  • HMS リクエストのレイテンシーとエラー率
  • スキーマバージョン
  • パーティションとカラム統計の量
  • オープントランザクションとコンパクションキュー
  • データベースのストレージ、バックアップ、レプリケーションの健全性

サポート対象ツールでスキーマを確認します。

sh
schematool -dbType postgres -info

日常的な修復手段として、直接 SQL 更新を使用しないでください。

HDFS、YARN、Tez を確認する #

サービス障害と SQL 障害を分離します。

sh
hdfs dfsadmin -report
yarn node -list -all
yarn application -list -appStates ACCEPTED,RUNNING,FAILED
yarn logs -applicationId application_1234567890000_0042

アプリケーション ID は、HiveServer2 または YARN が報告した値に置き換えてください。Tez では、DAG の状態と利用可能な Tez 診断情報を調べます。HS2 セッションが正常でも、キュー容量、リソース不足、認証情報、コンテナメモリが原因で実行アプリケーションが拒否される場合があります。

ウェアハウスと scratch の権限を確認する #

書き込みで使用されるすべてのパスをテストします。

sh
hdfs dfs -ls -d /warehouse/tablespace/managed/hive
hdfs dfs -ls -d /warehouse/tablespace/external/hive
hdfs dfs -ls -d /tmp
hdfs dfs -du -h /warehouse/tablespace/managed/hive/warehouse_demo.db

読み取り専用クエリが成功しても、サービスがステージングディレクトリを作成できなかったり、コミット済み出力をリネームできなかったりして、CTAS または INSERT が失敗する場合があります。

パーティションと統計を確認する #

物理状態と Metastore 状態を比較します。

sql
SHOW PARTITIONS orders;
DESCRIBE FORMATTED orders PARTITION (order_date = '2026-08-09');
SELECT COUNT(*) FROM orders WHERE order_date = '2026-08-09';

空のクエリ結果は、次を意味する可能性があります。

  • パーティションメタデータがない
  • パーティションロケーションが誤っている
  • 別のディレクトリ表記でファイルが配置されている
  • SerDe またはスキーマに互換性がない
  • ストレージ認証情報が不足している
  • 登録されたパーティション文字列と述語値が一致していない

データまたはメタデータを修正した後、統計情報を更新してください。

コンパクションの滞留を確認する #

sql
SHOW TRANSACTIONS;
SHOW COMPACTIONS;
SHOW LOCKS account_balances EXTENDED;

失敗したコンパクション、worker の不在、長時間オープンしているトランザクション、cleaner の遅延を調査します。ACID の delta ディレクトリを手動で削除するとスナップショットが破損する可能性があり、コンパクションの代替にはなりません。

レイヤーごとにトラブルシューティングする #

症状最初の確認項目一般的な原因
Beeline が接続できないHS2 リスナー、DNS、TLS、認証ログJDBC URL の誤り、到達不能な広告ホスト、プリンシパル不一致
接続は成功するが SQL コンパイルに失敗するHS2 ログ、HMS URI、schematool -infoHMS 使用不可、スキーマ不一致、メタデータ権限不足
テーブルは存在するがクエリが行を返さないSHOW PARTITIONS、DESCRIBE FORMATTED、HDFS 一覧パーティションメタデータ不足、ロケーション誤り、スキーマ不一致
クエリが accepted または queued のままになるYARN キュー、NodeManager、エンジンリソース容量不足、メモリ要求過大、キューポリシー
1 つのタスクだけが大幅に長く実行されるタスクカウンター、キー分布、シャッフル入力データの偏り、分割不能な入力、投機的実行の前提不成立
クエリが過剰なデータをスキャンするEXPLAIN、パーティション述語、ファイル統計プルーニングなし、統計情報の古さ、述語プッシュダウン非対応
挿入によって多数のファイルが作成されるタスク数、パーティション数、ライターの動作並列性過剰、動的パーティション、マイクロバッチ
Drop により想定外のファイルが削除されるテーブル型、プロパティ、ロケーション所有権Managed セマンティクス、External purge 設定
ACID ストレージが継続的に増加するトランザクション、コンパクション、cleanerworker 不足、コンパクション失敗、長時間のリーダー
コミット中に Permission denied が発生するサービス ID、scratch とウェアハウス ACLdoAs の誤り、proxy-user ルール、HDFS 所有権
エンジンごとに異なる値が返るスキーマ、タイムスタンプ、decimal、ACID サポートリーダー互換性またはカタログ解釈の不一致

一度に変更するレイヤーは 1 つにしてください。JAR の置き換え、Metastore 行の変更、ファイル削除を同時に行うと、元の障害を特定するために必要な証拠が失われます。

Spark、Trino、Iceberg と相互運用する #

共有メタデータは、同一のセマンティクスを意味しません。

Spark #

Spark SQL は HMS 互換カタログを使用し、Hive テーブルを読み取れます。その場合も、Spark が独自のパーサー、オプティマイザー、実行エンジン、ファイルリーダー、コミッター、設定を提供します。互換性は次に依存します。

  • ストレージ形式と SerDe
  • パーティション登録
  • タイムスタンプと decimal の設定
  • バケット化の実装
  • Hive ACID のサポート
  • カタログクライアントのバージョン
  • 認可統合

enableHiveSupport() は Hive カタログ統合を設定しますが、Spark SQL を HiveServer2 経由にするものではありません。

Trino #

Trino の Hive コネクターは、テーブルおよびパーティションメタデータに HMS を使用しながら、ストレージを直接読み取れます。クエリは HiveServer2 を経由しません。SQL 構文、型マッピング、ビュー、セキュリティ、ACID 機能、書き込み動作は、コネクターとリリースによって異なります。

Iceberg #

Iceberg は、スナップショットメタデータ、マニフェスト、スキーマおよびパーティションの進化、独自のコミットモデルを持つテーブル形式です。HMS はポインターと識別子を保存することで Iceberg カタログとして機能できますが、HMS が Iceberg のテーブルメタデータを置き換えるわけではありません。

各レイヤーを分離して考えてください。

レイヤー例
SQL エンジンまたはゲートウェイHiveServer2、Spark SQL、Trino、Kyuubi
カタログサービスHive Metastore、Iceberg REST カタログ
テーブル形式Hive 形式のディレクトリテーブル、Iceberg
ファイル形式ORC、Parquet、text
ストレージHDFS、S3 互換オブジェクトストレージ

Iceberg テーブルを通常の External Parquet テーブルとして登録し、メタデータを迂回して書き込まないでください。そのような書き込みは Iceberg スナップショットを迂回し、ファイルを不可視にしたり、テーブル不変条件を破壊したりする可能性があります。参加するすべてのエンジンが明示的にサポートするカタログとコネクターの組み合わせを使用してください。

正確なリリースに対して変更を計画する #

Hive の動作はリリース系列によって変化します。特に次の点に注意してください。

  • Java と Hadoop の互換性
  • 実行エンジン
  • ACID テーブルの要件
  • External テーブルの削除セマンティクス
  • 認可プラグイン
  • Metastore スキーマのバージョン
  • ベクトル化とオプティマイザールール
  • timestamp、decimal、ORC、Parquet の動作
  • オブジェクトストレージのコミットプロトコル
  • Spark、Trino、テーブル形式との相互運用性

別のクラスタのプロパティや構文を採用する前に、インストール済みバージョンのドキュメントとリリースノートを読んでください。起動時に受け付けられる設定キーでも、無視されたり、非推奨だったり、意味が異なったりする場合があります。

公式リファレンス #

Apache wiki は移行済みトピックについて読み取り専用であり、現在のドキュメントへのリンクを提供します。詳細が最新ページと異なる場合は、デプロイされたリリースに対応するドキュメントセットを優先してください。

コメント

GitHub で閲覧・コメントする(投稿にはログインが必要です)