专栏首页大数据实战演练基于Kerberos环境下,使用Java连接操作Hive

基于Kerberos环境下,使用Java连接操作Hive

每一个成功人士的背后,必定曾经做出过勇敢而又孤独的决定。

放弃不难,但坚持很酷~

本文主要介绍基于 Kerberos 环境下,如何使用 Java 远程连接 Hive 。

一、创建自定义 Principal 与 keytab

虽然可以使用 Hive 服务本身的 Principal 与 keytab 来连接 Hive ,但使用服务本身的 principal 不具有普遍性,所以还是建议使用自定义的 Principal 。

有两种场景,一种是在 Kerberos KDC 所在的主机上,一种是非 Kerberos KDC 所在的主机。以下分这两种场景来创建 Principal 和 Keytab 。

在 kerberos kdc 所在的主机上,在 root 用户下使用 kadmin.local 进入:

# 为linux增加liuyzh用户
useradd liuyzh
# 创建principal,randkey参数会自动生成随机密码
addprinc -randkey liuyzh/node71.xdata@EXAMPLE.COM
# 验证principal是否被创建
getprinc liuyzh/node71.xdata@EXAMPLE.COM
# 为liuyzh/node71.xdata@EXAMPLE.COM创建principal
ktadd -norandkey -k /etc/security/keytabs/liuyzh.service.keytab liuyzh/node71.xdata@EXAMPLE.COM
# 验证
kinit -kt /etc/security/keytabs/liuyzh.service.keytab liuyzh/node71.xdata@EXAMPLE.COM
# 查看kerberos认证缓存
klist
# 此时liuyzh用户就代理了root用户操作。

在非 kerberos kdc 主机上,在 root 用户下使用 kadmin 进入:

# 在非 kerberos kdc 所在的主机,首先需要验证身份:kinit xxx/admin@EXAMPLE.COM,输入明文密码
kinit admin/admin@EXAMPLE.COM
# 输入明文密码,例如:123456
# 创建principal,randkey参数会自动生成随机密码
addprinc -randkey liuyzh/node72.xdata@EXAMPLE.COM 
# 为liuyzh/node72.xdata@EXAMPLE.COM创建keytab
ktadd -k /etc/security/keytabs/liuyzh.service.keytab liuyzh/node72.xdata@EXAMPLE.COM
# 验证
kinit -kt liuyzh.service.keytab liuyzh/node72.xdata@EXAMPLE.COM
klist
# 此时liuyzh用户就代理了root用户操作。

注意:keytab 文件一般要配置执行用户的只读权限,还要注意记得配置 Windows 的 主机名与 ip 映射。

二、拷贝 krb5.conf 与 keytab 文件

Java 程序会用到 krb5.ini 和对应的 principal 文件,其中 krb5.ini 文件的内容是 linux 上 /etc/krb5.conf 文件里面的部分内容,内容如下所示:

[libdefaults]
  renew_lifetime = 7d
  forwardable = true
  default_realm = EXAMPLE.COM
  ticket_lifetime = 24h
  dns_lookup_realm = false
  dns_lookup_kdc = false
  # default_ccache_name = /tmp/krb5cc_%{uid}
  #default_tgs_enctypes = aes des3-cbc-sha1 rc4 des-cbc-md5
  #default_tkt_enctypes = aes des3-cbc-sha1 rc4 des-cbc-md5

[realms]
  EXAMPLE.COM = {
    admin_server = node71.xdata
    kdc = node71.xdata
  }

keytab 文件为上边创建 liuyzh/node71.xdata@EXAMPLE.COM 对应的 liuyzh.service.keytab 。principal 的主体部分(liuyzh)为代理用户,liuyzh.service.keytab 为密钥文件。

将 krb5.ini 和 keytab 文件从 Linux 上拷贝到项目工程的根目录下。

三、Java 代码示例

1、添加 pom 依赖:

<!-- Hive2.1.0 -->
<dependency>
    <groupId>org.apache.hive</groupId>
    <artifactId>hive-jdbc</artifactId>
    <version>2.1.0</version>
</dependency>

2、jdbc url 的两种写法

通过 jdbc 来连接 Hive ,jdbc 的写法有两种:

  • 通过指定 HiveServer2 的端口
jdbc:hive2://node72.xdata:10000;principal=hive/node72.xdata@EXAMPLE.COM
  • 通过指定 Zookeeper url
jdbc:hive2://node71.xdata:2181,node72.xdata:2181,node73.xdata:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2;principal=hive/node72.xdata@EXAMPLE.COM

基于 Kerberos 环境的 Hive jdbc url 需要特别注意,格式如下:

jdbc:hive2://xxx;principal=<Server_Principal_of_HiveServer2>

这里的 principal 是固定不变的,其指的 hive 服务所对应的 principal ,而不是用户所对应的 principal 。

3、初始化连接代码

初始化连接的逻辑里面,需要指定如下配置:

  • hadoop.security.authentication
  • java.security.krb5.conf
  • 登陆时指定 principal 和 keytab

具体代码如下:

public void getConnection() {
    Configuration conf = new Configuration();
    conf.set("hadoop.security.authentication", "Kerberos");
    System.setProperty("krb5_ini", System.getProperty("user.dir") + "\\krb5\\krb5.ini");
    System.setProperty("hive_keytab", System.getProperty("user.dir") + "\\krb5\\liuyzh.service.keytab");
    System.setProperty("java.security.krb5.conf", System.getProperty("krb5_ini"));
    UserGroupInformation.setConfiguration(conf);
    try {
        UserGroupInformation.loginUserFromKeytab("liuyzh/node71.xdata@EXAMPLE.COM", System.getProperty("hive_keytab"));
    } catch (IOException e) {
        e.printStackTrace();
    }
    try {
        // 使用hive用户登陆
        conn = DriverManager.getConnection(url2);
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

4、列举数据库内的所有表

    private static String url = "jdbc:hive2://node72.xdata:10000;principal=hive/node72.xdata@EXAMPLE.COM";
    private static String url2 = "jdbc:hive2://node71.xdata:2181,node72.xdata:2181,node73.xdata:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2;principal=hive/node72.xdata@EXAMPLE.COM";
    private static Connection conn = null;
    private static PreparedStatement ps = null;
    private static ResultSet rs = null;

    /*
     * @description: 通过jdbc连接hive2
     */
    @Test
    @Before
    public void getConnection() {
        Configuration conf = new Configuration();
        conf.set("hadoop.security.authentication", "Kerberos");
        System.setProperty("krb5_ini", System.getProperty("user.dir") + "\\krb5\\krb5.ini");
        System.setProperty("hive_keytab", System.getProperty("user.dir") + "\\krb5\\liuyzh.service.keytab");
        System.setProperty("java.security.krb5.conf", System.getProperty("krb5_ini"));
        UserGroupInformation.setConfiguration(conf);
        try {
            UserGroupInformation.loginUserFromKeytab("liuyzh/node71.xdata@EXAMPLE.COM", System.getProperty("hive_keytab"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            // 使用hive用户登陆
            conn = DriverManager.getConnection(url2);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * @description: 进入数据库,展示所有表
     */
    @Test
    public void showTables() {
        try {
            // 进入default数据库
            ps = conn.prepareStatement("use default");
            ps.execute();
            // 展示所有表
            rs = ps.executeQuery("show tables");
            // 处理结果集
            while (rs.next()) {
                System.out.println(rs.getString(1));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * @description: 关闭连接
     */
    @Test
    @After
    public void closeConnect() {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (ps != null) {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

四、总结

其实,基于kerberos连接Hive只需要改动初始化连接部分就可以,需要准备:

  • 设置 principal 和相对应的 keytab
  • 指定 java.security.krb5.conf 配置
  • 指定 hadoop.security.authentication 为 kerberos 认证

其它代码还是 外甥打灯笼 -- 照旧 。

更多的基于kerberos的hive操作,已经上传到 github ,地址为:

https://github.com/841809077/hdp2project/blob/master/src/main/java/com/hdp2/project/hive/HiveOperateTest.java

本文分享自微信公众号 - 大数据实战演练(gh_f942bfc92d26),作者:CREATE 17

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-08-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 新建spring boot项目

    java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized...

    create17
  • Java 实现 FastDFS 实现文件的上传、下载、删除

    上述方法就是将图片的 base64 码进行转换并上传到了 fastdfs 上。以下是可复制粘贴的源码:

    create17
  • HDFS ACL权限设置

    今天主要给大家说一下HDFS文件权限的问题。当一个普通用户去访问HDFS文件时,可能会报Permission denied的错误。那么你会怎么做呢?

    create17
  • 我对垂直搜索引擎的几点认识

    据说垂直搜索现在很热,那么什么是垂直搜索呢,下面是我的几点认识,欢迎大家讨论。

    田春峰-JCJC错别字检测
  • 一个直男产品经理指导程序员给老婆买面膜的故事

    今天的故事是这样的:单身直男产品经理为了让准爸爸程序员安心做需求,帮队友找来一条安抚孕妇情绪的妙计。

    用户1569917
  • 深度学习|大师之作,必是精品

    1neural networks and deep learning 这是一个非常经典的神经网络和深度学习的教程,有完整的免费的电子书,网址如下: http:/...

    double
  • 详解ConcurrentHashMap及JDK8的优化

    由于HashMap在并发中会出现一些问题,所以JDK中提供了并发容器ConcurrentHashMap。有关HashMap并发中的问题和原理,强烈建议查看这篇文...

    全菜工程师小辉
  • python包urllib名称

    经查询,在python3.5版本中是使用urllib.request,而在python2.7中则是urllib2

    努力在北京混出人样
  • 解决keras GAN训练是loss不发生变化,accuracy一直为0.5的问题

    常用于二分类问题,当然也可以用于多分类问题,通常需要在网络的最后一层添加sigmoid进行配合使用,其期望输出值(target)需要进行one hot编码,另外...

    砸漏
  • SpringBoot整合Scheduled(定时任务器)

      Scheduled 定时任务器:是Spring3.0以后自带的一个定时任务器。我们来看下在SpringBoot中我们怎么使用

    用户4919348

扫码关注云+社区

领取腾讯云代金券