Запись на HDFS с Java, получение "может быть реплицировано только на 0 узлов вместо minReplication"
Загрузил и запустил Cloudera Hadoop Demo VM для CDH4 (работает Hadoop 2.0.0). Я пытаюсь написать программу Java, которая будет запускаться с моего компьютера Windows 7 (тот же компьютер/ОС, в котором работает VM). У меня есть пример программы, например:
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();
}
}
Мой файл config.xml имеет только указанное свойство: fs.default.name = hdfs://CDH4_IP: 8020.
Когда я запускаю его, я получаю следующее исключение:
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)
Ive огляделся по Интернету, и похоже, что это происходит, когда дисковое пространство низкое, но это не так для меня, когда я запускаю "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
Я также могу запустить этот код просто отлично с помощью в VM. Я не уверен, в чем проблема или как ее исправить. Это мой первый раз с использованием hadoop, поэтому я, вероятно, пропустил что-то основное. Любые идеи?
Update
Единственное, что я вижу в журналах, - это исключение, подобное тому, которое находится на клиенте:
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)
Я попытался изменить разрешения в каталоге данных (/var/lib/hadoop-hdfs/cache/hdfs/dfs/data), и это не исправило (я дошел до полного доступа ко всем).
Я замечаю, что когда я просматриваю HDFS через веб-приложение HUE, я вижу, что структура папок была создана и что файл существует, но он пуст. Я попытался поместить файл под каталог пользователя по умолчанию, используя
FSDataOutputStream fdos=fs.create(new Path("testing/file04.txt"), true);
вместо
FSDataOutputStream fdos=fs.create(new Path("/testing/file04.txt"), true);
Что делает путь к файлу "/user/dharris/testing/file04.txt" ( "dharris" - мой пользователь Windows). Но это дало мне такую же ошибку.
Ответы
Ответ 1
У меня такая же проблема.
В моем случае ключом проблемы было следующее сообщение об ошибке.
В этой операции исключены 1 datanode (s) и 1 node (s).
Это означает, что ваш hdfs-клиент не смог подключиться к вашему datanode с портом 50010.
Когда вы подключились к hdfs namenode, вы можете получить статус datanode. Но ваш hdfs-клиент не смог подключиться к вашему datanode.
(В hdfs namenode управляет файловыми каталогами и datanodes.Если hdfs-клиент подключится к namnenode, он найдет путь к целевому файлу и адрес datanode, у которых есть данные. Тогда hdfs-клиент будет связываться с datanode. (Вы можете проверить эти uri-данные datanode, используя netstat, потому что hdfs-клиент будет пытаться связываться с datanodes, используя адрес, сообщенный namenode)
I решил эту проблему:
- открытие порта 50010 в брандмауэре.
- добавление свойства
"dfs.client.use.datanode.hostname", "true"
- добавление имени хоста в файл хоста на моем клиентском ПК.
Прошу прощения за плохое знание английского языка.
Ответ 2
Перейдите в виртуальную машину Linux и проверьте имя хоста и iP ADDRESS (используйте ifconfig cmd).
Затем в linux vm отредактируйте файл /etc/host с помощью
имя хоста IPADDRESS (SPALCE)
пример:
192.168.110.27 clouderavm
и измените все ваши конфигурационные файлы hadoop, например
ядро-site.xml
HDFS-site.xml
mapred-site.xml
пряжа site.xml
измените localhost или localhost.localdomain или 0.0.0.0 на ваше имя хоста
затем перезагрузите клаудер cloudera.
в редакторе Windows: C:\Windows\System32\Drivers\etc\hosts
добавьте одну строку в конец с помощью
вы vm машинный ip и имя хоста (так же, как вы сделали в файле /etc/host в vm)
VMIPADRESS VMHOSTNAME
пример:
192.168.110.27 clouderavm
затем проверьте, что он должен работать, для проверки конфигурации детали, следующей за VIDEO от вас.
https://www.youtube.com/watch?v=fSGpYHjGIRY
Ответ 3
добавить заданное свойство в hdfs-site.xml
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
и добавьте этот файл также в свою программу
conf.addResource("hdfs-site.xml");
stop hadoop
stop-all.sh
затем запустите
start-all.sh
Ответ 4
Я столкнулся с подобной проблемой и вам помогут две части информации.
-
Первое, что я понял, это использование ssh-туннеля для доступа к имени node, а когда клиентский код пытается получить доступ к данным node, он не может найти данные node из-за туннеля как-то испортил сообщение. Затем я запустил клиент в том же поле, что и имя hadoop node, и он решил проблему. Короче говоря, нестандартная конфигурация сети путала hadoop для поиска данных node.
-
Я использовал туннель ssh, я не могу получить доступ к имени node удаленно, и я думал, что это связано с ограничением порта администратором, поэтому я использовал туннель ssh, чтобы обойти это ограничение. Но это оказывается неправильной конфигурацией хаопа.
В файле core-site.xml после того, как я изменил
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>
to
<value>hdfs://host_name:9000</value>
Мне больше не нужен туннель ssh, и я могу получить доступ к hdfs удаленно.
Ответ 5
Так как я нашел много вопросов, подобных этому, в моем поиске того же самого вопроса, я думал, что поделюсь тем, что в конечном итоге сработало для меня. Я нашел этот пост на форуме Hortonworks: https://community.hortonworks.com/questions/16837/cannot-copy-from-local-machine-to-vm-datanode-via.html
Ответ был поистине понятным, что вызов новой функции Configuration() и установка правильных параметров по мере необходимости. В моем случае это был именно тот, который упоминается в этом посте. Поэтому мой рабочий код выглядит следующим образом.
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());
}
Ответ 6
в конфигурации hadoop, для репликации по умолчанию установлено значение 3. проверьте ее один раз и измените в соответствии с вашими требованиями.
Ответ 7
Вы можете попытаться удалить папку данных (dfs/data) вручную и сформировать namenode. Затем вы можете запустить hadoop.
Ответ 8
Из коэффициента репликации сообщения ошибки, похоже, будет отлично i.e.1.
Кажется, что datanode работает нормально или имеет разрешения.
Проверьте разрешения и проверьте статус формы datanode для пользователя, вы пытаетесь запустить hadoop.
Ответ 9
Вы используете одиночный datanode. Зачем нужно 3 репликации.
Вы можете изменить репликацию на 1 в файле core-site.xml.
Ответ 10
У меня была аналогичная проблема, в моем случае я просто опустел следующую папку ${hadoop.tmp.dir}/nm-local-dir/usercache/{{hdfs_user}}/appcache/
Ответ 11
Кажется, что проблема связана с FS.
Либо параметры в cross-site.xml не соответствуют файлу, который он пытается прочитать
ИЛИ
существует некоторое общее несоответствие в пути (я вижу, что есть ссылка WINDOWS).
вы можете использовать инструмент cygwin для установки пути и поместить его туда, где размещаются местоположения данных и временного файла, и которые должны в достаточной степени сделать трюк
Местоположение: $/bin/cygpath.exe
P.S. Репликация НЕ кажется основной проблемой здесь, согласно мне
Ответ 12
Вот как я создаю файлы в 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();
}
Ответ 13
Куда добавить нижеуказанную недвижимость. Это было упомянуто в комментарии.
добавив свойства "dfs.client.use.datanode.hostname", "true"