根据this question和我已经阅读过的文档,Spark Streaming的foreachRDD( someFunction )将在 someFunction 中执行驱动程序进程,但如果在RDD上进行了操作,则它们将在执行程序上完成 - RDD所在的位置。
以上所有内容对我来说都有用,虽然我注意到如果我打开检查点,那么似乎spark正在尝试序列化foreachRDD中的所有内容( someFunction )并发送到某个地方 - 这是因为我使用的对象之一是不可序列化的(即schemaRegistryClient)。我试过Kryo序列化器,但也没有运气。
如果我关闭检查点,序列化问题就会消失。
有没有办法让Spark不要序列化foreachRDD( someFunc )中使用的内容,同时还要继续使用检查点?
非常感谢。
答案 0 :(得分:3)
有没有办法让Spark不要序列化foreachRDD(someFunc)中使用的内容,同时还要继续使用检查点?
检查点不应与您的问题有任何关系。根本问题是您有一个非序列化的对象实例需要发送给您的工作人员。
当您具有此类依赖关系时,Spark中会使用一般模式。您创建一个具有延迟瞬态属性的object
,该属性将在需要时加载工作节点:
object RegisteryWrapper {
@transient lazy val schemaClient: SchemaRegisteryClient = new SchemaRegisteryClient()
}
当你需要在foreachRDD
内使用它时:
someStream.foreachRDD {
rdd => rdd.foreachPartition {
iterator => iterator.foreach {
someValue =>
val schemaClient = RegisteryWrapper.schemaClient
schemaClient.send(someValue)
}
}
}
答案 1 :(得分:0)
这里有几件事很重要:
答案 2 :(得分:0)
问题可能出在检查点数据上,如果您更改了代码中的任何内容,则可以删除旧的检查点元数据。