web-dev-qa-db-fra.com

Définir l'utilisateur système hadoop pour le client intégré dans Java webapp

Je souhaite soumettre des travaux MapReduce à partir d'une application Web Java à un cluster Hadoop distant, mais je ne suis pas en mesure de spécifier pour quel utilisateur le travail doit être soumis. Je souhaite configurer et utiliser un utilisateur système qui doit être utilisé pour tous les travaux MapReduce.

Actuellement, je ne peux pas spécifier d'utilisateur et quel que soit le travail hadoop exécuté 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é

  1. diverses combinaisons de création d'instances UserGroupInformation (proxy et utilisateur normal) et
  2. définir la propriété système Java avec -Duser.name=hduser, changer l'envar USER et en tant qu'appel codé en dur System.setProperty("user.name", "hduser").

... en vain. Concernant 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 Java n'est évidemment pas une vraie solution à utiliser dans l'application Web.

Est-ce qu'un organisme 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.

29
Christoffer Soop

Enfin je suis tombé sur la constante

static final String HADOOP_USER_NAME = "HADOOP_USER_NAME";`

dans le UserGroupInformation class.

La définition de cette variable soit en tant que variable d’environnement, en tant que propriété système Java au démarrage (à l’aide de -D) Ou par programme avec System.setProperty("HADOOP_USER_NAME", "hduser");, Hadoop utilise le nom d’utilisateur de votre choix pour se connecter au cluster Hadoop distant.

45
Christoffer Soop

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; 
    }
});
6
volhv

Je peux résoudre un problème similaire en utilisant la fonction d'emprunt 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 à distance (hôte de bureau Windows dans mon cas) doit être ajouté dans core-site.xml comme indiqué dans l'URL susmentionnée

2
kiran