Todos os produtos
Search
Central de documentação

E-MapReduce:Phoenix

Última atualização: Jul 10, 2026

O Apache Phoenix é uma camada SQL construída sobre o HBase que permite usar SQL padrão para consultar e gerenciar dados armazenados no HBase.

Pré-requisitos

Crie um cluster DataServing ou Custom com os services Phoenix e HBase selecionados. Para mais informações, consulte Criar um cluster.

Usar o Phoenix pela linha de comando

  1. Conecte-se ao cluster por SSH. Para mais informações, consulte Fazer logon em um cluster.

  2. Execute o comando a seguir para abrir a ferramenta de linha de comando do Phoenix.

    /opt/apps/PHOENIX/phoenix-current/bin/sqlline.py
  3. Use SQL para consultar dados. As operações comuns incluem:

    • Criar uma tabela

      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)
      );
    • Inserir dados

      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');
    • Consultar dados

      SELECT * FROM example;

      A consulta retorna a seguinte saída:

      +--------+-------------+------------+
      | MY_PK  | FIRST_NAME  | LAST_NAME  |
      +--------+-------------+------------+
      | 100    | Jack        | Ben        |
      | 200    | Jack3       | Ben3       |
      +--------+-------------+------------+
    • Excluir a tabela

      DROP TABLE IF EXISTS example;

Conectar-se ao Phoenix usando JDBC

Configurar a dependência do Maven

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

O valor de ${phoenix.version} deve corresponder à versão do Phoenix no cluster.

Exemplo de código

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();
    }
}

Conectar-se ao Phoenix com Kerberos via JDBC

Se o cluster usar autenticação Kerberos, esta seção explica como escrever um cliente JDBC para conectar-se com segurança ao service Phoenix em um cluster EMR com Kerberos ativado. O cliente utiliza uma URL JDBC com informações de principal e keytab para autenticação e executa operações básicas de DDL e DML para verificar a conexão.

Etapa 1: Preparar o ambiente e as credenciais

Antes de escrever o código, configure o ambiente e crie credenciais Kerberos no nó mestre do cluster.

  1. Conecte-se ao nó mestre por SSH. Para mais informações, consulte Fazer logon em um cluster.

  2. Identifique o realm Kerberos.

    Cada cluster com Kerberos ativado possui um realm exclusivo.

    Execute o comando a seguir para obter o realm Kerberos. Anote o realm para uso posterior.

    cat /etc/krb5.conf | grep default_realm

    Exemplo de resposta:

    default_realm = EMR.C-4FC5FDDE3759****.COM
  3. Crie um principal de cliente.

    Um principal é a identidade exclusiva de um cliente no Kerberos. Crie um principal para a aplicação Java.

    1. No nó mestre, execute o comando a seguir para usar a ferramenta kadmin.local:

      sudo kadmin.local
    2. Na sessão interativa do kadmin.local, execute o comando a seguir para criar o principal:

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

      Quando solicitado, defina e memorize uma senha para o principal. Embora o arquivo keytab permita logon sem senha, essa senha ainda pode ser necessária em alguns casos.

  4. Exporte o arquivo keytab.

    1. Na ferramenta kadmin.local, execute o comando a seguir para exportar o arquivo keytab:

      xst -k /tmp/phoenix_client.keytab phoenix_client@EMR.C-4FC5FDDE3759****.COM
    2. Execute o comando a seguir para sair do kadmin.local:

      exit
      Importante
      • Permissões: Verifique se o usuário que executa o programa Java tem permissões de leitura no arquivo keytab.

      • Distribuição: Se o programa Java for executado em outra máquina, copie com segurança o arquivo phoenix_client.keytab e o arquivo /etc/krb5.conf para ela. Garanta que estejam em um caminho acessível à aplicação.

Etapa 2: Escrever e empacotar a aplicação

  • Método 1: Usar um arquivo JAR pré-compilado (verificação rápida)

    hbase-phoenix-kerberos-1.0-SNAPSHOT.jar

  • Método 2: Compilar e empacotar manualmente (recomendado para produção)

    Use o exemplo de código a seguir para compilação e empacotamento manuais.

    Exemplo de código principal (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;
    /**
     * A client that connects to a Kerberos-secured Phoenix cluster using JDBC.
     * All connection parameters are provided through a complete JDBC URL passed from the command line.
     */
    public class PhoenixKerberosDemo {
        /**
         * The main entry point for the application.
         *
         * @param args Command-line arguments. The program expects one argument: the complete Phoenix JDBC URL.
         */
        public static void main(String[] args) {
            // --- 1. Validate command-line input: Expect one argument, the 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); // Exit with an error code
            }
            String jdbcUrl = args[0];
            System.out.println("Attempting to connect to Phoenix...");
            System.out.println("Using JDBC URL: " + jdbcUrl);
            try {
                // --- 2. Load the Phoenix driver ---
                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. Use a try-with-resources statement to establish a connection and execute SQL. This syntax automatically closes resources. ---
            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) {
                // Catch SQL exceptions and provide helpful troubleshooting tips
                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.");
        }
    }
    

    Configuração do 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 Compiler  -->
                <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>

Etapa 3: Executar a aplicação

  1. Escolha um ambiente de execução.

    Selecione um dos dois ambientes de execução a seguir:

    • Executar em um nó do cluster (recomendado):

      • Os nós do cluster já possuem as bibliotecas de dependência necessárias do Hadoop, HBase e Phoenix pré-instaladas. Portanto, nenhuma configuração adicional é necessária. A conectividade de rede também está disponível por padrão, oferecendo um ambiente completo e estável.

      • Ideal para: verificação rápida e testes durante desenvolvimento e depuração.

    • Executar fora do cluster

      Para executar o programa fora do cluster, atenda às seguintes condições:

      • Conectividade de rede: garanta a conectividade entre a máquina que executa o programa e os nós ZooKeeper, HBase Master e RegionServer do cluster.

      • Configuração do Kerberos: copie o arquivo krb5.conf do cluster e o arquivo keytab gerado para a máquina onde o programa será executado.

      • Gerenciamento de dependências: o classpath do comando de execução deve incluir todos os arquivos JAR de dependência necessários dos clientes Hadoop, HBase e Phoenix. Isso geralmente é mais complexo do que executar em um nó do cluster. Recomendamos o uso de ferramentas como Maven ou Gradle para gerenciar as dependências.

  2. Execute o script.

    O script kerberos-phoenix.sh a seguir inclui todas as configurações necessárias. Edite-o e execute-o conforme necessário.

    #!/bin/bash
    # ======================= 1. User configuration (modify based on your environment) =======================
    # Directory for Hadoop and HBase configuration files
    HADOOP_CONF_DIR="/etc/taihao-apps/hadoop-conf"
    HBASE_CONF_DIR="/etc/taihao-apps/hbase-conf"
    # Path to the Phoenix client JAR file. Using a symbolic link is a best practice to stay resilient to version changes.
    # First, confirm this file exists by using `ls -l /opt/apps/PHOENIX/phoenix-current/`. This path may need to be modified for different versions.
    PHOENIX_JAR="/opt/apps/PHOENIX/phoenix-current/phoenix-client-lite-hbase-2.6.jar"
    # Your application's JAR file name.
    YOUR_JAR_FILE="hbase-phoenix-kerberos-1.0-SNAPSHOT.jar"
    # Path to the Kerberos configuration file.
    KRB5_CONF_PATH="/etc/krb5.conf"
    # --- [Core] JDBC URL configuration ---
    # Format: jdbc:phoenix:[ZK Address]:[ZK Port]:[HBase ZNode]:[Principal]:[Absolute Keytab Path]
    # Replace the ZK address, REALM, and keytab path below with your actual information.
    ZK_QUORUM="master-1-1" # If there are multiple ZooKeeper nodes, separate them with commas, for example, "zk1,zk2,zk3"
    ZK_PORT="2181"
    HBASE_ZNODE="/hbase" # For a secure cluster, it might be /hbase-secure
    PRINCIPAL="phoenix_client@EMR.C-4FC5FDDE3759****.COM" # Replace with your principal
    KEYTAB_PATH="/tmp/phoenix_client.keytab" # Absolute path to the keytab file
    JDBC_URL="jdbc:phoenix:${ZK_QUORUM}:${ZK_PORT}:${HBASE_ZNODE}:${PRINCIPAL}:${KEYTAB_PATH}"
    # =================================================================================
    # ======================= 2. Execution (usually no changes needed) =================================
    echo "================================================="
    echo "Starting Phoenix Kerberos JDBC Demo..."
    echo "Using JDBC URL: ${JDBC_URL}"
    echo "================================================="
    # Build the classpath. Order: current directory -> configuration directories -> your JAR -> dependency JARs
    # `hbase classpath` automatically loads core Hadoop/HBase dependencies
    CLASS_PATH=".:${HADOOP_CONF_DIR}:${HBASE_CONF_DIR}:${YOUR_JAR_FILE}:${PHOENIX_JAR}:$(hbase classpath)"
    # Execute the Java program
    java -cp "${CLASS_PATH}" \
         -Djava.security.krb5.conf="${KRB5_CONF_PATH}" \
         PhoenixKerberosDemo "${JDBC_URL}"
    # Check the exit code
    if [ $? -eq 0 ]; then
        echo -e "\n[SUCCESS] Program finished successfully."
    else
        echo -e "\n[FAILED] Program terminated with an error."
    fi
    # =================================================================================
    1. Faça upload do arquivo JAR empacotado na Etapa 2 e do script kerberos-phoenix.sh para um diretório de destino no nó mestre.

    2. Execute o comando a seguir para conceder permissões de execução ao script:

      chmod +x kerberos-phoenix.sh
    3. Execute o comando a seguir para iniciar o script:

      ./kerberos-phoenix.sh

      Exemplo de saída:

      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.

Referências

Para mais informações sobre o Phoenix, consulte a documentação oficial: