仅使用一个分区设计Spark Streaming App中的缺陷?

时间:2018-04-17 20:17:23

标签: scala apache-spark apache-kafka spark-streaming

我正在使用Apache Spark开发流媒体应用程序。该应用程序通过订阅名为sensor的Kafka主题来接收传感器数据。该应用程序的目的是过滤传感器数据,对其进行转换并将其发布回其他消费者名为people的其他Kafka主题。主题people中的消息必须与主题sensor中的消息具有相同的顺序。因此,我目前在Kafka中只使用一个分区。

这是我的代码:

val myStream = KafkaUtils.createDirectStream[K, V](streamingContext, PreferConsistent, Subscribe[K, V](topics, consumerConfig))

def process(record: (RDD[ConsumerRecord[String, String]], Time)): Unit = record match {
case (rdd, time) if !rdd.isEmpty =>
    // More Code...
    // Filter RDD, transform to JSON, build Seq[People]...
    // In the end, I have: Dataset[People]
    // Publish to Kafka topic 'people'
case _ =>
}

myStream.foreachRDD((x, y) => process((x, y)))

今天,在将其转换为我的People数据结构之后,我问了一个关于如何在Spark中实现正确排序的问题。

answer表示使用单个分区的Spark是不明智的,这实际上可能是一个设计缺陷:

  

除非你有一个分区(然后你不会使用Spark,不是吗?)订单...

我现在想知道我是否可以改进我的应用程序的整体设计(更改map-reduce流程),或者Spark是否适合我的用例。

2 个答案:

答案 0 :(得分:1)

虽然这主要是基于意见的您正在使用专为以下目的而设计的工具

  • 容错,
  • 分布,
  • 平行,
  • 处理,没有特定的订单保证

解决问题定义

  • 顺序,
  • 非分布式
  • 有严格的订单保证,
  • 可能会破坏容错(由于单个执行程序上放置了大量数据)。

其中:

  • 来自容错队列的单线程使用者

完全足够

所以主观地说这里有一个严重的设计缺陷。

答案 1 :(得分:0)

在你的情况下,卡夫卡不是正确的选择。 Kafka仅维护分区内消息的总顺序。 Kafka的并行性或可伸缩性完全取决于特定主题的no:of partitions。缺陷完全与设计有关。

  

如果你真的想保留订单,你可以拥有一个纪元   数据中的时间戳,一旦转换了数据,就可以对其进行排序   数据并存储它。