Установить пользователя системы системы suoop для клиента, встроенного в Java webapp
Я хотел бы отправить задания MapReduce из веб-приложения java в удаленный кластер Hadoop, но не могу указать, к какому пользователю нужно отправить задание. Я хотел бы настроить и использовать системного пользователя, который должен использоваться для всех заданий MapReduce.
В настоящее время я не могу указать какого-либо пользователя и независимо от того, что задание hadoop работает под именем пользователя текущего пользователя клиентской системы. Это вызывает ошибку с сообщением
Permission denied: user=alice, access=WRITE, inode="staging":hduser:supergroup:rwxr-xr-x
... где "alice" - локальный, зарегистрированный пользователь на клиентской машине.
Я пробовал
- различные комбинации создания экземпляров
UserGroupInformation
(как прокси, так и обычного пользователя) и
- задание свойства Java System с помощью
-Duser.name=hduser
, изменение USER
envar и жесткого кодирования System.setProperty("user.name", "hduser")
.
... безрезультатно. Что касается 1) я признаю, что не имею понятия о том, как эти классы должны использоваться. Также обратите внимание, что изменение свойства Java-системы, очевидно, не является реальным решением для использования в веб-приложении.
Кто-нибудь знает, как вы указываете, какой пользователь Hadoop использует для подключения к удаленной системе?
PS/Hadoop использует конфигурацию по умолчанию, означающую, что при подключении к кластеру не используется аутентификация, а Kerberos не используется для связи с удаленными машинами.
Ответы
Ответ 1
Наконец, я наткнулся на константу
static final String HADOOP_USER_NAME = "HADOOP_USER_NAME";`
в UserGroupInformation class
.
Устанавливая это как переменную среды, как свойство системы Java при запуске (используя -D
) или программно с помощью System.setProperty("HADOOP_USER_NAME", "hduser");
, Hadoop использует любое имя пользователя, которое вы хотите подключить к удаленному кластеру Hadoop.
Ответ 2
Код ниже работает для меня так же, как
System.setProperty("HADOOP_USER_NAME", "hduser")
UserGroupInformation ugi = UserGroupInformation.createRemoteUser("hduser");
ugi.doAs(new PrivilegedExceptionAction<Void>() {
public Void run() throws Exception {
Configuration configuration = new Configuration();
configuration.set("hadoop.job.ugi", "hduser");
int res = ToolRunner.run(configuration, new YourTool(), args);
return null;
}
});
Ответ 3
Я могу решить подобную проблему, используя функцию безопасного олицетворения http://hadoop.apache.org/docs/stable1/Secure_Impersonation.html
следующий фрагмент кода
UserGroupInformation ugi = UserGroupInformation.createProxyUser("hduser", UserGroupInformation.getLoginUser());
ugi.doAs(new PrivilegedExceptionAction() {
public Void run() throws Exception {
Configuration jobconf = new Configuration();
jobconf.set("fs.default.name", "hdfs://server:hdfsport");
jobconf.set("hadoop.job.ugi", "hduser");
jobconf.set("mapred.job.tracker", "server:jobtracker port");
String[] args = new String[] { "data/input", "data/output" };
ToolRunner.run(jobconf, WordCount.class.newInstance(), args);
return null;
} });
Удаленный (Windows Desktop host в моем случае) идентификатор пользователя входа должен быть добавлен в core-site.xml, как указано в вышеупомянутом URL