Définir l'utilisateur système hadoop pour le client intégré dans Java webapp
Je voudrais soumettre des travaux MapReduce d'une application Web java à un cluster Hadoop distant mais je ne peux pas spécifier pour quel utilisateur le travail doit être soumis. Je voudrais configurer et utiliser un utilisateur système qui devrait être utilisé pour tous les travaux MapReduce.
Actuellement, je suis incapable de spécifier un utilisateur et peu importe ce que le travail hadoop s'exécute sous le nom d'utilisateur de l'utilisateur actuellement connecté du système client. Cela provoque une erreur avec le message
Permission denied: user=alice, access=WRITE, inode="staging":hduser:supergroup:rwxr-xr-x
... où "alice" est l'utilisateur local connecté sur la machine cliente.
J'ai essayé
- diverses combinaisons de création d'instances
UserGroupInformation
(à la fois proxies et utilisateur normal) et - définition de la propriété système Java avec
-Duser.name=hduser
, Modification de l'envarUSER
et d'un appelSystem.setProperty("user.name", "hduser")
codé en dur.
... en vain. En ce qui concerne 1) j'avoue n'avoir aucune idée de la façon dont ces classes sont censées être utilisées. Veuillez également noter que la modification de la propriété système Java n'est évidemment pas une solution réelle pour une utilisation dans l'application web.
Est-ce qu'un corps sait comment vous spécifiez quel utilisateur Hadoop utilise pour se connecter à un système distant?
PS / Hadoop utilise la configuration par défaut, ce qui signifie qu'aucune authentification n'est utilisée lors de la connexion au cluster et que Kerberos n'est pas utilisé pour communiquer avec les machines distantes.
3 réponses
Enfin, je suis tombé sur la constante
static final String HADOOP_USER_NAME = "HADOOP_USER_NAME";`
Dans le UserGroupInformation class
.
Définir ceci soit comme une variable d'environnement, comme une propriété système Java au démarrage (en utilisant -D
) ou par programmation avec System.setProperty("HADOOP_USER_NAME", "hduser");
fait que Hadoop utilise le nom d'utilisateur que vous voulez pour vous connecter au cluster Hadoop distant.
Le code ci-dessous fonctionne pour moi comme
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;
}
});
Je suis capable de résoudre un problème similaire en utilisant la fonctionnalité d'usurpation d'identité sécurisée http://hadoop.apache.org/docs/stable1/Secure_Impersonation.html
Voici l'extrait de code
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;
} });
L'id utilisateur de connexion distant (Windows desktop host dans mon cas) doit être ajouté dans core-site.xml comme mentionné dans L'URL mentionnée ci-dessus