在使用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表進行查詢相關的操作了
參考資料: