环境:
security cdh 5.2.0
security hbase
启动mapreduce的账户为hive或者others(非hbase),如下假设以bi账户为例
出发点:
mapper/reduce程序中读取hbase中数据,或者写入hbase数据
踩过的坑:
- 在mapreduce的job创建过程中加入如下认证代码
UserGroupInformation.setConfiguration(conf); UserGroupInformation.loginUserFromKeytab(conf.get("hbase.master.kerberos.principal"), conf.get("hbase.keytab.path"));
a.若此处使用该节点bi账户的认证登陆,mapreduce可以正常启动,然而在mapper/reduce阶段访问hbase认证失败。
b.若此处使用该节点hbase账户的认证登陆,同样也会报认证失败。 - 考虑如上b中情况,采用hbase账户认证,若在job创建后,加入如下代码
import org.apache.hadoop.hbase.security.User; if (User.isSecurityEnabled()) { User.getCurrent().obtainAuthTokenForJob(conf, job); }
可通过,此时采用的hbase认证读写hbase - jar包问题,mapreduce过程中,加载不了hbase相关的jar
若在job创建阶段掉了hbase相关类,例如Configuration conf = HBaseConfiguration.create();必须在hadoopclasspath中加载jar包,方式例如
for jarfile in `ls /opt/cloudera/parcels/CDH-5.2.0-1.cdh5.2.0.p0.36/jars/.`; do export HADOOP_CLASSPATH="${HADOOP_CLASSPATH}:/opt/cloudera/parcels/CDH-5.2.0-cdh5.2.0.p0.36/jars/$jarfile" done
若在mapper、reduce中调用了hbase相关类,需要采用-libjars方式或者cdh中TableMapReduceUtil.addDependencyJars方式,两者能达到相同的效果,参考如下
hadoop jar my.jar com.myclassname -libjars /opt/cloudera/parcels/CDH-5.2.0-1.cdh5.2.0.p0.36/lib/hbase/hbase-common-0.98.6-cdh5.2.0.jar,/opt/cloudera/parcels/CDH-5.2.0-1.cdh5.2.0.p0.36/lib/hbase/hbase-protocol-0.98.6-cdh5.2.0.jar,/opt/cloudera/parcels/CDH-5.2.0-1.cdh5.2.0.p0.36/lib/hbase/lib/hbase-client-0.98.6-cdh5.2.0.jar,/opt/cloudera/parcels/CDH-5.2.0-1.cdh5.2.0.p0.36/lib/hbase/lib/htrace-core.jar params
或者创建job后增加代码
TableMapReduceUtil.addDependencyJars(job);
- mapreduce的输入为bi不可读的目录或者hbase不可读的目录,会有读取权限问题
可采用acl方式解决hadoop fs -setfacl -R -m user:hbase:r-x /user/hive/warehouse/dmp_system.db/apps_rank
但不建议使用此方法,acl需要管理员hdfs授权,建议读取本用户目录的数据。 - 采用bi账户,bi认证,且使用如上第二点的user obtainAuthTokenForJob,mapper、reducer写入hbase认证失败。
需要在hbase shell中对该账户授权,例如:grant 'bi','RWX','hbase_table_name'
具体可参考https://github.com/bkersbergen/hbase-kerberos-mapreduce-hadoop2
总结:若在使用mapreduce时,即需要读取hdfs目录,又要读写入hbase,建议采用如上5这种方式,即,hdfs目录对于该账户具有读写权限,并且对hbase表进行该账户的读写授权。