Java代码访问华为中台MRS服务Hive数仓踩坑之旅

背景:

某大型国企总部要抽取地方公司的数据,总部和地方都是用的华为的数据中台。需要我们自己开发一个API接口,总部通过调用API接口抽取地方中台的数据。

存在的问题:

开发环境:

首先是开发环境的问题,因为总部和地方部署华为中台都是私有云,我没有私有云的环境,因此我是自己申请的公有云环境开发的。

另外需要注意华为MRS的hive为高可用,连接一律是需要通过zookeeper。

(1)网络问题:

申请华为公有云的MRS后一定要配置集群所在服务器ECS绑定公网IP。

(2)安全组问题(适用生产环境私有云):

修改绑定MRS的安全组,添加本机电脑或者服务器(或0.0.0.0任意IP)的2181、10000等端口的准入。

(3)配置公网IP与ECS服务器的别名(适用生产环境私有云):

因为是通过zookeeper连接hive,程序自动从zookeeper中拿到的其实是hive集群所在服务器的别名,因此需要对应公网IP与ECS服务器的别名。
在这里插入图片描述

生产环境:

生产环境中hive集群集成了kerberos安全认证,程序中需要添加安全认证代码。

(1)添加安全认证:

Kerberos安全认证示例代码如下:

System.setProperty("java.security.krb5.conf","/var/cqljgt_springboot/conf/krb5.conf");
org.apache.hadoop.conf.Configuration conf = new org.apache.hadoop.conf.Configuration();

if (isSecurityMode) {
    String userName = "cq_xxxx_xxxx";
    String userKeytabFile = "/var/cqljgt_springboot/conf/user.keytab";
    String krb5File = "/var/cqljgt_springboot/conf/krb5.conf";
    conf.set(HADOOP_SECURITY_AUTHENTICATION, "Kerberos");
    conf.set(HADOOP_SECURITY_AUTHORIZATION, "true");
    conf.addResource(new FileInputStream(new File("/var/cqljgt_springboot/conf/core-site.xml")));
    conf.addResource(new FileInputStream(new File("/var/cqljgt_springboot/conf/hivemetastore-site.xml")));
    conf.addResource(new FileInputStream(new File("/var/cqljgt_springboot/conf/hive-site.xml")));

    LoginUtil.setJaasConf("Client", userName, userKeytabFile);
    LoginUtil.setZookeeperServerPrincipal("zookeeper/hadoop");

    LoginUtil.login(userName, userKeytabFile, krb5File, conf);
}

其中LoginUtil来自华为官网示例代码:

https://github.com/huaweicloud/huaweicloud-mrs-example/blob/mrs-2.1/src/hive-examples/src/main/java/com/huawei/bigdata/security/LoginUtil.java

下面就是巨坑,这两行代码中的Client和zookeeper/hadoop千万不要改动:

LoginUtil.setJaasConf("Client", userName, userKeytabFile);
LoginUtil.setZookeeperServerPrincipal("zookeeper/hadoop");

正常就是这样的:
在这里插入图片描述

如果上面的两行代码有改动,则根据zookeeper拿不到hive的地址:
在这里插入图片描述
上面是我的代码中的日志,其他人的可能不是这样,但应该是报这个错误的:

Exception in thread "main" java.sql.SQLException: org.apache.hive.jdbc.ZooKeeperHiveClientException: Unable to read HiveServer2 configs from ZooKeeper
at org.apache.hive.jdbc.HiveConnection.<init>(HiveConnection.java:144)
at org.apache.hive.jdbc.HiveDriver.connect(HiveDriver.java:105)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at JDBCExample.main(JDBCExample.java:82)
Caused by: org.apache.hive.jdbc.ZooKeeperHiveClientException: Unable to read HiveServer2 configs from ZooKeeper
at org.apache.hive.jdbc.ZooKeeperHiveClientHelper.configureConnParams(ZooKeeperHiveClientHelper.java:100)
at org.apache.hive.jdbc.Utils.configureConnParams(Utils.java:509)
at org.apache.hive.jdbc.Utils.parseURL(Utils.java:429)
at org.apache.hive.jdbc.HiveConnection.<init>(HiveConnection.java:142)
... 4 more
Caused by: org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss for /hiveserver2
at org.apache.zookeeper.KeeperException.create(KeeperException.java:99)
at org.apache.zookeeper.KeeperException.create(KeeperException.java:51)
at org.apache.zookeeper.ZooKeeper.getChildren(ZooKeeper.java:2374)
at org.apache.curator.framework.imps.GetChildrenBuilderImpl$3.call(GetChildrenBuilderImpl.java:214)
at org.apache.curator.framework.imps.GetChildrenBuilderImpl$3.call(GetChildrenBuilderImpl.java:203)
at org.apache.curator.RetryLo,op.callWithRetry(RetryLoop.java:107)
at org.apache.curator.framework.imps.GetChildrenBuilderImpl.pathInForeground(GetChildrenBuilderImpl.java:200)
at org.apache.curator.framework.imps.GetChildrenBuilderImpl.forPath(GetChildrenBuilderImpl.java:191)
at org.apache.curator.framework.imps.GetChildrenBuilderImpl.forPath(GetChildrenBuilderImpl.java:38)

上面报错的原因也很大可能是“Client”和“zookeeper/hadoop”这儿的问题,如果确信不是这个原因,也可以查看一下的华为官网解决方案:

https://support.huaweicloud.com/trouble-mrs/mrs_03_0172.html

至于为什么“Client”和“zookeeper/hadoop”不能改动,我在官网没有查到。“zookeeper/hadoop”则是涉及到zookeeper安全认证的principal,或许这就是默认的吧。

(2)账号权限问题:

下面就是第二个巨坑了。kerberos通过之后,代码中运行jdbc查询表,报错:

org.apache.hive.service.cli.HiveSQLException: Error while compiling statement: FAILED: HiveAccessControlException Permission denied: Principal [name=cq_xxxx_xxxx, type=USER] does not have following privileges for operation DESCTABLE [[SELECT] on Object [type=TABLE_OR_VIEW, name=dwd_pms.t_zh_ztjx_sysjz]]

大致的意思就是给我们的hive账户没有查询表的权限。

中台工作人员给的答复是,每次执行SQL语句前都要加上set role admin,他那边儿一切没问题,有问题是你代码的问题,他还给了验证:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201127110722838.png?x-oss-process=image/watermark,type_ZmFuZ3poZW在这里插入图片描述
什么?难道不是超级管理员给赋权嘛,自己给自己赋权。然后我怀着怀疑的态度照他们的建议在代码中添加set role admin后又去执行的代码,果然还是有问题的。错误提示用户不属于admin角色:
在这里插入图片描述
然后我在华为官网查到了解决方法(这难道就是一切没问题嘛):
在这里插入图片描述
(3)用户、角色等的修改后,kerberos认证文件需要重新下载

中台的人对hive账号的权限做出修改后,就突然的kerberos安全认证通过不了了。为此又花了一天的时间排查这个问题,最后我好像在华为官网找到了答案:
在这里插入图片描述

成果:

所有问题得到解决后:
在这里插入图片描述
在这里插入图片描述

总结:

本来一天时间就开发好了API接口,但调试环境花了将近一周的时间。主要就是生产环境中kerberos认证通过后hive账号权限的改动引起的keytab认证文件重新下载;再一个就是hive账号查询权限问题,一开始中台的人说一切没问题,咱就只能在自己代码里找问题,但其实后来我才在官网查到是需要他们配置的。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值