我正在尝试使用Spark Kafka Direct Stream方法。它通过创建与kafka主题分区一样多的RDD分区来简化并行性,如此doc中所述。根据我的理解,spark将为每个RDD分区创建一个执行程序来进行计算。
因此,当我以纱线群集模式提交应用程序,并将选项 num-executors 指定为与分区数量不同的值时,将会有多少执行程序?
例如,有一个带有2个分区的kafka主题,我将 num-executors 指定为4:
export YARN_CONF_DIR=$HADOOP_HOME/client_conf
./bin/spark-submit \
--class playground.MainClass \
--master yarn-cluster \
--num-executors 4 \
../spark_applications/uber-spark-streaming-0.0.1-SNAPSHOT.jar \
127.0.0.1:9093,127.0.0.1:9094,127.0.0.1:9095 topic_1
我试一试,发现执行者的数量是4,每个执行者都会从kafka读取和处理数据。为什么? kafka主题中只有2个分区,4个执行程序如何从kafka主题中读取,该主题只有2个分区?
以下是spark应用程序和日志的详细信息。
我的火花应用程序,它会在每个执行程序中从kafka打印收到的消息(在 flatMap 方法中):
...
String brokers = args[0];
HashSet<String> topicsSet = new HashSet<String>(Arrays.asList(args[1].split(",")));
kafkaParams.put("metadata.broker.list", brokers);
JavaPairInputDStream<String, String> messages =
KafkaUtils.createDirectStream(jssc, String.class, String.class, StringDecoder.class, StringDecoder.class,
kafkaParams, topicsSet);
JavaPairDStream<String, Integer> wordCounts =
messages.flatMap(new FlatMapFunction<Tuple2<String, String>, String>()
{
public Iterable<String> call(Tuple2<String, String> tuple) throws Exception
{
System.out.println(String.format("[received from kafka] tuple_1 is %s, tuple_2 is %s", tuple._1(),
tuple._2())); // print the kafka message received in executor
return Arrays.asList(SPACE.split(tuple._2()));
}
}).mapToPair(new PairFunction<String, String, Integer>()
{
public Tuple2<String, Integer> call(String word) throws Exception
{
System.out.println(String.format("[word]: %s", word));
return new Tuple2<String, Integer>(word, 1);
}
}).reduceByKey(new Function2<Integer, Integer, Integer>()
{
public Integer call(Integer v1, Integer v2) throws Exception
{
return v1 + v2;
}
});
wordCounts.print();
Runtime.getRuntime().addShutdownHook(new Thread(){
@Override
public void run(){
System.out.println("gracefully shutdown Spark!");
jssc.stop(true, true);
}
});
jssc.start();
jssc.awaitTermination();
我的Kafka主题,有2个分区。 String &#34; hello hello word 1&#34;,&#34; hello hello word 2&#34;,&#34; hello hello word 3&#34;, ...被发送到话题。
Topic: topic_2 PartitionCount:2 ReplicationFactor:2 Configs:
Topic: topic_2 Partition: 0 Leader: 3 Replicas: 3,1 Isr: 3,1
Topic: topic_2 Partition: 1 Leader: 1 Replicas: 1,2 Isr: 1,2
Webconsle :
执行者1的控制台输出:
...
[received from kafka] tuple_1 is null, tuple_2 is hello hello world 12
[word]: hello
[word]: hello
[word]: world
[word]: 12
...
执行者2的控制台输出:
...
[received from kafka] tuple_1 is null, tuple_2 is hello hello world 2
[word]: hello
[word]: hello
[word]: world
[word]: 2
...
执行者3的控制台输出:
...
[received from kafka] tuple_1 is null, tuple_2 is hello hello world 3
[word]: hello
[word]: hello
[word]: world
[word]: 3
...
答案 0 :(得分:5)
每个分区一次由一个执行程序操作(假设您没有打开推测执行)。
如果你有比执行分区更多的执行程序,那么并非所有执行程序都可以在任何给定的RDD上运行。但正如您所指出的,由于DStream是一系列RDD,随着时间的推移,每个执行程序都会做一些工作。