呼叫jar包把風電資料往hdfs寫資料無許可權問題 錯誤資訊:hadoop.security.AccessControlException:Permission denied:user=gcl,access=write,inode:"":jeff:hive:-rw-r--r-- 首先想到的兩個方法: 1、將hdfs-core.xml配置檔案的dfs.permisssions引數修改為false 2、修改操作檔案的許可權 但是這兩種方法都很僵,不夠優雅
因為user=gcl,這裡我所期望的是系統的使用者名稱為hive,於是就想configuration這個配置類有沒有在哪段原始碼裡設定以哪個使用者執行?
org.apache.hadoop.security.UserGroupInformation有一個靜態方法:getCurrentUser()。它會返回一個UserGroupInformation類的例項,如果subject為空,或者這個subject中與org.apache.hadoop.security.User對應的Principal為空,那麼說明尚未登入過,呼叫getLoginUser()建立UserGroupInformation的例項。 getLoginUser()的流程: 1.建立LoginContext: name:如果hadoop.security.authentication等於”kerberos”,那麼是“hadoop-user-kerberos”或者“hadoop-keytab-kerberos”,否則是“hadoop-simple”。它的主要作用是作為appName傳遞給UserGroupInformation.HadoopConfiguration.getAppConfigurationEntry(String appName)方法。 subject: callbackHandler: 空 Configuration: UserGroupInformation.HadoopConfiguration的例項。 2.login.login(); 這個會呼叫HadoopLoginModule的login()和commit()方法。 HadoopLoginModule的login()方法是一個空函式,只列印了一行除錯日誌 LOG.debug("hadoop login"); commit()方法負責把Principal新增到Subject中。 此時一個首要問題是username是什麼? 在使用了kerberos的情況下,從javax.security.auth.kerberos.KerberosPrincipal的例項獲取username。 在未使用kerberos的情況下,優先讀取HADOOP_USER_NAME這個系統環境變數,如果不為空,那麼拿它作username。否則,讀取HADOOP_USER_NAME這個java環境變數。否則,從com.sun.security.auth.NTUserPrincipal或者com.sun.security.auth.UnixPrincipal的例項獲取username。 如果以上嘗試都失敗,那麼丟擲異常LoginException("Can’t find user name")。 最終拿username構造org.apache.hadoop.security.User的例項新增到Subject中。 配置完HADOOP_USER_NAME系統變數之後,資料夾所有者和使用者都將成為hive