Apache Phoenix は HBase 上に構築された SQL レイヤーであり、標準 SQL を使用して HBase に保存されたデータをクエリおよび管理できます。
前提条件
Phoenix および HBase サービスを選択して、DataServing クラスターまたはカスタムクラスターを作成済みであること。詳細については、「クラスターの作成」をご参照ください。
コマンドラインからの Phoenix の使用
-
SSH を使用してクラスターに接続します。詳細については、「クラスターへのログイン」をご参照ください。
-
次のコマンドを実行して、Phoenix コマンドラインツールを使用します。
/opt/apps/PHOENIX/phoenix-current/bin/sqlline.py -
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 認証情報を作成します。
-
SSH を使用してマスターノードに接続します。詳細については、「クラスターへのログイン」をご参照ください。
-
Kerberos レルムを特定します。
Kerberos が有効な各クラスターには、一意のレルムがあります。
次のコマンドを実行して Kerberos レルムを取得します。後で使用するためにレルムを記録しておきます。
cat /etc/krb5.conf | grep default_realm以下は応答例です。
default_realm = EMR.C-4FC5FDDE3759****.COM -
クライアントプリンシパルを作成します。
プリンシパルは、Kerberos におけるクライアントの一意の ID です。Java アプリケーション用にプリンシパルを作成する必要があります。
-
マスターノードで、次のコマンドを実行して
kadmin.localツールを使用します。sudo kadmin.local -
`kadmin.local` のインタラクティブなセッションで、次のコマンドを実行してプリンシパルを作成します。
addprinc phoenix_client@EMR.C-4FC5FDDE3759****.COMプロンプトが表示されたら、プリンシパルのパスワードを設定し、覚えておいてください。keytab ファイルを使用するとパスワードなしでログインできますが、場合によってはこのパスワードが必要になることがあります。
-
-
keytab ファイルをエクスポートします。
-
`kadmin.local` ツールで、次のコマンドを実行して keytab ファイルをエクスポートします。
xst -k /tmp/phoenix_client.keytab phoenix_client@EMR.C-4FC5FDDE3759****.COM -
次のコマンドを実行して `kadmin.local` を終了します。
exit重要-
権限:Java プログラムを実行するユーザーが keytab ファイルに対する読み取り権限を持っていることを確認してください。
-
配布: Java プログラムを別のマシンで実行する場合は、
phoenix_client.keytabファイルと/etc/krb5.confファイルをそのマシンに安全にコピーし、それらがアプリケーションがアクセスできるパスにあることを確認してください。
-
-
ステップ 2:アプリケーションの作成とパッケージング
-
方法 1:プリコンパイルされた JAR ファイルの使用 (クイック検証)
-
方法 2:手動でのコンパイルとパッケージング (本番環境に推奨)
手動でのコンパイルとパッケージングには、次のコード例を使用できます。
ステップ 3:アプリケーションの実行
-
実行環境を選択します。
次の 2 つの実行環境のいずれかを選択します:
-
クラスターノードでの実行 (推奨):
-
クラスターノードには、必要な Hadoop、HBase、および Phoenix の依存関係ライブラリがプリインストールされているため、追加の設定は不要です。ネットワーク接続もデフォルトで利用可能であり、完全で安定した環境を提供します。
-
最適な用途:開発およびデバッグ中の迅速な検証とテスト。
-
-
クラスター外での実行
プログラムをクラスター外で実行するには、次の条件が満たされていることを確認してください:
-
ネットワーク接続:プログラムを実行するマシンと、クラスターの ZooKeeper、HBase Master、および RegionServer ノードとの間のネットワーク接続を確保してください。
-
Kerberos 構成: クラスターの
krb5.confファイルと生成された keytab ファイルを、プログラムを実行するマシンにコピーします。 -
依存関係の管理:実行コマンドのクラスパスには、必要なすべての Hadoop、HBase、および Phoenix クライアントの依存関係 JAR ファイルを含める必要があります。これは通常、クラスターノードで実行するよりも複雑です。依存関係の管理には、Maven や Gradle などのツールを使用することを推奨します。
-
-
-
スクリプトを実行します。
以下の
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 # =================================================================================-
ステップ 2 でパッケージ化された JAR ファイルと
kerberos-phoenix.shスクリプトを、マスターノード上のターゲットディレクトリにアップロードします。 -
次のコマンドを実行して、スクリプトに実行権限を付与します。
chmod +x kerberos-phoenix.sh -
次のコマンドを実行して、スクリプトを実行します。
./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 の詳細については、公式ドキュメントをご参照ください: