我使用Spark Streaming" JavaKafkaWordCount.java"提出的示例代码。
public final class JavaKafkaWordCount {
private static final Pattern SPACE = Pattern.compile(" ");
private JavaKafkaWordCount() {
}
public static void main(String[] args) throws Exception {
if (args.length < 4) {
System.err.println("Usage: JavaKafkaWordCount <zkQuorum> <group> <topics> <numThreads>");
System.exit(1);
}
StreamingExamples.setStreamingLogLevels();
SparkConf sparkConf = new SparkConf().setAppName("JavaKafkaWordCount");
// Create the context with 2 seconds batch size
JavaStreamingContext jssc = new JavaStreamingContext(sparkConf, new Duration(2000));
int numThreads = Integer.parseInt(args[3]);
Map<String, Integer> topicMap = new HashMap<>();
String[] topics = args[2].split(",");
for (String topic: topics) {
topicMap.put(topic, numThreads);
}
JavaPairReceiverInputDStream<String, String> messages =
KafkaUtils.createStream(jssc, args[0], args[1], topicMap);
JavaDStream<String> lines = messages.map(Tuple2::_2);
JavaDStream<String> words = lines.flatMap(x -> Arrays.asList(SPACE.split(x)).iterator());
JavaPairDStream<String, Integer> wordCounts = words.mapToPair(s -> new Tuple2<>(s, 1))
.reduceByKey((i1, i2) -> i1 + i2);
wordCounts.print();
jssc.start();
jssc.awaitTermination();
}
}
&#13;
创建SparkConf
对象后,会创建JavaStreamingContext
。
然后它定义了执行WordCount所需的所有功能,并启动JavaStreamingContext
。之后,它永远不会回到wordCount.print()
,但它会继续打印。怎么可能?当JSSC从INITIALIZED切换到ACTIVE时会发生什么?它是循环还是什么?
答案 0 :(得分:2)
在内部,Spark Streaming使用调度程序执行所有已注册的“输出操作”。
'输出操作'是导致声明的流转换实现的操作,这些转换在Spark中是惰性的。
在问题中代码的特定情况下,wordCounts.print();
是这样的“输出操作”,它将在Spark Streaming调度程序中注册,使其在每个“批处理间隔”执行。 “批处理间隔”是在创建流式上下文时定义的。回到上面的代码:new JavaStreamingContext(sparkConf, new Duration(2000));
'批处理间隔'
是2000毫秒或2秒。
简而言之:
每2秒,Spark Streaming将触发wordCounts.print()
的执行,而map
又会使用该间隔的数据实现DStream的评估。实现过程将在DStream(和底层RDD)上应用所有已定义的转换,例如同一代码中的flatMap
,mapToPair
和session["devise.user_attributes"] = user.attributes
操作。