我有一个用例,我必须以FIFO方式处理事件。这些是从机器生成的事件。每台机器每30秒生成一个事件。对于特定的机器,我们需要根据FIFO fasion处理事件。
我们每天需要处理大约2.4亿个事件。对于如此大规模的规模,我们需要使用Kafka + Spark Streaming
从Kafka文档中我了解到我们可以使用消息的关键字段将消息路由到特定的主题分区。这确保了我可以使用机器ID作为密钥,并确保来自特定机器的所有消息都进入相同的主题分区。
50%的问题解决了。
处理方面的问题来了。
Kafka Direct方法的spark文档说RDD分区等同于Kafka分区。
所以当我执行rdd.foreachPartition时,任务是否在有序的时尚中迭代?
是否确保RDD的分区始终位于一个执行程序中?
是否确保foreachPartition任务仅由整个分区的一个线程执行?
请帮忙。
答案 0 :(得分:1)
我们假设您没有使用任何重新分区数据的运算符(例如repartition
,reduceByKey
,reduceByKeyAndWindow
,...)。
所以当我执行rdd.foreachPartition时,任务是否在有序的时尚中迭代?
是。它按照Kafka分区中的顺序处理数据。
是否确保RDD的分区始终位于一个执行程序中?
是。如果您不启用speculation
,则只有一个执行程序(任务)处理分区。 speculation
可能会启动另一项任务来运行相同的分区,如果它太慢的话。
是否确保foreachPartition任务仅由整个分区的一个线程执行?
是。它逐个处理一个分区中的数据。
答案 1 :(得分:0)
从Kafka文档中我了解到我们可以使用消息的关键字段将消息路由到特定的主题分区。这确保了我可以使用机器ID作为密钥,并确保来自特定机器的所有消息都进入相同的主题分区。
在向Kafka发布数据时,您不需要使用计算机ID。使用null作为键,kafka将在内部使用Hash分区方案将数据适当地发送到不同的kafka主机。
处理方面的问题来了。
Gotcha :当你在spark中处理时,它不会有全局顺序。示例:有5个事件(按时间排序):e0(最早),e1,e2,e3,e4(最新)
这些路由到不同的kafka分区:
Kakfa Partition P0: e0, e3
Kafka Partition P1: e1, e2, e4
所以当你在阅读你的火花工作时,你将在一个RDD中获得e0, e3
,在另一个RDD中获得e1, e2, e4
,按顺序。
如果想要全局排序(e0,e1,e2,e3,e4),则需要在kafka中写入单个分区。但是,您将失去分区容错并遇到一些性能问题(需要调整生产者和消费者)。 3000个事件/秒应该没问题,但这也取决于你的kafka集群。
@zsxwing(see)
已经回答了您的其他问题