web-dev-qa-db-fra.com

En écrivant sur HDFS à partir de Java, obtenir "ne peut être répliqué que sur des nœuds au lieu de minReplication"

J'ai téléchargé et lancé la démo Hadoop de Cloudera VM pour CDH4 (sous Hadoop 2.0.0). J'essaie d'écrire un programme Java qui s'exécutera à partir de mon ordinateur Windows 7 (le même ordinateur/système d'exploitation sur lequel la VM s'exécute). J'ai un exemple de programme comme:

public static void main(String[] args) {
    try{
        Configuration conf = new Configuration();
        conf.addResource("config.xml");
        FileSystem fs = FileSystem.get(conf);
        FSDataOutputStream fdos=fs.create(new Path("/testing/file01.txt"), true);
        fdos.writeBytes("Test text for the txt file");
        fdos.flush();
        fdos.close();
        fs.close();
    }catch(Exception e){
        e.printStackTrace();
    }

}

Mon fichier config.xml a uniquement une propriété définie: fs.default.name = hdfs: // CDH4_IP: 8020.

Lorsque je l'exécute, je reçois l'exception suivante:

org.Apache.hadoop.ipc.RemoteException(Java.io.IOException): File /testing/file01.txt could only be replicated to 0 nodes instead of minReplication (=1).  There are 1 datanode(s) running and 1 node(s) are excluded in this operation.
    at org.Apache.hadoop.hdfs.server.blockmanagement.BlockManager.chooseTarget(BlockManager.Java:1322)
    at org.Apache.hadoop.hdfs.server.namenode.FSNamesystem.getAdditionalBlock(FSNamesystem.Java:2170)
    at org.Apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.addBlock(NameNodeRpcServer.Java:471)
    at org.Apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolServerSideTranslatorPB.addBlock(ClientNamenodeProtocolServerSideTranslatorPB.Java:297)
    at org.Apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos$ClientNamenodeProtocol$2.callBlockingMethod(ClientNamenodeProtocolProtos.Java:44080)
    at org.Apache.hadoop.ipc.ProtobufRpcEngine$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine.Java:453)
    at org.Apache.hadoop.ipc.RPC$Server.call(RPC.Java:898)
    at org.Apache.hadoop.ipc.Server$Handler$1.run(Server.Java:1693)
    at org.Apache.hadoop.ipc.Server$Handler$1.run(Server.Java:1689)
    at Java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.Java:396)
    at org.Apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.Java:1332)
    at org.Apache.hadoop.ipc.Server$Handler.run(Server.Java:1687)
    at org.Apache.hadoop.ipc.Client.call(Client.Java:1160)
    at org.Apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.Java:202)
    at $Proxy9.addBlock(Unknown Source)
    at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:39)
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:25)
    at Java.lang.reflect.Method.invoke(Method.Java:597)
    at org.Apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.Java:164)
    at org.Apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.Java:83)
    at $Proxy9.addBlock(Unknown Source)
    at org.Apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolTranslatorPB.addBlock(ClientNamenodeProtocolTranslatorPB.Java:290)
    at org.Apache.hadoop.hdfs.DFSOutputStream$DataStreamer.locateFollowingBlock(DFSOutputStream.Java:1150)
    at org.Apache.hadoop.hdfs.DFSOutputStream$DataStreamer.nextBlockOutputStream(DFSOutputStream.Java:1003)
    at org.Apache.hadoop.hdfs.DFSOutputStream$DataStreamer.run(DFSOutputStream.Java:463)

J’ai regardé sur Internet et cela semble se produire lorsque l’espace disque est faible, mais ce n’est pas le cas pour moi lorsque j’exécute "hdfs dfsadmin -report".

Configured Capacity: 25197727744 (23.47 GB)
Present Capacity: 21771988992 (20.28 GB)
DFS Remaining: 21770715136 (20.28 GB)
DFS Used: 1273856 (1.21 MB)
DFS Used%: 0.01%
Under replicated blocks: 0
Blocks with corrupt replicas: 0
Missing blocks: 0

-------------------------------------------------
Datanodes available: 1 (1 total, 0 dead)

Live datanodes:
Name: 127.0.0.1:50010 (localhost.localdomain)
Hostname: localhost.localdomain
Decommission Status : Normal
Configured Capacity: 25197727744 (23.47 GB)
DFS Used: 1273856 (1.21 MB)
Non DFS Used: 3425738752 (3.19 GB)
DFS Remaining: 21770715136 (20.28 GB)
DFS Used%: 0.01%
DFS Remaining%: 86.4%
Last contact: Fri Jan 11 17:30:56 EST 201323 EST 2013

Je peux aussi bien exécuter ce code avec la machine virtuelle. Je ne sais pas quel est le problème ni comment le résoudre. C’est la première fois que j'utilise hadoop, il me manque donc probablement quelque chose de fondamental. Des idées?

Mettre à jour

La seule chose que je vois dans les journaux est une exception similaire à celle sur get sur le client:

Java.io.IOException: File /testing/file01.txt could only be replicated to 0 nodes instead of minReplication (=1).  There are 1 datanode(s) running and 1 node(s) are excluded in this operation.
    at org.Apache.hadoop.hdfs.server.blockmanagement.BlockManager.chooseTarget(BlockManager.Java:1322)
    at org.Apache.hadoop.hdfs.server.namenode.FSNamesystem.getAdditionalBlock(FSNamesystem.Java:2170)
    at org.Apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.addBlock(NameNodeRpcServer.Java:471)
    at org.Apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolServerSideTranslatorPB.addBlock(ClientNamenodeProtocolServerSideTranslatorPB.Java:297)
    at org.Apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos$ClientNamenodeProtocol$2.callBlockingMethod(ClientNamenodeProtocolProtos.Java:44080)
    at org.Apache.hadoop.ipc.ProtobufRpcEngine$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine.Java:453)
    at org.Apache.hadoop.ipc.RPC$Server.call(RPC.Java:898)
    at org.Apache.hadoop.ipc.Server$Handler$1.run(Server.Java:1693)
    at org.Apache.hadoop.ipc.Server$Handler$1.run(Server.Java:1689)
    at Java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.Java:396)
    at org.Apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.Java:1332)
    at org.Apache.hadoop.ipc.Server$Handler.run(Server.Java:1687)

J'ai essayé de changer les autorisations sur le répertoire de données (/ var/lib/hadoop-hdfs/cache/hdfs/dfs/data) et cela n'a pas résolu le problème (je suis même allé jusqu'à donner un accès complet à tout le monde).

Je remarque que lorsque je navigue sur HDFS via l'application Web HUE, je constate que la structure de dossiers a été créée et que le fichier existe mais qu'il est vide. J'ai essayé de mettre le fichier dans le répertoire utilisateur par défaut en utilisant

FSDataOutputStream fdos=fs.create(new Path("testing/file04.txt"), true); 

au lieu de

FSDataOutputStream fdos=fs.create(new Path("/testing/file04.txt"), true);

Ce qui fait que le chemin du fichier devient "/user/dharris/testing/file04.txt" ("dharris" est mon utilisateur Windows). Mais cela m'a donné le même genre d'erreur.

18
David Harris

J'ai le même problème.
Dans mon cas, une des clés du problème était le message d'erreur suivant.
Il y a 1 datanode (s) en cours d'exécution et 1 nœud (s) sont exclus dans cette opération.

Cela signifie que votre client hdfs ne peut pas se connecter à votre code de données avec le port 50010. Lorsque vous vous connectez à un nom de fichier hdfs, vous pouvez obtenir le statut d'un code de code. Mais, votre client hdfs n'aurait pas réussi à se connecter à votre code de données.

(En hdfs, un namenode gère les répertoires de fichiers et les datanodes. Si hdfs-client se connecte à un namnenode, il trouvera un chemin de fichier cible et une adresse de datanode contenant les données. Ensuite, hdfs-client communiquera avec datanode. vérifie ces uri de code en utilisant netstat, car hdfs-client essaiera de communiquer avec des datanodes en utilisant une adresse renseignée par namenode)

J'ai résolu ce problème par:

  1. ouverture du port 50010 dans un pare-feu.
  2. ajout de la propriété "dfs.client.use.datanode.hostname", "true"
  3. ajout du nom d’hôte à hostfile sur mon PC client.

Je suis désolé pour ma faible compétence en anglais.

11
kook

Allez à linux VM et vérifiez le nom d’hôte et l’adresse iP (utilisez ifconfig cmd). Puis, dans le fichier linux vm edit/etc/Host avec

IPADDRESS (SPALCE) nom d'hôte

exemple: 192.168.110.27 clouderavm

et changer tous les fichiers de configuration de votre hadoop comme

core-site.xml

hdfs-site.xml

mapred-site.xml

yarn-site.xml

changez localhost ou localhost.localdomain ou 0.0.0.0 en votre nom d’hôte

puis relancez cloudera manger.

dans la machine Windows, éditez C:\Windows\System32\Drivers\etc\hosts

ajouter une ligne à la fin avec

votre ordinateur virtuel et votre nom d’hôte (comme dans le fichier/etc/Host de la machine virtuelle)

VMIPADRESS VMHOSTNAME  

exemple : 

192.168.110.27 clouderavm

alors vérifiez maintenant, cela devrait fonctionner, pour vérifier la configuration détaillée, suivez VIDEO de votre tube 

https://www.youtube.com/watch?v=fSGpYHjGIRY

2
Chennakrishna

ajouter une propriété donnée dans hdfs-site.xml

<property>
   <name>dfs.replication</name>
   <value>1</value>
 </property>

et ajoutez ce fichier aussi dans votre programme

conf.addResource("hdfs-site.xml");

arrêter hadoop 

stop-all.sh

puis commencez

start-all.sh
2
Kishore

J'ai rencontré le même problème et deux informations peuvent vous aider.

  1. La première chose que j’ai réalisée est que j’utilisais le tunnel ssh pour accéder au nœud de nom. Lorsque le code client tente d’accéder au nœud de données, il ne peut pas trouver le nœud de données car le tunnel a en quelque sorte gâché la communication. J'ai alors exécuté le client sur la même boîte que le noeud de nom de hadoop et cela a résolu le problème. En bref, la configuration réseau non standard confondait hadoop pour trouver le nœud de données.

  2. La raison pour laquelle j'ai utilisé le tunnel ssh est que je ne peux pas accéder au nœud de nom à distance et que je pensais que c'était dû à une restriction de port par l'administrateur. J'ai donc utilisé le tunnel ssh pour contourner la restriction. Mais cela s’avère être une mauvaise configuration de hadoop.

Dans core-site.xml après avoir changé

<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>

à 

<value>hdfs://Host_name:9000</value>

Je n'ai plus besoin du canal ssh et je peux accéder au fichier hdfs à distance.

1
zfy

Depuis que j'ai trouvé beaucoup de questions comme celle-ci dans ma recherche pour avoir exactement le même problème, j'ai pensé partager ce qui a finalement fonctionné pour moi. J'ai trouvé ce post sur le forum Hortonworks: https://community.hortonworks.com/questions/16837/cannot-copy-from-local-machine-to-vm-datanode-via.html

La réponse consistait vraiment à comprendre ce que signifie appeler nouvelle Configuration () et définir les paramètres corrects selon mes besoins. Dans mon cas, c'était exactement celui mentionné dans cet article. Donc, mon code de travail ressemble à ceci.

try {
    Configuration config = new Configuration();
    config.set("dfs.client.use.datanode.hostname", "true");
    Path pdFile = new Path("stgicp-" + pd);
    FileSystem dFS = FileSystem.get(new URI("hdfs://" + HadoopProperties.Hive_Host + ":" + HadoopProperties.HDFS_DEFAULT_PORT), config, 
            HadoopProperties.Hive_DEFAULT_USER);
    if (dFS.exists(pdFile)) {
        dFS.delete(pdFile, false);
    } 
    FSDataOutputStream outStream = dFS.create(pdFile);
    for (String sjWLR : processWLR.get(pd)) {
        outStream.writeBytes(sjWLR);
    }     
    outStream.flush();
    outStream.close();

    dFS.delete(pdFile, false);
    dFS.close();
} catch (IOException | URISyntaxException | InterruptedException e) {
    log.error("WLR file processing error: " + e.getMessage());
}
1
Eva Donaldson

J'ai eu un problème similaire, dans mon cas je viens de vider le dossier suivant ${hadoop.tmp.dir}/nm-local-dir/usercache/{{hdfs_user}}/appcache/

0
bachr

Vous pouvez essayer de supprimer manuellement le dossier data (dfs/data) et de formater le nom de fichier. Vous pouvez alors commencer hadoop.

0

Il semble y avoir un problème avec le système de fichiers. Soit les paramètres de cross-site.xml ne correspondent pas au fichier qu’il essaie de lire.

OU 

il y a quelques incompatibilités communes dans le chemin (je vois qu'il y a une référence WINDOWS).

vous pouvez utiliser l'outil cygwin pour configurer le chemin d'accès et le placer à l'emplacement approprié des emplacements de fichiers de données temporaires et temporaires. Emplacement: $/bin/cygpath.exe

P.S. La réplication ne semble pas être le problème principal ici selon moi

0
Yunus Khan

Voici comment je crée des fichiers dans le HDFS:

import Java.io.BufferedReader;
import Java.io.BufferedWriter;
import Java.io.InputStreamReader;
import Java.io.OutputStream;
import Java.io.OutputStreamWriter;
import org.Apache.hadoop.fs.FileSystem;
import org.Apache.hadoop.fs.Path;

FileSystem hdfs = FileSystem.get(context.getConfiguration());
Path outFile=new Path("/path to store the output file");

String line1=null;

if (!hdfs.exists(outFile)){
            OutputStream out = hdfs.create(outFile);
            BufferedWriter br = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
            br.write("whatever data"+"\n");
            br.close();
            hdfs.close();
        }
else{
            String line2=null;
            BufferedReader br1 = new BufferedReader(new InputStreamReader(hdfs.open(outFile)));
            while((line2=br1.readLine())!=null){
                line1=line1.concat(line2)+"\n";
            }
            br1.close();
            hdfs.delete(outFile, true);
            OutputStream out = hdfs.create(outFile);
            BufferedWriter br2 = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
            br2.write(line1+"new data"+"\n");
            br2.close();
            hdfs.close();
        }
0
Punit Naik

D'après le message d'erreur, le facteur de réplication semble être correct, à savoir 1. Il semble que le code de données fonctionne correctement ou présentent des problèmes d'autorisation. Vérifiez les autorisations et vérifiez le statut de code de données de l'utilisateur que vous tentez d'utiliser. courir hadoop.

0
Neha Milak

dans la configuration hadoop, la réplication par défaut est définie sur 3. Vérifiez-la une fois et modifiez-la en fonction de vos besoins.

0
srikayala