Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将文件写入Hdfs时发生IOException_Java_Hadoop_Ioexception - Fatal编程技术网

Java 将文件写入Hdfs时发生IOException

Java 将文件写入Hdfs时发生IOException,java,hadoop,ioexception,Java,Hadoop,Ioexception,我正在开发一个从mqtt代理获取gps数据并将其加载到hadoop集群的程序。在尝试将数据写入hdfs时,我得到了一个IOException。以下是完整的堆栈跟踪: java.io.IOException: Failed on local exception: com.google.protobuf.InvalidProtocolBufferException: Message missing required fields: callId, status; Host Details : loc

我正在开发一个从mqtt代理获取gps数据并将其加载到hadoop集群的程序。在尝试将数据写入hdfs时,我得到了一个IOException。以下是完整的堆栈跟踪:

java.io.IOException: Failed on local exception: com.google.protobuf.InvalidProtocolBufferException: Message missing required fields: callId, status; Host Details : local host is: "quickstart.cloudera/192.168.25.170"; destination host is: "quickstart.cloudera":8020; 
    at org.apache.hadoop.net.NetUtils.wrapException(NetUtils.java:765)
    at org.apache.hadoop.ipc.Client.call(Client.java:1165)
    at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:184)
    at com.sun.proxy.$Proxy7.create(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:165)
    at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:84)
    at com.sun.proxy.$Proxy7.create(Unknown Source)
    at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolTranslatorPB.create(ClientNamenodeProtocolTranslatorPB.java:187)
    at org.apache.hadoop.hdfs.DFSOutputStream.<init>(DFSOutputStream.java:1250)
    at org.apache.hadoop.hdfs.DFSOutputStream.newStreamForCreate(DFSOutputStream.java:1269)
    at org.apache.hadoop.hdfs.DFSClient.create(DFSClient.java:1063)
    at org.apache.hadoop.hdfs.DFSClient.create(DFSClient.java:1021)
    at org.apache.hadoop.hdfs.DistributedFileSystem.create(DistributedFileSystem.java:232)
    at org.apache.hadoop.hdfs.DistributedFileSystem.create(DistributedFileSystem.java:75)
    at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:806)
    at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:787)
    at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:686)
    at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:675)
    at com.mqttHadoopLoader.hadoop.MqttLoader.HdfsWriter.writeToHdfs(HdfsWriter.java:19)
    at com.mqttHadoopLoader.hadoop.MqttLoader.MqttDataLoader.messageArrived(MqttDataLoader.java:43)
    at org.eclipse.paho.client.mqttv3.internal.CommsCallback.handleMessage(CommsCallback.java:354)
    at org.eclipse.paho.client.mqttv3.internal.CommsCallback.run(CommsCallback.java:162)
    at java.lang.Thread.run(Thread.java:748)
Caused by: com.google.protobuf.InvalidProtocolBufferException: Message missing required fields: callId, status
    at com.google.protobuf.UninitializedMessageException.asInvalidProtocolBufferException(UninitializedMessageException.java:81)
    at org.apache.hadoop.ipc.protobuf.RpcPayloadHeaderProtos$RpcResponseHeaderProto$Builder.buildParsed(RpcPayloadHeaderProtos.java:1094)
    at org.apache.hadoop.ipc.protobuf.RpcPayloadHeaderProtos$RpcResponseHeaderProto$Builder.access$1300(RpcPayloadHeaderProtos.java:1028)
    at org.apache.hadoop.ipc.protobuf.RpcPayloadHeaderProtos$RpcResponseHeaderProto.parseDelimitedFrom(RpcPayloadHeaderProtos.java:986)
    at org.apache.hadoop.ipc.Client$Connection.receiveResponse(Client.java:850)
    at org.apache.hadoop.ipc.Client$Connection.run(Client.java:781)
这是调用HdfsWriter的mqtt方法:

String destFile = "hdfs://127.0.0.0.1:8020/gpsData/output/gps_data.txt";
 //Note *this is just a placeholder IP address for the purpose of this post. I do have the fully correct IP address for the program. 

    public void writeToHdfs(String gpsInfo) {
        try {
            Configuration conf = new Configuration();
            System.out.println("Connecting to -- " + conf.get("fs.defaultFS"));

            FileSystem fs = FileSystem.get(URI.create(destFile), conf);
            System.out.println(fs.getUri());

            // Error seems to occur here
            OutputStream outStream = fs.create(new Path(destFile));

            byte[] messageByt = gpsInfo.getBytes();
            outStream.write(messageByt);
            outStream.close();

            System.out.println(destFile + " copied to HDFS");

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
public void messageArrived(String topic, MqttMessage message)
        throws Exception {
            System.out.println(message);
            HdfsWriter hdfsWriter = new HdfsWriter();
            hdfsWriter.writeToHdfs(message.toString());
    }
我对hadoop还是一个新手,所以任何和所有的帮助都是很好的

更新
我已经完成了调试,可以肯定地告诉您,每当我尝试调用文件系统方法时,都会发生错误。例如,
fs.exists(pt)
fs.setReplication()

我相信hdfs使用的是google protobuf库。您的客户端代码似乎使用了错误(不兼容)的protobuf版本。试着朝这个方向挖

我相信hdfs使用google protobuf库。您的客户端代码似乎使用了错误(不兼容)的protobuf版本。试着朝这个方向挖

HDFS客户端和NameNode之间的协议使用Google协议缓冲区来序列化消息。该错误表示客户端发送的消息未包含所有预期字段,因此与服务器不兼容

这可能表示您正在运行的HDFS客户端版本比NameNode的版本旧。例如,
callId
字段是在apachejira发行版跟踪的特性中实现的,并在apachehadoop2.1.0-beta中发布。该版本之前的客户端不会在其消息中包含
callId
,因此它与运行2.1.0-beta或更高版本的NameNode不兼容


我建议检查您的客户端应用程序,以确保它使用的是与Hadoop集群版本匹配的Hadoop客户端库版本。从堆栈跟踪来看,您似乎正在使用Cloudera发行版。如果是这样的话,那么通过在其Maven存储库中使用Cloudera提供的匹配客户端库依赖项版本,您可能会获得最大的成功。有关详细信息,请参阅。

HDFS客户端和NameNode之间的协议使用Google协议缓冲区来序列化消息。该错误表示客户端发送的消息未包含所有预期字段,因此与服务器不兼容

这可能表示您正在运行的HDFS客户端版本比NameNode的版本旧。例如,
callId
字段是在apachejira发行版跟踪的特性中实现的,并在apachehadoop2.1.0-beta中发布。该版本之前的客户端不会在其消息中包含
callId
,因此它与运行2.1.0-beta或更高版本的NameNode不兼容


我建议检查您的客户端应用程序,以确保它使用的是与Hadoop集群版本匹配的Hadoop客户端库版本。从堆栈跟踪来看,您似乎正在使用Cloudera发行版。如果是这样的话,那么通过在其Maven存储库中使用Cloudera提供的匹配客户端库依赖项版本,您可能会获得最大的成功。有关详细信息,请参阅。

您需要仔细阅读错误消息。它告诉您错误:InvalidProtocolBufferException:消息缺少必填字段:callId,status;。因此,您正在向服务器发送无效数据。问题在于你发送什么,而不是如何发送。@JB Nizet是的,我已经阅读了错误消息。多次。一次又一次我甚至不知道错误消息是在说什么“消息”。如果您查看我包含的代码,您会发现我没有直接调用任何名为“Message”的代码。我已经调试好了,可以告诉您,我尝试调用的任何文件系统消息都会发生这种情况(即,
fs.exists(pt)
fs.setReplication(pt,(short)1)
)。但是,我找不到直接发生此错误的位置。您需要仔细阅读错误消息。它告诉您错误:InvalidProtocolBufferException:消息缺少必填字段:callId,status;。因此,您正在向服务器发送无效数据。问题在于你发送什么,而不是如何发送。@JB Nizet是的,我已经阅读了错误消息。多次。一次又一次我甚至不知道错误消息是在说什么“消息”。如果您查看我包含的代码,您会发现我没有直接调用任何名为“Message”的代码。我已经调试好了,可以告诉您,我尝试调用的任何文件系统消息都会发生这种情况(即,
fs.exists(pt)
fs.setReplication(pt,(short)1)
)。但是,我找不到直接发生此错误的位置。