ClouderaのHadoopデモをダウンロードして起動しましたVM for CDH4(Hadoop 2.0.0を実行しています)。Javaプログラムを作成しようとしています私のWindows 7マシンから実行します(VMが実行されているのと同じマシン/ OS)。次のようなサンプルプログラムがあります:
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)
私はインターネットを見回してみましたが、ディスク容量が少ないときにこれが発生するようですが、「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を使用するのが初めてなので、おそらく基本的なものが欠けています。何か案は?
ログに表示されるのは、クライアントで取得した場合と同様の例外のみです。
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)のアクセス許可を変更しようとしましたが、それは修正されませんでした(私は、すべてのユーザーに完全なアクセス権を与えるまでは行った)。
HUE Webアプリを介してHDFSを参照しているときに、フォルダー構造が作成され、ファイルは存在するが空であることがわかりました。を使用してデフォルトのユーザーディレクトリの下にファイルを入れてみました
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つのノードがこの操作で除外されています。
これは、hdfs-clientが50010ポートでデータノードに接続できなかったことを意味します。 hdfs namenodeに接続すると、データノードのステータスを取得できます。しかし、hdfs-clientはデータノードに接続できませんでした。
(hdfsでは、namenodeがファイルディレクトリとデータノードを管理します。hdfs-clientがnamnenodeに接続すると、データがあるデータファイルのターゲットファイルパスとアドレスが検出されます。その後、hdfs-clientはdatanodeと通信します。 hdfs-clientは、namenodeによって通知されたアドレスを使用してデータノードと通信しようとするため、netstatを使用してそれらのデータノードuriを確認してください)
私解決済みその問題:
"dfs.client.use.datanode.hostname", "true"
英語が下手でごめんなさい。
Linux VMに移動し、ホスト名とiPアドレスを確認します(ifconfig cmdを使用)。次に、linux vmで/ etc/Hostファイルを次のように編集します。
IPADDRESS(SPALCE)ホスト名
例:192.168.110.27 clouderavm
そして、あなたのすべてのhadoop設定ファイルを次のように変更します
core-site.xml
hdfs-site.xml
mapred-site.xml
糸サイト.xml
localhostまたはlocalhost.localdomainまたは0.0.0.0をyour hostnameに変更します
その後、clouderaマネージャーを再起動します。
windowsマシンで編集C:\ Windows\System32\Drivers\etc\hosts
最後に1行追加
vMマシンのIPとホスト名(VMの/ etc/Hostファイルで行ったのと同じ)
VMIPADRESS VMHOSTNAME
例:
192.168.110.27 clouderavm
次に確認してください、動作するはずです。詳細な構成チェックについては、チューブのビデオに従ってください
hdfs-site.xml
に特定のプロパティを追加する
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
このファイルをプログラムにも追加します
conf.addResource("hdfs-site.xml");
hadoopを停止する
stop-all.sh
それから始めます
start-all.sh
私は同様の問題に遭遇し、2つの情報が役立つかもしれません。
最初に気付いたのは、sshトンネルを使用してネームノードにアクセスしていて、クライアントコードがデータノードにアクセスしようとしたときに、トンネルが何らかの形で通信を混乱させたため、データノードを見つけられなかったことです。次に、hadoop名前ノードと同じボックスでクライアントを実行し、問題を解決しました。つまり、非標準のネットワーク構成では、データノードを見つけるためのhadoopが混乱していました。
Sshトンネルを使用した理由は、名前ノードにリモートでアクセスできず、管理者によるポート制限が原因であると考えたため、sshトンネルを使用して制限をバイパスしました。しかし、それはhadoopの構成の誤りであることが判明しました。
変更後のcore-site.xml内
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>
に
<value>hdfs://Host_name:9000</value>
Ssh turnnelはもう必要なく、hdfsにリモートでアクセスできます。
まったく同じ問題を抱えていることを検索して、このような質問をたくさん見つけたので、最終的に私に役立つことを共有したいと思いました。 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());
}
同様の問題があり、私の場合、次のフォルダを空にしただけです${hadoop.tmp.dir}/nm-local-dir/usercache/{{hdfs_user}}/appcache/
データ(dfs/data)フォルダーを手動で削除して、namenodeをフォーマットしてみてください。その後、hadoopを開始できます。
FSに問題があるようです。 cross-site.xmlのパラメーターが、読み取ろうとしているファイルと一致していません
OR
パスにいくつかの一般的な不一致があります(WINDOWS参照があることがわかります)。
cygwinツールを使用してパスを設定し、データノードと一時ファイルの場所が配置される場所に配置することができます。これにより、トリックを十分に実行できます。場所:$/bin/cygpath.exe
P.S。私によれば、レプリケーションはここでは主要な問題ではないようです
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();
}
エラーメッセージから、レプリケーション係数は問題ないようです。データノードが適切に機能しているか、権限の問題があるようです。権限を確認し、ユーザーからデータノードのステータスを確認してください。あなたはhadoopを実行しようとしています。
hadoop構成では、デフォルトのレプリケーションは3に設定されています。一度確認して、要件に応じて変更してください。