Apache spark Spark Streaming未读取所有卡夫卡记录

Apache spark Spark Streaming未读取所有卡夫卡记录,apache-spark,apache-kafka,spark-streaming,Apache Spark,Apache Kafka,Spark Streaming,我们从卡夫卡向SparkStreaming发送了15条记录,但spark只收到11条记录。我使用的是spark 2.1.0和kafka_2.12-0.10.2.0 代码 import java.util.HashMap; 导入java.util.Map; 导入java.util.Properties; 导入org.apache.kafka.clients.producer.KafkaProducer; 导入org.apache.kafka.clients.producer.ProducerCon

我们从卡夫卡向SparkStreaming发送了15条记录,但spark只收到11条记录。我使用的是spark 2.1.0和kafka_2.12-0.10.2.0

代码

import java.util.HashMap;
导入java.util.Map;
导入java.util.Properties;
导入org.apache.kafka.clients.producer.KafkaProducer;
导入org.apache.kafka.clients.producer.ProducerConfig;
导入org.apache.kafka.clients.producer.ProducerRecord;
导入org.apache.spark.api.java.JavaSparkContext;
导入org.apache.spark.api.java.function.function;
导入org.apache.spark.sql.SparkSession;
导入org.apache.spark.streaming.Duration;
导入org.apache.spark.streaming.api.java.JavaDStream;
导入org.apache.spark.streaming.api.java.javapairReceiverInputStream;
导入org.apache.spark.streaming.api.java.JavaStreamingContext;
导入org.apache.spark.streaming.kafka.KafkaUtils;
导入scala.Tuple2;
公共类KafkaToSparkData{
公共静态void main(字符串[]args)引发InterruptedException{
int timeDuration=100;
int consumerNumberOfThreads=1;
字符串consumerTopic=“InputDataTopic”;
字符串zookeeperUrl=“localhost:2181”;
字符串consumerTopicGroup=“testgroup”;
字符串producerKafkaUrl=“localhost:9092”;
字符串producerTopic=“OutputDataTopic”;
字符串sparkMasterUrl=“local[2]”;
Map topicMap=newhashmap();
topicMap.put(consumerTopic,consumerNumberOfThreads);
SparkSession SparkSession=SparkSession.builder().master(sparkMasterUrl.appName(“卡夫卡火花”).getOrCreate();
JavaSparkContext JavaSparkContext=新的JavaSparkContext(sparkSession.sparkContext());
JavaStreamingContext JavaStreamingContext=新的JavaStreamingContext(javaSparkContext,新的持续时间(timeDuration));
JavaPairReceiverInputStreamMessages=KafkaUtils.createStream(javaStreamingContext、zookeeperUrl、consumerTopicGroup、topicMap);
JavaDStream NewRecord=messages.map(新函数(){
私有静态最终长serialVersionUID=1L;
公共字符串调用(Tuple2行)引发异常{
字符串响应Kafka=“”;
System.out.println(“数据为”+行);
字符串值数据=行。\u 2;
responseToKafka=ValueData+“|”+“0”;
Properties configProperties=新属性();
put(ProducerConfig.BOOTSTRAP\u SERVERS\u CONFIG,producerKafkaUrl);
configProperties.put(“key.serializer”,org.apache.kafka.common.serialization.StringSerializer.class);
configProperties.put(“value.serializer”,org.apache.kafka.common.serialization.StringSerializer.class);
卡夫卡制作人=新卡夫卡制作人(配置属性);
ProducerRecord topicMessage=新的ProducerRecord(producerTopic,responseToKafka);
producer.send(topicMessage);
producer.close();
卡夫卡的回归反应;
}
});
系统输出打印项次(“打印记录”);
NewRecord.print();
javaStreamingContext.start();
javaStreamingContext.awaitTermination();
javaStreamingContext.close();
}
}
卡夫卡制作人 bin/kafka-console-producer.sh--代理列表localhost:9092--主题InputDataTopic # 1. 2. 3. 4. 5. 6. 7. 8. 9 10 11 12 13 14 15 16 17 十八

卡夫卡消费者 bin/kafka-console-consumer.sh--引导服务器localhost:9092--主题OutputDataTopic--从开始 # 1|0 2|0 3|0 4|0 5|0 6|0 7|0 8|0 9|0 10|0 11 | 0


有人能帮我一下吗?

我们在这里看到的是Spark中懒惰操作的工作方式。 在这里,我们使用
map
操作来产生副作用,即向卡夫卡发送一些数据

然后使用
print
将流具体化。默认情况下,
print
将显示流的前10个元素,但需要使用
n+1
元素以显示“…”以指示何时有更多元素

这个
take(11)
强制实现前11个元素,因此它们从原始流中提取,并使用
map
函数进行处理。这导致了卡夫卡的部分出版

如何解决这个问题?嗯,上面已经有提示:不要在
map
函数中使用副作用。 在这种情况下,使用流并将其发送到Kafka的正确输出操作应该是
foreachRDD

此外,为了避免为每个元素创建Kafka producer实例,我们使用
foreachPartition
处理内部
RDD

此过程的代码框架如下所示:

messages.foreachRDD{rdd => 
  rdd.foreachPartition{partitionIter => 
       producer = // create producer
       partitionIter.foreach{elem =>
           record = createRecord(elem)
           producer.send(record)
       }
       producer.flush()  
       producer.close()
   }
}    

我们在这里看到的是Spark中懒惰操作的工作方式。 在这里,我们使用
map
操作来产生副作用,即向卡夫卡发送一些数据

然后使用
print
将流具体化。默认情况下,
print
将显示流的前10个元素,但需要使用
n+1
元素以显示“…”以指示何时有更多元素

这个
take(11)
强制实现前11个元素,因此它们从原始流中提取,并使用
map
函数进行处理。这导致了卡夫卡的部分出版

如何解决这个问题?嗯,上面已经有提示:不要在
map
函数中使用副作用。 在这种情况下,使用流并将其发送到Kafka的正确输出操作应该是
foreachRDD

此外,为了避免为每个元素创建Kafka producer实例,我们使用
foreachPartition
处理内部
RDD

此过程的代码框架如下所示:

messages.foreachRDD{rdd => 
  rdd.foreachPartition{partitionIter => 
       producer = // create producer
       partitionIter.foreach{elem =>
           record = createRecord(elem)
           producer.send(record)
       }
       producer.flush()  
       producer.close()
   }
}    

你能补充一个完整的可重复的例子吗?也就是说,添加制作人。@maasg,我已经添加了完整的代码。我从卡夫卡制作人那里发了18张唱片。。但是卡夫卡消费者只收到了11张加工过的唱片,有人能帮我吗?你能添加一张完整的复制品吗