如何使用Java连接Kerberos的Phoenix

简介: 如何使用Java连接Kerberos的Phoenix


文档编写目的

本文主要介绍如何使用Java代码访问Kerberos环境下的Phoenix5.0。

  1. 内容概述
  • 代码编写
  • 验证
  • 总结
  1. 测试环境
  • CM和CDH版本均为7.1.1
  • Phoenix版本为5.0.0
  • 集群已启用Kerberos

代码编写

1.1 集群环境

CM和CDH版本均为7.1.1

集群已启用Kerberos认证

使用Phoenix查看HBase表情况

phoenix-sqlline
!tables

1.2 编写Java代码

创建一个Maven工程pro-phoenix

添加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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.apress.phoenix</groupId>
    <artifactId>pro-phoenix</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <!--<phoenix.version>5.0.0-HBase-2.0</phoenix.version>-->
        <phoenix.version>5.0.0-HBase-2.0</phoenix.version>
        <hadoop.version>2.7.1</hadoop.version>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.apache.phoenix</groupId>
            <artifactId>phoenix-core</artifactId>
            <version>${phoenix.version}</version>
            <exclusions>
                <exclusion>
                    <artifactId>hadoop-auth</artifactId>
                    <groupId>org.apache.hadoop</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>hadoop-hdfs</artifactId>
                    <groupId>org.apache.hadoop</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <artifactId>hadoop-auth</artifactId>
            <groupId>org.apache.hadoop</groupId>
            <version>${hadoop.version}</version>
        </dependency>        
  <dependency>
            <artifactId>hadoop-hdfs</artifactId>
            <groupId>org.apache.hadoop</groupId>
            <version>${hadoop.version}</version>
        </dependency>
        <dependency>
            <artifactId>hadoop-common</artifactId>
            <groupId>org.apache.hadoop</groupId>
            <version>${hadoop.version}</version>
        </dependency>
     </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.0</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

新建Kerberos用户hbase/_HOST@HADOOP.COM,并导出keytab文件

kadmin.local
addprinc hbase/_HOST@HADOOP.COM
xst -norandkey -k hbasehost.keytab hbase/_HOST@HADOOP.COM

在项目工程目录下创建conf目录,并将krb5.conf和keytab文件拷贝到该目录下

hbase-site.xml文件拷贝到Maven工程下的resources目录下

在工程下创建测试类PhoenixKrbTest.java,代码如下:

package com.apress.phoenix.chapter3;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.log4j.Logger;
import org.apache.phoenix.jdbc.PhoenixConnection;
import java.io.IOException;
import java.sql.*;
public class PhoenixKrbTest {
    private static Logger log = Logger.getLogger(PhoenixKrbTest.class);
    /**
     * 获取连接
     */
    public Connection getConn() {
        // 连接hadoop环境,进行 Kerberos认证
        Configuration conf = new Configuration();
        conf.set("hadoop.security.authentication", "Kerberos");
        // linux 环境会默认读取/etc/nokrb.cnf文件,win不指定会默认读取C:/Windows/krb5.ini
        /*if (System.getProperty("os.name").toLowerCase().startsWith("win")) {
            System.setProperty("java.security.krb5.conf", "/conf/krb5.conf");
        }*/
        System.setProperty("java.security.krb5.conf", "conf/krb5.conf");
        UserGroupInformation.setConfiguration(conf);
        Connection conn = null;
        try {
            UserGroupInformation.loginUserFromKeytab("hbase/_HOST@HADOOP.COM", "conf/hbasehost.keytab");
            Class.forName("org.apache.phoenix.jdbc.PhoenixDriver");
            // kerberos环境下Phoenix的jdbc字符串为 jdbc:phoenix:zk:2181:/znode:principal:keytab
            String url = "jdbc:phoenix:cdp2.hadoop.com:2181:/hbase:hbase/_HOST@HADOOP.COM:conf/hbasehost.keytab";
            conn = DriverManager.getConnection(url).unwrap(PhoenixConnection.class);
        } catch (ClassNotFoundException e) {
            log.error(e.getMessage());
            e.printStackTrace();
        } catch (SQLException e1) {
            log.error(e1.getMessage());
            e1.printStackTrace();
        } catch (IOException e2) {
            log.error(e2.getMessage());
            e2.printStackTrace();
        }
        return conn;
    }
    /**
     * 对表执行操作
     * 通过phoenix 创建表、插入数据、索引、查询数据
     */
    public void operTable() {
        Connection conn = getConn();
        ResultSet rs = null;
        Statement stmt = null;
        try {
            stmt = conn.createStatement();
            stmt.execute("DROP TABLE if EXISTS testjdbc");
            stmt.execute("CREATE TABLE testjdbc (id INTEGER NOT NULL PRIMARY KEY, content VARCHAR)");
            // 创建二级索引
//            stmt.execute("create index test_idx on testjdbc(content)");
            // 循环插入数据
            for (int i = 1; i <= 100; i++) {
                stmt.executeUpdate("upsert INTO testjdbc VALUES (" + i + ",'The num is " + i + "')");
            }
            conn.commit();
            PreparedStatement statement = conn.prepareStatement("SELECT * FROM testjdbc limit 10");
            rs = statement.executeQuery();
            while (rs.next()) {
                log.info("-------------The num is ---------------" + rs.getInt(1));
                String id = rs.getString("id");
                String content = rs.getString("content");
                System.out.println("id = " + id + "; " + "content = " + content);
            }
        } catch (SQLException e) {
            log.error(e.getMessage());
            e.printStackTrace();
        } finally {
            closeRes(conn, stmt, rs);
        }
    }
    /**
     * 关闭资源
     *
     * @param conn
     * @param statement
     * @param rs
     */
    public void closeRes(Connection conn, Statement statement, ResultSet rs) {
        try {
            if (conn != null) {
                conn.close();
            }
            if (statement != null)
                statement.close();
            if (rs != null)
                rs.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        PhoenixKrbTest test = new PhoenixKrbTest();
        test.operTable();
    }
}

1.3 示例代码执行

在IDEA中运行编写好的代码,代码执行情况如下:

验证

kinit hbase
klist


Phoenix终端验证

登录Phoenix,查看表信息如下

phoenix-sqlline
!tables

如上所示,testjdbc表已被创建。

查看testjdbc表中数据

select * from testjdbc limit 10;

如上所示,与IDEA中查询的数据一致

HBase shell验证

登录HBase shell,查看当前已存在的表

hbase shell
list

查看表中数据

1. scan 'TESTJDBC',{LIMIT => 10}

如上所示,与IDEA以及Phoenix终端中查询数据一致。

总结

  • Kerberos环境下需要krb5.conf和keytab文件,并且需要在代码中执行principal。
  • Kerberos环境需要hbase-site.xml文件,只需将该文件放在项目工程下的resources目录下即可
  • 在访问HBase时,实际上是先访问的Zookeeper,所以代码中需要配置Zookeeper集群的url。
  • 访问Kerberos,JDK需要启用无限制强度加密,jdk1.8.0_160以上默认启用


相关实践学习
云数据库HBase版使用教程
&nbsp; 相关的阿里云产品:云数据库 HBase 版 面向大数据领域的一站式NoSQL服务,100%兼容开源HBase并深度扩展,支持海量数据下的实时存储、高并发吞吐、轻SQL分析、全文检索、时序时空查询等能力,是风控、推荐、广告、物联网、车联网、Feeds流、数据大屏等场景首选数据库,是为淘宝、支付宝、菜鸟等众多阿里核心业务提供关键支撑的数据库。 了解产品详情:&nbsp;https://cn.aliyun.com/product/hbase &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2天前
|
NoSQL Java MongoDB
java连接MongoDB
java连接MongoDB
|
2天前
|
数据采集 Java 关系型数据库
Java代码高效连接数据库
Java代码高效连接数据库
23 2
|
2天前
|
IDE 关系型数据库 MySQL
【Java+MySQL】前后端连接小白教程
【Java+MySQL】前后端连接小白教程
40 0
|
2天前
|
NoSQL Java API
Redis官方推荐的Java连接开发工具Jedis
Redis官方推荐的Java连接开发工具Jedis
|
2天前
|
监控 安全 Java
Java与物联网:连接与控制设备
Java与物联网:连接与控制设备
30 0
|
2天前
|
Linux Windows
FinalShell连接Linux虚拟机报错java.net.ConnectException: Connection timed out: connect(亲测有效)
FinalShell连接Linux虚拟机报错java.net.ConnectException: Connection timed out: connect(亲测有效)
214 0
|
2天前
|
前端开发 Java 应用服务中间件
【异常解决】java程序连接MinIO报错The request signature we calculated does not match the signature you provided.
【异常解决】java程序连接MinIO报错The request signature we calculated does not match the signature you provided.
15 0
|
2天前
|
SQL Java 关系型数据库
【JAVA基础篇教学】第十六篇:Java连接和操作MySQL数据库
【JAVA基础篇教学】第十六篇:Java连接和操作MySQL数据库
|
2天前
|
SQL Java 数据库连接
Java数据库编程实践:连接与操作数据库
Java数据库编程实践:连接与操作数据库
12 0
|
2天前
|
NoSQL Java 关系型数据库
Java基础教程(21)-Java连接MongoDB
【4月更文挑战第21天】MongoDB是开源的NoSQL数据库,强调高性能和灵活性。Java应用通过MongoDB Java驱动与之交互,涉及MongoClient、MongoDatabase、MongoCollection和Document等组件。连接MongoDB的步骤包括:配置连接字符串、创建MongoClient、选择数据库和集合。伪代码示例展示了如何建立连接、插入和查询数据。