在使用hive的过程中,难免会遇到多用户使用的问题。在配置上主要分两个大的步骤来完成。

    我配置的版本是cdh5.0,对应的hive版本是0.12

    假设现在用户tom想通过hive对数据库order的order_item表进行查询操作

    首先要在hive中配置用户tom对数据库和表的相关权限,在hive中提供了对数据库,表的授权管理,类似于操作系统权限可以授予给不同的主题,如用户(USER),组(GROUP),角色(ROLES)。那么要先使用grant语句针对用户tom可以访问的数据库和表进行授权

GRANT SELECT on TABLE(DATABASE) order_item to USER tom;

授权完成后,用户tom就可以查询order_item表了

这里有一个问题要说明下,默认情况下,任何用户都可以使用grant语句进行授权操作,所以必须要有一个超级管理员的角色来管理授权的操作,否则授权就没有任何意义了。建立超级管理员,需要添加hive.semantic.analyzer.hook配置,并实现自己的权限控制类

import org.apache.hadoop.hive.ql.parse.ASTNode;
import org.apache.hadoop.hive.ql.parse.AbstractSemanticAnalyzerHook;
import org.apache.hadoop.hive.ql.parse.HiveParser;
import org.apache.hadoop.hive.ql.parse.HiveSemanticAnalyzerHookContext;
import org.apache.hadoop.hive.ql.parse.SemanticException;
import org.apache.hadoop.hive.ql.session.SessionState;

 /**
  * 设置Hive超级管理员
  * 
  */
 public class AuthHook extends AbstractSemanticAnalyzerHook {
     private static String admin = "admin";
 
     @Override
     public ASTNode preAnalyze(HiveSemanticAnalyzerHookContext context,
             ASTNode ast) throws SemanticException {
         switch (ast.getToken().getType()) {
         case HiveParser.TOK_CREATEDATABASE:
         case HiveParser.TOK_DROPDATABASE:
         case HiveParser.TOK_CREATEROLE:
         case HiveParser.TOK_DROPROLE:
         case HiveParser.TOK_GRANT:
         case HiveParser.TOK_REVOKE:
         case HiveParser.TOK_GRANT_ROLE:
         case HiveParser.TOK_REVOKE_ROLE:
             String userName = null;
             if (SessionState.get() != null
                     && SessionState.get().getAuthenticator() != null) {
                 userName = SessionState.get().getAuthenticator().getUserName();
             }
             if (!admin.equalsIgnoreCase(userName)) {
                 throw new SemanticException(userName
                         + " can't use ADMIN options, except " + admin + ".");
             }
             break;
         default:
             break;
         }
         return ast;
     }
 }


添加了控制类之后还必须添加下面的配置:

<property> 

    <name>hive.semantic.analyzer.hook</name> 

    <value>com.xxx.AuthHook</value>  

</property>

(若有使用hiveserver,hiveserver必须重启)

至此,只有admin用户可以进行Grant/Revoke操作。

hive授权管理完成之后,下一步就需要在hdfs的/user目录下建立用户的home目录,可以使用hadoop账户来建立。具体操作如下

hadoop fs -mkdir /user/tom
hadoop fs -chown tom:tom /user/tom

建立此目录的目的是,当用户tom使用hive查询时,产生的mr job会在/user/tom/.staging目录下存储作业相关的临时文件。具体源码如下

首先调用JobSubmitter的submitJobInternal

JobStatus submitJobInternal(Job job, Cluster cluster) 
  throws ClassNotFoundException, InterruptedException, IOException {
    //validate the jobs output specs 
    checkSpecs(job);
    Configuration conf = job.getConfiguration();
    addMRFrameworkToDistributedCache(conf);
    //获取临时存储目录
    Path jobStagingArea = JobSubmissionFiles.getStagingDir(cluster, conf);
    ....
}
JobSubmissionFiles.getStagingDir(){
    Path stagingArea = cluster.getStagingAreaDir();
}
Cluster.getStagingAreaDir(){
    if (stagingAreaDir == null) {
      stagingAreaDir = new Path(client.getStagingAreaDir());
    }
    return stagingAreaDir;
}
YarnRunner.getStagingAreaDir(){
    return resMgrDelegate.getStagingAreaDir();
}
ResourceMgrDelegate.getStagingAreaDir(){
    String user = 
      UserGroupInformation.getCurrentUser().getShortUserName();
    Path path = MRApps.getStagingAreaDir(conf, user);
    LOG.debug("getStagingAreaDir: dir=" + path);
    return path.toString();
}
MRApps.getStagingAreaDir(){
    //获取yarn.app.mapreduce.am.staging-dir的值,为/user
    return new Path(conf.get(MRJobConfig.MR_AM_STAGING_DIR,
        MRJobConfig.DEFAULT_MR_AM_STAGING_DIR)
        + Path.SEPARATOR + user + Path.SEPARATOR + STAGING_CONSTANT);
}

经过层层调用,MRApps.getStagingAreaDir()组装最终的提交目录,为/user/$user/.staging,由此可见为什么需要配置/user目录下的tom目录


上述步骤完成后,就可以使用tom用户对order_item表进行查询相关的操作了



参考资料:

http://yugouai.iteye.com/blog/1864772

http://blog.csdn.net/dyllove98/article/details/9149091