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é

  1. diverses combinaisons de création d'instances UserGroupInformation (à la fois proxies et utilisateur normal) et
  2. définition de la propriété système Java avec -Duser.name=hduser, Modification de l'envar USER et d'un appel System.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.

26
demandé sur Christoffer Soop 2012-06-15 00:59:13

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.

39
répondu Christoffer Soop 2012-06-16 10:08:24

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; 
    }
});
5
répondu volhv 2013-03-21 12:27:44

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

1
répondu kiran 2014-01-30 16:38:41