Java连接HBase的方法,包含Kerberos认证。
完整代码示例:

package com.example.hbase;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.io.compress.Compression.Algorithm;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.security.UserGroupInformation;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;public class HBaseClientUtil {private static final String TABLE_NAME = "test:test";private static final String CF_DEFAULT = "cf";/*** HBase 通用客户端Kerberos认证* @param resources 配置文件资源* @param krb5Conf krb5.conf文件路径* @param principal Kerberos用户主体,eg:xingweidong@BIGDATA.ZXXK.COM* @param keytabFile keytab文件路径* @return* @throws IOException*/public static Connection getHBaseConn(List<String> resources, String krb5Conf, String principal, String keytabFile) throws IOException {Configuration config = HBaseConfiguration.create();// 添加必要的配置文件 (hbase-site.xml, core-site.xml)for (int i = 0; i < resources.size(); i++) {config.addResource(new Path(resources.get(i)));}// Kerberos认证// 设置java安全krb5.confSystem.setProperty("java.security.krb5.conf", krb5Conf);// 设置用户主体(Principal)config.set("kerberos.principal" , principal);// 使用用户keytab文件认证config.set("keytab.file" , keytabFile);UserGroupInformation.setConfiguration(config);try {// 登录UserGroupInformation.loginUserFromKeytab(principal, keytabFile);} catch (IOException e) {e.printStackTrace();}// 创建连接return ConnectionFactory.createConnection(config);}/*** HBase2.2.0+ 客户端Kerberos认证 (未验证)* @param resources 配置文件资源* @param krb5Conf krb5.conf文件路径* @param principal Kerberos用户主体,eg:xingweidong@BIGDATA.ZXXK.COM* @param keytabFile keytab文件路径* @return* @throws IOException*/public static Connection getHBaseConn220(List<String> resources, String krb5Conf, String principal, String keytabFile) throws IOException {Configuration config = HBaseConfiguration.create();// 添加必要的配置文件 (hbase-site.xml, core-site.xml)for (int i = 0; i < resources.size(); i++) {config.addResource(new Path(resources.get(i)));}// 设置java安全krb5.conf (未验证是否需要此配置)System.setProperty("java.security.krb5.conf", krb5Conf);// Kerberos认证config.set("hbase.client.kerberos.principal", principal);config.set("hbase.client.keytab.file", keytabFile);// 创建连接return ConnectionFactory.createConnection(config);}public static void createOrOverwrite(Admin admin, HTableDescriptor table) throws IOException {if (admin.tableExists(table.getTableName())) {admin.disableTable(table.getTableName());admin.deleteTable(table.getTableName());}admin.createTable(table);}public static void createSchemaTables(Connection connection) throws IOException {try (Admin admin = connection.getAdmin()) {HTableDescriptor table = new HTableDescriptor(TableName.valueOf(TABLE_NAME));table.addFamily(new HColumnDescriptor(CF_DEFAULT).setCompressionType(Algorithm.NONE));System.out.print("Creating table. ");createOrOverwrite(admin, table);System.out.println(" Done.");}}public static void main(String... args) throws IOException {// 添加必要的配置文件 (hbase-site.xml, core-site.xml)List<String> resources = new ArrayList<String>() {{add("/home/xwd/ws/hbase/hbase-clientconfig/hbase-conf/core-site.xml");add("/home/xwd/ws/hbase/hbase-clientconfig/hbase-conf/hbase-site.xml");add("/home/xwd/ws/hbase/hbase-clientconfig/hbase-conf/hdfs-site.xml");}};String krb5Conf = "/home/xwd/ws/hbase/krb5/krb5.conf";String principal = "xingweidong@BIGDATA.ZXXK.COM";String keytabFile = "/home/xwd/ws/hbase/krb5/xingweidong.keytab";// HBase操作Connection connection = HBaseClientUtil.getHBaseConn(resources, krb5Conf, principal, keytabFile);createSchemaTables(connection);System.out.println(" Put data ");Table table = connection.getTable(TableName.valueOf("test:test"));try {Put put = new Put(Bytes.toBytes("hbase_client_test"));put.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("col"), Bytes.toBytes("hbase_loginUserFromKeytab"));table.put(put);} finally {// 关闭连接table.close();connection.close();}}
}

配置要点

依赖包

从目标环境中复制即可,包括hadoop和hbase两个服务的相关jar。
如果是CDH集群,复制 /opt/cloudera/parcels/CDH/jars目录下的jar即可,里面包含了所有CDH服务的jar包。

如果使用IntelliJ IDEA开发,可以快速添加外部依赖库,以cdh依赖包为例。在工程中创建目录 src/libs/cdh,将依赖包放入cdh目录,右键点击cdh目录,选择 Add as Library。

在pom.xml指定外部库,就不需要从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.example.bigdata</groupId><artifactId>devexample</artifactId><version>1.0-SNAPSHOT</version><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding><compilerArguments><extdirs>${basedir}/src/libs/cdh</extdirs><!--指定外部lib--></compilerArguments></configuration></plugin></plugins></build></project>

添加配置文件

添加配置文件,加载目标环境的配置项。
Java通过HBase Client连接HBase的时候,可以加载目标环境的配置文件,以获取正确的配置,比起在代码中显示地设置配置项,加载配置文件资源的方法能够获取完整的目标环境配置,可以减少错误和精简代码。
主要配置文件是hbase-site.xmlcore-site.xml,这里还添加了 hdfs-site.xml,为了避免缺少配置。这三个文件都是HBase的客户端配置下的文件。
获取HBase客户端配置的通用方式是从HBase的配置目录中获取。如果使用Cloudera Manager管理HBase,可以从Cloudera Manager中的HBase服务下载客户端配置:操作 -> 下载客户端配置

Kerberos认证

如果HBase启用了Kerberos,在客户端访问时需要进行Kerberos认证,认证的方法有两种:

1、HBase通用客户端Kerberos认证。

2、HBase2.2.0+客户端Kerberos认证。从HBase 2.2.0开始支持的认证方法。

在 2.2.0 版本之前,客户端环境必须通过kinit命令从 KDC 或 keytab 登录到 Kerberos,然后才能与 HBase 集群进行通信。

从 2.2.0 开始,客户端可以在hbase-site.xml中指定以下配置:

<property><name>hbase.client.keytab.file</name><value>/local/path/to/client/keytab</value>
</property><property><name>hbase.client.keytab.principal</name><value>foo@EXAMPLE.COM</value>
</property>

然后,应用程序可以自动执行登录和凭据续订作业,而不会受到客户端干扰。

它是可选功能,客户端升级到 2.2.0,只要保持hbase.client.keytab.filehbase.client.keytab.principal未设置,它仍然可以保留旧版本中的登录和凭证更新逻辑。

请注意,如果客户端和服务器端站点文件中的hbase.security.authentication不匹配,则客户端将无法与群集通信。

HBase通用客户端Kerberos认证

示例代码:

/*** HBase 通用客户端Kerberos认证* @param resources 配置文件资源* @param krb5Conf krb5.conf文件路径* @param principal Kerberos用户主体,eg:xingweidong@BIGDATA.ZXXK.COM* @param keytabFile keytab文件路径* @return* @throws IOException*/
public static Connection getHBaseConn(List<String> resources, String krb5Conf, String principal, String keytabFile) throws IOException {Configuration config = HBaseConfiguration.create();// 添加必要的配置文件 (hbase-site.xml, core-site.xml)for (int i = 0; i < resources.size(); i++) {config.addResource(new Path(resources.get(i)));}// Kerberos认证// 设置java安全krb5.confSystem.setProperty("java.security.krb5.conf", krb5Conf);// 设置用户主体(Principal)config.set("kerberos.principal" , principal);// 使用用户keytab文件认证config.set("keytab.file" , keytabFile);UserGroupInformation.setConfiguration(config);try {// 登录UserGroupInformation.loginUserFromKeytab(principal, keytabFile);} catch (IOException e) {e.printStackTrace();}// 创建连接return ConnectionFactory.createConnection(config);
}

这个方法的核心是在代码中使用UserGroupInformation.loginUserFromKeytab() 进行Kerberos认证,主要配置说明:

配置 说明
java.security.krb5.conf krb5.conf文件路径。该文件从目标集群下载,文件在服务器的默认路径:/etc/krb5.conf。
keytab.file 用户的keytab文件,使用keytab文件可以避免交互式输入密码。
kerberos.principal Kerberos用户主体名。
UserGroupInformation.loginUserFromKeytab 使用keytab方式登录。

上述示例代码主要描述了Kerberos认证,但是在实际应用中,Kerberos keytab是需要自动更新的,否则一旦keytab过期,应用就会出现认证失败的问题。
通过分析UserGroupInformation的源码,发现了启用keytab自动更新的配置,主要源码如下:

private static synchronized void initialize(Configuration conf, boolean overrideNameRules) {authenticationMethod = SecurityUtil.getAuthenticationMethod(conf);if (overrideNameRules || !HadoopKerberosName.hasRulesBeenSet()) {try {HadoopKerberosName.setConfiguration(conf);} catch (IOException var7) {throw new RuntimeException("Problem with Kerberos auth_to_local name configuration", var7);}}try {kerberosMinSecondsBeforeRelogin = 1000L * conf.getLong("hadoop.kerberos.min.seconds.before.relogin", 60L);} catch (NumberFormatException var6) {throw new IllegalArgumentException("Invalid attribute value for hadoop.kerberos.min.seconds.before.relogin of " + conf.get("hadoop.kerberos.min.seconds.before.relogin"));}kerberosKeyTabLoginRenewalEnabled = conf.getBoolean("hadoop.kerberos.keytab.login.autorenewal.enabled", false);if (!(groups instanceof UserGroupInformation.TestingGroups)) {groups = Groups.getUserToGroupsMappingService(conf);}UserGroupInformation.conf = conf;if (metrics.getGroupsQuantiles == null) {int[] intervals = conf.getInts("hadoop.user.group.metrics.percentiles.intervals");if (intervals != null && intervals.length > 0) {int length = intervals.length;MutableQuantiles[] getGroupsQuantiles = new MutableQuantiles[length];for(int i = 0; i < length; ++i) {getGroupsQuantiles[i] = metrics.registry.newQuantiles("getGroups" + intervals[i] + "s", "Get groups", "ops", "latency", intervals[i]);}metrics.getGroupsQuantiles = getGroupsQuantiles;}}}

其中的kerberosKeyTabLoginRenewalEnabled这个配置就是keytab自动更新的开关了,默认值为false,我们可以通过在应用代码中设置为true,来启用这个功能,示例代码如下:

// 启用keytab renewal
config.set("hadoop.kerberos.keytab.login.autorenewal.enabled", "true");

HBase2.2.0+客户端Kerberos认证

从HBase2.2.0版本开始,支持了一种新的Kerberos认证方法,只需要添加两个客户端配置,HBase会自动处理认证登录和凭证更新。

Hbase官方API org.apache.hadoop.hbase.client.ConnectionFactory 的说明如下:

Since 2.2.0, Connection created by ConnectionFactory can contain user-specified kerberos credentials if caller has following two configurations set:

  • hbase.client.keytab.file, points to a valid keytab on the local filesystem
  • hbase.client.kerberos.principal, gives the Kerberos principal to use

By this way, caller can directly connect to kerberized cluster without caring login and credentials renewal logic in application.

示例代码:(未验证)

/*** HBase2.2.0+ 客户端Kerberos认证 (未验证)* @param resources 配置文件资源* @param krb5Conf krb5.conf文件路径* @param principal Kerberos用户主体,eg:xingweidong@BIGDATA.ZXXK.COM* @param keytabFile keytab文件路径* @return* @throws IOException*/
public static Connection getHBaseConn220(List<String> resources, String krb5Conf, String principal, String keytabFile) throws IOException {Configuration config = HBaseConfiguration.create();// 添加必要的配置文件 (hbase-site.xml, core-site.xml)for (int i = 0; i < resources.size(); i++) {config.addResource(new Path(resources.get(i)));}// 设置java安全krb5.conf (未验证是否需要此配置)System.setProperty("java.security.krb5.conf", krb5Conf);// Kerberos认证config.set("hbase.client.kerberos.principal", principal);config.set("hbase.client.keytab.file", keytabFile);// 创建连接return ConnectionFactory.createConnection(config);
}

我使用的是CDH6.3.2,HBase版本是2.1.0,验证发现使用这两个配置项进行连接HBase是无法成功的,但是在Spark Streaming中使用这个配置可以成功将数据写入HBase,比较奇怪,也许有哪个地方不对。

获取keytab文件

使用目标用户登录gateway01.bigdata.zxxk.com主机,例如xingweidong,执行以下命令:

ipa-getkeytab -s utility1.bigdata.zxxk.com -p xingweidong@BIGDATA.ZXXK.COM -k ./xingweidong.keytab --password

输入密码即可获取keytab文件。

参数说明

参数 说明 示例值
-s FreeIPA服务端主机名 utility1.bigdata.zxxk.com
-p 用户主体,注意加上域名 xingweidong@BIGDATA.ZXXK.COM
-k keytab文件存储目录 ./xingweidong.keytab
–password 使用密码

问题记录

Server not found in Kerberos database

报错


Caused by: javax.security.sasl.SaslException: Call to worker03.bigdata.zxxk.com/10.111.116.225:16020 failed on local exception: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Server not found in Kerberos database (7) - LOOKING_UP_SERVER)] [Caused by javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Server not found in Kerberos database (7) - LOOKING_UP_SERVER)]]...
Caused by: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Server not found in Kerberos database (7) - LOOKING_UP_SERVER)]...
Caused by: GSSException: No valid credentials provided (Mechanism level: Server not found in Kerberos database (7) - LOOKING_UP_SERVER)...
Caused by: KrbException: Server not found in Kerberos database (7) - LOOKING_UP_SERVER...
Caused by: KrbException: Identifier doesn't match expected value (906)...

问题:调用worker03.bigdata.zxxk.com/10.111.116.225:16020失败,在Kerberos数据库没有找到服务。

分析

查看krb5kdc.log,发现:

Aug 08 09:56:41 utility1.bigdata.zxxk.com krb5kdc[11263](info): TGS_REQ (4 etypes {18 17 16 23}) 10.111.127.23: LOOKING_UP_SERVER: authtime 0,  hbase_zxxk_user@BIGDATA.ZXXK.COM for hbase/10.111.116.225@BIGDATA.ZXXK.COM, Server not found in Kerberos database

kerberos在数据库中无法找到服务:hbase/10.111.116.225@BIGDATA.ZXXK.COM
但是kerberos数据库中存在服务:hbase/worker03.bigdata.zxxk.com@BIGDATA.ZXXK.COM
理论上,应该使用 hbase/worker03.bigdata.zxxk.com@BIGDATA.ZXXK.COM 访问hbase,但是不知道是哪个环节搞错了,所以无法正确访问hbase。

解决

hbase客户端相关的配置如下:

<property><name>hbase.regionserver.kerberos.principal</name><value>hbase/_HOST@BIGDATA.ZXXK.COM</value>
</property>

这本案例中,正常来说,_HOST 会被替换为 worker03.bigdata.zxxk.com,但是根据结果来看,_HOST 被替换成 10.111.116.225 了。
经分析,替换错误的原因是DNS解析错误,只要在网络配置中配置正确的DNS服务即可解决。
在本案例中,配置DNS服务:114.114.114.114 和 8.8.8.8 ,可以正常访问HBase。

Java连接HBase相关推荐

  1. java连接Hbase数据库

    java连接Hbase数据库 如果是是连接机群上的Hbase服务,需要提前将相关的几个xml文件存放在本地的编程目录下,否则开发端无法获取机群信息及授权: hdfs-site.xml core-sit ...

  2. java连接hbase时出现....is accessible from more than one module:

    今天在用java程序连接hbase时,出现错误,The package org.apache.hadoop.hbase is accessible from more than one module: ...

  3. 在Java连接hbase时出现的问题

    问题1: java.net.ConnectException: Connection refused: no further information zookeeper.ClientCnxn: Ses ...

  4. JAVA连接hbase伪分布失败_hbase伪分布安装配置

    hbase.rootdir --hbase持久保存的目录 hdfs:192.168.8.101:9000/hbase hbase.cluster.distributed --是否是分布式 true h ...

  5. Java连接HBASE数据库,创建一个表,删除一张表,修改表,输出插入,修改,数据删除,数据获取,显示表信息,过滤查询,分页查询,地理hash

    准备工作 1.创建Java的Maven项目 创建好的目录结构如下: 另外注意junit的版本,最好不要太高,最开始笔者使用的junit4.12的,发现运行的时候会报错.最后把Junit的版本改成4.7 ...

  6. JDBC——java连接mysql、hive、hbase教程

    JDBC模板 一.准备工作 1.1.创建Maven工程 1.2.修改pom文件 1.3.修改Project Structure 1.4.修改Settings 1.5.资源文件夹 二.Java连接mys ...

  7. hbase原理与实践_JAVA连接HBase客户端及HBase写入数据和读取数据原理解析

    JAVA连接HBase客户端 接着上篇文章进行代码的实践,从JAVA 客户端对 HBase的客户端进行一系列操作 工具类:HbaseUtil 静态代码块一次性创建连接对象 并赋值 返回连接对象 Con ...

  8. 【Hbase】第三章——Hbase的Shell操作与Java连接

    文章目录 任务 1.基本操作 1.1 进入客户端 1.2 namespace 1.3 DDL 1.4 DML 2. JavaApi连接Hbase 2.1 配置maven 2.2 配置log4j.pro ...

  9. java hbase创建_hadoop组件介绍及python 连接Hbase

    Ambari Apache Ambari是一种基于Web的工具,支持Hadoop集群的供应.管理和监控.是Apache顶级开源项目之一,由Hortonworks公司开源. Ø 官方网站地址: http ...

  10. python链接hbase模块_HBase实战(1):使用Python连接Hbase数据库

    来源于 https://blog.csdn.net/duan_zhihua/java/article/details/80622166 使用Python连接Hbase数据库 1,Hbase下载. 下载 ...

最新文章

  1. Getting Started with OpenCV
  2. 线程 、进程、协程 三者区别
  3. XML-RPC远程方法调用
  4. abiword Namespace List
  5. 线程,进程,并发,并行
  6. 安装meme_我见过的最好JavaScript Meme,详细说明了
  7. 使Android 自带SDK 完美支持HTML5 之 html5webview
  8. 接口,实现类,对象方法的调用关系.(查看程序输出)
  9. rsyslog-mysql_04-Log rsyslog-mysql loganalyzer
  10. chrome浏览器加载css、js等静态资源文件的坑
  11. 最小生成树——贪心算法
  12. Windows下安装JanusGraph(踩坑记录)
  13. U盘复制东西时显示:磁盘被写保护,请去掉写保护或使用另一张磁盘的解决方法。
  14. 支付系列-对接支付宝支付
  15. 基于TQ2440的SPI驱动学习(OLED)
  16. 基于WPS的在线编辑服务【.net Core 3.1】
  17. 100个深度图像分割算法,纽约大学UCLA等最新综述论文
  18. 【Lesson 4】 和弦的大小增减属
  19. Win10隐藏状态栏图标的方法
  20. 一文读懂IBIS模型

热门文章

  1. matlab解三角函数方程某值附近,matlab解三角函数已知参数方程
  2. 物联网可靠连接——PLC-IOT电力线载波通讯
  3. 现代通信技术课程小结
  4. 软考笔记——2.1进程管理、同步互斥、死锁、线程
  5. 计算机鼠标左右键作用,win7电脑鼠标右键有什么功能和作用
  6. 封玩家IP和机器码以及解开被封的教程
  7. 《如何让你爱的人爱上你》第一部分:第一印象
  8. wifi6无线网卡驱动linux,linux2.6.8内核装intel wifi link 5100无线网卡驱动的问题?
  9. 思科模拟器交换机路由器常用命令
  10. android listview 刷新 闪烁,listview刷新 怎样防止Listview刷新闪烁