chenpengcong / blog

14 stars 3 forks source link

Hadoop生态组件踩坑记 #28

Open chenpengcong opened 5 years ago

chenpengcong commented 5 years ago

本文记录使用Hadoop生态相关组件过程中遇到的问题及解决方案

Kerberos

1. Windows下使用Kinit.exe报错ICMP Port Unreachable

在windows下使用kinit.exe需要注意使用的是否是Kerberos安装目录下的kinit.exe,因为JDK的安装目录下也存在kinit.exe文件,很大可能会由于环境变量的路径顺序问题导致先找到了jdk中的kinit.exe文件导致报错

Hadoop

1. 为HTTP接口开启kerberos认证时注意hosts文件配置

在配置Hadoop的http交互认证时,在windows下使用firefox访问YARN的Web UI(http://debian9-100.cn:8088/cluster)时返回

HTTP ERROR 403 
Problem accessing /cluster. Reason: 
java.lang.IllegalArgumentException: Malformed gss token 
Powered by Jetty://

排查了好久,最终在krb5kdc服务的日志文件krb5kdc.log中找到突破口,报错日志如下

Aug 26 16:27:11 debian9-100 krb5kdc[6051](info): TGS_REQ (6 etypes {18 17 16 23 25 26}) 192.168.137.1: LOOKING_UP_SERVER: authtime 0, HTTP/debian9-100.cn@CPC.CN for HTTP/debian9-100@CPC.CN, Server not found in Kerberos database

提示HTTP/debian9-100@CPC.CN找不到,而我明明在所有需要配置hostname的地方都配置了FQDN,即debian9-100.cn而不是debian9-100.cn,为什么会出现debian9-100

经过查找,windows下的hosts文件中如下一行引起了我的注意

192.168.137.100 debian9-100 debian9-100.cn 

尝试将debian9-100.cn配置在debian9-100前面,结果问题就解决了

过后在linux环境下试了下hostname -f命令,输出的FQDN总是hosts文件中出现的第一个域名,所以在配置FQDN时记得配置在最前面

ZooKeeper

1. Zookeeper不会通过KRB5_CONFIG环境变量寻找krb5.conf文件

为zookeeper配置kerberos认证时,发现报错

2019-08-27 16:13:35,886 [myid:1] - ERROR [main:QuorumPeerMain@101] - Unexpected exception, exiting abnormally
java.io.IOException: Could not configure server because SASL configuration did not allow the ZooKeeper server to authenticate itself properly: javax.security.auth.login.LoginException: Cannot locate KDC

提示不能找到KDC,最终尝试将krb5.conf移动到默认安装路径/etc/krb5.conf就解决问题了

Sqoop

1. export使用allowinsert更新模式时--columns参数失效

因为HDFS上数据的字段顺序与数据库表字段顺序不一定会一致,所以会出现--update-key, --update-mode allowinsert, --columns三个选项同时使用情况,经测试,这3个参数同时使用时--columns参数的功能会失效,sqoop不会按照--columns指定的顺序进行导出

测试环境如下

软件版本: Hadoop2.7.7, Oracle 11g, sqoop-1.4.7-hadoop260.jar

Sqoop集成方式:Java API,参考Using Apache’s Sqoop as an API中最后一种调用方法

        SqoopTool tool = new ExportTool();
        String[] args = {
                "--connect", "jdbc:oracle:thin:@192.168.1.6:1521/myservice",
                "--username", "test",
                "--password", "test",
                "--table", table,
                "--export-dir", exportDir,
                "--fields-terminated-by", delimiter
            };
        SqoopOptions options = new SqoopOptions();
        try {
            options = tool.parseArguments(args, conf, options, false);
            tool.validateOptions(options);
            return tool.run(options);
        } catch (Exception e) {
            logger.error("export failed", e);
            return -1;
        }

Hive

1. 升级Hive的oracle更新脚本存在问题

在将Hive从1.2.1更新到2.3.6时,发现oracle的更新脚本039-HIVE-12274.oracle.sql执行报错,报错原因是该脚本将VARCHAR2类型的字段直接改为CLOB,在oracle中是不允许的。

经查找发现该bug早就被修复了https://issues.apache.org/jira/browse/HIVE-17333

但是在我下载的2.3.6版本的安装包中却还是存在该问题,正确的更新脚本可以使用Hive源码的master分支中的039-HIVE-12274.oracle.sql

Hbase

1. 单独配置Securing ZooKeeper Data

有这么一个需求:让Hbase在Zookeeper中创建的znode具有ACL,保证Hbase在zookeeper上的数据不被篡改

配置Hbase使用SASL认证访问zookeepe基本参考官网SASL Authentication with ZooKeeper即可

但需要解决两个问题

  1. 按照官网配置后Hbase在Zookeeper创建的znode没有相应的ACL,经验证,需要配置hbase.security.authentications为kerberos后Hbase才会创建具有ACL的znode,但一旦配置hbase.security.authentications为kerberos,还需要为master和region server配置kerberos认证,而我的需求仅仅是保证hbase在zookeeper中的数据是安全的。解决方案是手动创建具有ACL的znode,create /hbase "" sasl:hbase:cdrwa。经验证Hbase可以正常访问
  2. 需要在zookeeper的的配置文件zoo.cfg中添加kerberos.removeHostFromPrincipal=true和 kerberos.removeRealmFromPrincipal=true,否则会因为kerberos的principal带有hostname导致认证失败,参考Configure the HBase Servers (Masters and RegionServers) to Use Authentication to Connect to ZooKeeper

Kylin

1. 避免使用关键字作为列名

有次我使用了day作为Hive表的分区列

PARTITIONED BY (`day` string COMMENT '日期')

导致在Kylin查询SQL中一旦使用day作为过滤条件,Kylin就会报SQL错误,原因是day作为SQL的保留关键字不能直接作为列名使用。

因为Kylin使用了Apache Calcite解析器来解析SQL,所以检查是否使用了保留关键字可以查看Calcite的SQL参考文档中列出的关键字

该问题在Kylin JIRA上有过记录

2. Kylin在构建cube的第三个环节Extract Fact Table Distinct Columns报错Error: Could not find or load main class org.apache.hadoop.mapreduce.v2.app.MRAppMaster

该报错日志在YARN的WEB UI中是看不到的,只有提示container被kill的日志,有用的错误信息需要通过命令行yarn log -applicationId查看

问题在于Kylin提交的Job在Hadoop集群中运行时找不到依赖的Jar,而Kylin提交的Job寻找jar依赖于提交的Job的mapreduce.application.classpath属性值

Kylin设置Job的mapreduce.application.classpath属性过程:检查Hadoop配置文件是否配置了mapreduce.application.classpath,有则设置Job的mapreduce.application.classpath,没有则调用mapred classpath命令将输出的路径作为mapreduce.application.classpath的值

而我当时的Kylin所在节点的Hadoop配置文件没有配置mapreduce.application.classpath,hadoop安装路径也与Hadoop集群各节点的hadoop安装路径不一致,导致Kylin调用mapred classpath得到的路径在Hadoop集群各节点上是无效的

解决该问题有两种方案:

  1. 在Hadoop集群任意节点执行mapred classpath,并将输出的路径配置到Kylin所在节点的Hadoop配置文件mapred-site.xml的mapreduce.application.classpath属性
  2. 在Kylin所在节点安装Hadoop时,安装路径与Hadoop集群中各节点的Hadoop安装路径一致,这样Kylin调用mapred classpath获取到的路径在Hadoop各节点是有效的

参考:http://apache-kylin.74782.x6.nabble.com/Can-not-execute-mapreduce-job-as-missing-jars-td1516.html

GypGit commented 10 months ago

@chenpengcong ,Hey bro, your hadoop problem handling column solved a problem that had been bothering me for three days! Thank you so much!