无法实现Spark函数的顺序执行

时间:2015-02-26 08:27:31

标签: apache-spark spark-streaming

在我们的Spark Pipeline中,我们读取了来自kafka的消息。

JavaPairDStream<byte[],byte[]> = messagesKafkaUtils.createStream(streamingContext, byte[].class, byte[].class,DefaultDecoder.class,DefaultDecoder.class,
                configMap,topic,StorageLevel.MEMORY_ONLY_SER());

我们使用地图功能转换这些消息。

JavaDStream<ProcessedData> lines=messages.map(new Function<Tuple2<byte[],byte[]>, ProcessedData>() 
        {
          public ProcessedData  call(Tuple2<byte[],byte[]> tuple2) 
            {


            }
        });

//这里ProcessedData是我的消息bean类。

在此之后,我们使用foreachRDD函数将此消息保存到Cassandra中。然后我们使用foreachRDD函数在ElasticSearch中索引相同的消息。我们要求的是首先将消息存储在cassandra中并且它成功执行然后仅将其编入索引ElasticSearch。要实现这一点,我们需要顺序执行Cassandra和弹性搜索功能。

我们无法在Cassandra的foreachRDD函数中生成JavaDStream作为ElasticSearch Function的输入。

如果我们在其中使用map函数,我们可以成功执行Cassandra和Elastic Search函数的顺序执行。但是我们的Spark Pipeline中没有Action并且它没有被执行。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

实现此排序的一种方法是将Cassandra插入和ElasticSearch索引放在同一任务中。 粗略地像这样(*):

val kafkaDStream = ???
val processedData = kafkaDStream.map(elem => ProcessData(elem))
val cassandraConnector = CassandraConnector(sparkConf)
processData.forEachRDD{rdd =>
    rdd.forEachPartition{partition => 
        val elasClient = ??? elasticSearch client instance
        partition.foreach{elem => 
            cassandraConnector.withSessionDo(session =>
                 session.execute("INSERT ....")
            }
            elasClient.index(elem) // whatever the client method is called
        }
     }
}

我们牺牲了批处理操作的能力(例如,通过Cassandra-spark连接器在内部完成)以实现排序。

(*)这段代码的Java版本结构非常相似,只是更详细。