すべてのプロダクト
Search
ドキュメントセンター

E-MapReduce:Phoenix

最終更新日:Jun 22, 2026

Apache Phoenix は HBase 上に構築された SQL レイヤーであり、標準 SQL を使用して HBase に保存されたデータをクエリおよび管理できます。

前提条件

Phoenix および HBase サービスを選択して、DataServing クラスターまたはカスタムクラスターを作成済みであること。詳細については、「クラスターの作成」をご参照ください。

コマンドラインからの Phoenix の使用

  1. SSH を使用してクラスターに接続します。詳細については、「クラスターへのログイン」をご参照ください。

  2. 次のコマンドを実行して、Phoenix コマンドラインツールを使用します。

    /opt/apps/PHOENIX/phoenix-current/bin/sqlline.py
  3. SQL を使用してデータをクエリできます。一般的な操作は次のとおりです:

    • テーブルの作成

      CREATE TABLE IF NOT EXISTS example(
          my_pk bigint not null,
          m.first_name varchar(50),
          m.last_name varchar(50) 
          CONSTRAINT pk PRIMARY KEY (my_pk)
      );
    • データの挿入

      UPSERT INTO example(my_pk,m.first_name,m.last_name) VALUES(100,'Jack','Ben');
      UPSERT INTO example(my_pk,m.first_name,m.last_name) VALUES(200,'Jack3','Ben3');
    • データのクエリ

      SELECT * FROM example;

      クエリは次の出力を返します。

      +--------+-------------+------------+
      | MY_PK  | FIRST_NAME  | LAST_NAME  |
      +--------+-------------+------------+
      | 100    | Jack        | Ben        |
      | 200    | Jack3       | Ben3       |
      +--------+-------------+------------+
    • テーブルの削除

      DROP TABLE IF EXISTS example;

JDBC を使用した Phoenix への接続

Maven 依存関係の設定

<dependency>
     <groupId>org.apache.phoenix</groupId>
     <artifactId>phoenix-core</artifactId>
     <version>${phoenix.version}</version>
</dependency>

${phoenix.version} は、お使いのクラスター上の Phoenix バージョンと一致させる必要があります。

コード例

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import java.sql.Statement;
public class TestPhoenixJdbc {
    public static void main(String[] args) throws SQLException {
        Statement stmt = null;
        ResultSet rset = null;
        Class.forName("org.apache.phoenix.jdbc.PhoenixDriver");
        Connection con = DriverManager.getConnection("jdbc:phoenix:[zookeeper quorum hosts]");
        stmt = con.createStatement();
        stmt.executeUpdate("create table test (mykey integer not null primary key, mycolumn varchar)");
        stmt.executeUpdate("upsert into test values (1,'Hello')");
        stmt.executeUpdate("upsert into test values (2,'World!')");
        con.commit();
        PreparedStatement statement = con.prepareStatement("select * from test");
        rset = statement.executeQuery();
        while (rset.next()) {
            System.out.println(rset.getString("mycolumn"));
        }
        statement.close();
        con.close();
    }
}

JDBC 経由での Kerberos 対応 Phoenix への接続

ご利用のクラスターで Kerberos 認証を使用している場合、このセクションでは、Kerberos が有効な EMR クラスター上の Phoenix サービスに安全に接続する JDBC クライアントを作成する方法について説明します。クライアントは、プリンシパルと keytab の情報を含む JDBC URL を使用して認証し、基本的な DDL および DML 操作を実行して接続を検証します。

ステップ 1:環境と認証情報の準備

コードを作成する前に、環境を設定し、クラスターのマスターノードで Kerberos 認証情報を作成します。

  1. SSH を使用してマスターノードに接続します。詳細については、「クラスターへのログイン」をご参照ください。

  2. Kerberos レルムを特定します。

    Kerberos が有効な各クラスターには、一意のレルムがあります。

    次のコマンドを実行して Kerberos レルムを取得します。後で使用するためにレルムを記録しておきます。

    cat /etc/krb5.conf | grep default_realm

    以下は応答例です。

    default_realm = EMR.C-4FC5FDDE3759****.COM
  3. クライアントプリンシパルを作成します。

    プリンシパルは、Kerberos におけるクライアントの一意の ID です。Java アプリケーション用にプリンシパルを作成する必要があります。

    1. マスターノードで、次のコマンドを実行して kadmin.local ツールを使用します。

      sudo kadmin.local
    2. `kadmin.local` のインタラクティブなセッションで、次のコマンドを実行してプリンシパルを作成します。

      addprinc phoenix_client@EMR.C-4FC5FDDE3759****.COM

      プロンプトが表示されたら、プリンシパルのパスワードを設定し、覚えておいてください。keytab ファイルを使用するとパスワードなしでログインできますが、場合によってはこのパスワードが必要になることがあります。

  4. keytab ファイルをエクスポートします。

    1. `kadmin.local` ツールで、次のコマンドを実行して keytab ファイルをエクスポートします。

      xst -k /tmp/phoenix_client.keytab phoenix_client@EMR.C-4FC5FDDE3759****.COM
    2. 次のコマンドを実行して `kadmin.local` を終了します。

      exit
      重要
      • 権限:Java プログラムを実行するユーザーが keytab ファイルに対する読み取り権限を持っていることを確認してください。

      • 配布: Java プログラムを別のマシンで実行する場合は、phoenix_client.keytab ファイルと /etc/krb5.conf ファイルをそのマシンに安全にコピーし、それらがアプリケーションがアクセスできるパスにあることを確認してください。

ステップ 2:アプリケーションの作成とパッケージング

  • 方法 1:プリコンパイルされた JAR ファイルの使用 (クイック検証)

    hbase-phoenix-kerberos-1.0-SNAPSHOT.jar

  • 方法 2:手動でのコンパイルとパッケージング (本番環境に推奨)

    手動でのコンパイルとパッケージングには、次のコード例を使用できます。

    コアコード例 (PhoenixKerberosDemo.java)

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    /**
     * JDBC を使用して Kerberos で保護された Phoenix クラスターに接続するクライアント。
     * すべての接続パラメーターは、コマンドラインから渡される完全な JDBC URL を通じて提供されます。
     */
    public class PhoenixKerberosDemo {
        /**
         * アプリケーションのメインエントリポイント。
         *
         * @param args コマンドライン引数。プログラムは 1 つの引数、つまり完全な Phoenix JDBC URL を想定しています。
         */
        public static void main(String[] args) {
            // --- 1. コマンドライン入力の検証:1 つの引数、JDBC URL を想定 ---
            if (args.length != 1) {
                System.err.println("ERROR: Invalid number of arguments.");
                System.err.println("Usage: java PhoenixKerberosDemo \"<full_jdbc_url>\"");
                System.err.println("Example: \"jdbc:phoenix:zk1,zk2:2181:/hbase:user@REALM.COM:/path/to/user.keytab\"");
                System.exit(1); // エラーコードで終了
            }
            String jdbcUrl = args[0];
            System.out.println("Attempting to connect to Phoenix...");
            System.out.println("Using JDBC URL: " + jdbcUrl);
            try {
                // --- 2. Phoenix ドライバーのロード ---
                Class.forName("org.apache.phoenix.jdbc.PhoenixDriver");
            } catch (ClassNotFoundException e) {
                System.err.println("FATAL ERROR: Phoenix JDBC driver not found in the classpath.");
                e.printStackTrace();
                System.exit(1);
            }
            // --- 3. try-with-resources 文を使用して接続を確立し、SQL を実行します。この構文はリソースを自動的に閉じます。---
            try (Connection con = DriverManager.getConnection(jdbcUrl);
                 Statement stmt = con.createStatement()) {
                System.out.println("Connection established successfully.");
                final String tableName = "TEST";
                System.out.println("Creating table '" + tableName + "'...");
                stmt.executeUpdate("CREATE TABLE IF NOT EXISTS " + tableName + " (mykey INTEGER NOT NULL PRIMARY KEY, mycolumn VARCHAR)");
                con.commit();
                System.out.println("Upserting data...");
                stmt.executeUpdate("UPSERT INTO " + tableName + " VALUES (1, 'Hello')");
                stmt.executeUpdate("UPSERT INTO " + tableName + " VALUES (2, 'World-Kerberos!')");
                con.commit();
                System.out.println("Data upserted successfully.");
                String sql = "SELECT * FROM " + tableName;
                System.out.println("Querying for results with: " + sql);
                try (PreparedStatement statement = con.prepareStatement(sql);
                     ResultSet rset = statement.executeQuery()) {
                    System.out.println("Query results:");
                    while (rset.next()) {
                        System.out.println(rset.getInt("mykey") + " -> " + rset.getString("mycolumn"));
                    }
                }
                System.out.println("Cleaning up the test table...");
                stmt.executeUpdate("DROP TABLE IF EXISTS " + tableName);
                con.commit();
            } catch (SQLException e) {
                // SQL 例外をキャッチし、役立つトラブルシューティングのヒントを提供します
                System.err.println("\n--- FAILED TO EXECUTE DATABASE OPERATION ---");
                System.err.println("Please check the following:");
                System.err.println("1. The JDBC URL is correct (format, principal, keytab path).");
                System.err.println("2. Network connectivity to ZooKeeper and HBase.");
                System.err.println("3. The keytab file exists and has correct read permissions.");
                System.err.println("4. The principal has sufficient permissions on HBase tables and namespaces.");
                e.printStackTrace();
            }
            System.out.println("\nExecution finished.");
        }
    }
    

    Maven 設定 (pom.xml)

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                                 http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.aliyun.emr.doctor</groupId>
        <artifactId>hbase-phoenix-kerberos</artifactId>
        <version>1.0-SNAPSHOT</version>
        <name>Archetype - hbase-phoenix-kerberos</name>
        <url>http://maven.apache.org</url>
        <properties>
            <phoenix.version>5.2.1</phoenix.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.apache.phoenix</groupId>
                <artifactId>phoenix-core</artifactId>
                <version>${phoenix.version}</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
        <build>
            <plugins>
                <!--  Java コンパイラ  -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.1</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-shade-plugin</artifactId>
                    <version>3.2.4</version>
                    <executions>
                        <execution>
                            <phase>package</phase>
                            <goals>
                                <goal>shade</goal>
                            </goals>
                            <configuration>
                                <filters>
                                    <filter>
                                        <artifact>*:*</artifact>
                                        <excludes>
                                            <exclude>META-INF/*.SF</exclude>
                                            <exclude>META-INF/*.DSA</exclude>
                                            <exclude>META-INF/*.RSA</exclude>
                                        </excludes>
                                    </filter>
                                </filters>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </project>

ステップ 3:アプリケーションの実行

  1. 実行環境を選択します。

    次の 2 つの実行環境のいずれかを選択します:

    • クラスターノードでの実行 (推奨):

      • クラスターノードには、必要な Hadoop、HBase、および Phoenix の依存関係ライブラリがプリインストールされているため、追加の設定は不要です。ネットワーク接続もデフォルトで利用可能であり、完全で安定した環境を提供します。

      • 最適な用途:開発およびデバッグ中の迅速な検証とテスト。

    • クラスター外での実行

      プログラムをクラスター外で実行するには、次の条件が満たされていることを確認してください:

      • ネットワーク接続:プログラムを実行するマシンと、クラスターの ZooKeeper、HBase Master、および RegionServer ノードとの間のネットワーク接続を確保してください。

      • Kerberos 構成: クラスターの krb5.conf ファイルと生成された keytab ファイルを、プログラムを実行するマシンにコピーします。

      • 依存関係の管理:実行コマンドのクラスパスには、必要なすべての Hadoop、HBase、および Phoenix クライアントの依存関係 JAR ファイルを含める必要があります。これは通常、クラスターノードで実行するよりも複雑です。依存関係の管理には、Maven や Gradle などのツールを使用することを推奨します。

  2. スクリプトを実行します。

    以下の kerberos-phoenix.sh スクリプトには、すべての必須設定が含まれています。必要に応じて、このスクリプトを編集して実行できます。

    #!/bin/bash
    # ======================= 1. ユーザー設定 (ご利用の環境に合わせて変更) =======================
    # Hadoop および HBase 設定ファイルのディレクトリ
    HADOOP_CONF_DIR="/etc/taihao-apps/hadoop-conf"
    HBASE_CONF_DIR="/etc/taihao-apps/hbase-conf"
    # Phoenix クライアント JAR ファイルへのパス。シンボリックリンクを使用することは、バージョンの変更に対応するためのベストプラクティスです。
    # まず、`ls -l /opt/apps/PHOENIX/phoenix-current/` を使用してこのファイルが存在することを確認します。このパスは、バージョンによって変更が必要な場合があります。
    PHOENIX_JAR="/opt/apps/PHOENIX/phoenix-current/phoenix-client-lite-hbase-2.6.jar"
    # ご利用のアプリケーションの JAR ファイル名。
    YOUR_JAR_FILE="hbase-phoenix-kerberos-1.0-SNAPSHOT.jar"
    # Kerberos 設定ファイルへのパス。
    KRB5_CONF_PATH="/etc/krb5.conf"
    # --- [コア] JDBC URL 設定 ---
    # フォーマット:jdbc:phoenix:[ZK アドレス]:[ZK ポート]:[HBase ZNode]:[プリンシパル]:[Keytab の絶対パス]
    # 以下の ZK アドレス、REALM、および keytab パスを実際の情報に置き換えてください。
    ZK_QUORUM="master-1-1" # ZooKeeper ノードが複数ある場合は、カンマで区切ります (例: "zk1,zk2,zk3")
    ZK_PORT="2181"
    HBASE_ZNODE="/hbase" # セキュアなクラスターの場合、/hbase-secure になることがあります
    PRINCIPAL="phoenix_client@EMR.C-4FC5FDDE3759****.COM" # ご利用のプリンシパルに置き換えてください
    KEYTAB_PATH="/tmp/phoenix_client.keytab" # keytab ファイルへの絶対パス
    JDBC_URL="jdbc:phoenix:${ZK_QUORUM}:${ZK_PORT}:${HBASE_ZNODE}:${PRINCIPAL}:${KEYTAB_PATH}"
    # =================================================================================
    # ======================= 2. 実行 (通常は変更不要) =================================
    echo "================================================="
    echo "Starting Phoenix Kerberos JDBC Demo..."
    echo "Using JDBC URL: ${JDBC_URL}"
    echo "================================================="
    # クラスパスを構築します。順序:カレントディレクトリ -> 設定ディレクトリ -> ご利用の JAR -> 依存関係 JAR
    # `hbase classpath` は、コアの Hadoop/HBase 依存関係を自動的にロードします
    CLASS_PATH=".:${HADOOP_CONF_DIR}:${HBASE_CONF_DIR}:${YOUR_JAR_FILE}:${PHOENIX_JAR}:$(hbase classpath)"
    # Java プログラムの実行
    java -cp "${CLASS_PATH}" \
         -Djava.security.krb5.conf="${KRB5_CONF_PATH}" \
         PhoenixKerberosDemo "${JDBC_URL}"
    # 終了コードの確認
    if [ $? -eq 0 ]; then
        echo -e "\n[SUCCESS] Program finished successfully."
    else
        echo -e "\n[FAILED] Program terminated with an error."
    fi
    # =================================================================================
    1. ステップ 2 でパッケージ化された JAR ファイルと kerberos-phoenix.sh スクリプトを、マスターノード上のターゲットディレクトリにアップロードします。

    2. 次のコマンドを実行して、スクリプトに実行権限を付与します。

      chmod +x kerberos-phoenix.sh
    3. 次のコマンドを実行して、スクリプトを実行します。

      ./kerberos-phoenix.sh

      以下は出力例です:

      2025-08-13 13:22:30,825 INFO query.GuidePostsCacheProvider: Sucessfully loaded class for GuidePostsCacheFactor of type: org.apache.phoenix.query.DefaultGuidePostsCacheFactory
      2025-08-13 13:22:30,939 INFO connectionqueryservice.ConnectionQueryServicesMetricsManager: Created object for NoOp Connection query service metrics manager
      Connection established successfully.
      Creating table 'TEST'...
      2025-08-13 13:22:33,433 INFO client.HBaseAdmin: Operation: CREATE, Table Name: default:TEST, procId: 144 completed
      Upserting data...
      Data upserted successfully.
      Querying for results with: SELECT * FROM TEST
      Query results:
      1 -> Hello
      2 -> World-Kerberos!
      Cleaning up the test table...
      2025-08-13 13:22:33,597 INFO client.HBaseAdmin: Started disable of TEST
      2025-08-13 13:22:34,209 INFO client.HBaseAdmin: Operation: DISABLE, Table Name: default:TEST, procId: 147 completed
      2025-08-13 13:22:34,521 INFO client.HBaseAdmin: Operation: DELETE, Table Name: default:TEST, procId: 151 completed
      Execution finished.
      2025-08-13 13:22:34,559 INFO log.QueryLoggerDisruptor: Shutting down QueryLoggerDisruptor..
      2025-08-13 13:22:34,559 INFO client.ConnectionImplementation: Closing master protocol: MasterService
      2025-08-13 13:22:34,563 INFO hbase.ChoreService: Chore service for: AsyncConn Chore Service had [ScheduledChore name=RefreshCredentials, period=30000, unit=MILLISECONDS] on shutdown
      2025-08-13 13:22:34,563 INFO query.ConnectionQueryServicesImpl: hconnection-0x1fdf1c5 HConnection closed. Stacktrace for informational purposes: java.lang.Thread.getStackTrace(Thread.java:1564)
      org.apache.phoenix.util.LogUtil.getCallerStackTrace(LogUtil.java:55)
      org.apache.phoenix.query.ConnectionQueryServicesImpl.closeConnection(ConnectionQueryServicesImpl.java:537)
      org.apache.phoenix.query.ConnectionQueryServicesImpl.close(ConnectionQueryServicesImpl.java:649)
      org.apache.phoenix.jdbc.PhoenixDriver.close(PhoenixDriver.java:349)
      ...
      org.apache.phoenix.jdbc.PhoenixDriver.closeInstance(PhoenixDriver.java:138)
      org.apache.phoenix.jdbc.PhoenixDriver.access$000(PhoenixDriver.java:68)
      org.apache.phoenix.jdbc.PhoenixDriver$1$1.run(PhoenixDriver.java:94)
      java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
      java.util.concurrent.FutureTask.run(FutureTask.java:266)
      java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
      java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
      java.lang.Thread.run(Thread.java:750)
      [SUCCESS] Program finished successfully.

参考

Phoenix の詳細については、公式ドキュメントをご参照ください: