我正在测试检查点并使用下面的基本Spark流代码预先写入日志。我正在检查一个本地目录。在启动和停止应用程序几次后(使用 Ctrl - C ) - 它将拒绝启动,因为在检查点directoty中看起来像某些数据损坏。我得到了:
org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 80.0 failed 1 times, most recent failure: Lost task 0.0 in stage 80.0 (TID 17, localhost): com.esotericsoftware.kryo.KryoException: Encountered unregistered class ID: 13994
at com.esotericsoftware.kryo.util.DefaultClassResolver.readClass(DefaultClassResolver.java:137)
at com.esotericsoftware.kryo.Kryo.readClass(Kryo.java:670)
at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:781)
at org.apache.spark.serializer.KryoDeserializationStream.readObject(KryoSerializer.scala:229)
at org.apache.spark.serializer.DeserializationStream$$anon$1.getNext(Serializer.scala:169)
at org.apache.spark.util.NextIterator.hasNext(NextIterator.scala:73)
at scala.collection.Iterator$$anon$12.hasNext(Iterator.scala:439)
at scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:408)
at org.apache.spark.util.collection.ExternalSorter.insertAll(ExternalSorter.scala:192)
完整代码:
import org.apache.hadoop.conf.Configuration
import org.apache.spark._
import org.apache.spark.streaming._
object ProtoDemo {
def createContext(dirName: String) = {
val conf = new SparkConf().setAppName("mything")
conf.set("spark.streaming.receiver.writeAheadLog.enable", "true")
val ssc = new StreamingContext(conf, Seconds(1))
ssc.checkpoint(dirName)
val lines = ssc.socketTextStream("127.0.0.1", 9999)
val words = lines.flatMap(_.split(" "))
val pairs = words.map(word => (word, 1))
val wordCounts = pairs.reduceByKey(_ + _)
val runningCounts = wordCounts.updateStateByKey[Int] {
(values: Seq[Int], oldValue: Option[Int]) =>
val s = values.sum
Some(oldValue.fold(s)(_ + s))
}
// Print the first ten elements of each RDD generated in this DStream to the console
runningCounts.print()
ssc
}
def main(args: Array[String]) = {
val hadoopConf = new Configuration()
val dirName = "/tmp/chkp"
val ssc = StreamingContext.getOrCreate(dirName, () => createContext(dirName), hadoopConf)
ssc.start()
ssc.awaitTermination()
}
}
答案 0 :(得分:0)
基本上你要做的是驱动程序故障情况,为此工作,根据你运行的集群,你必须按照下面的说明监控驱动程序进程,如果失败则重新启动驱动程序
配置应用程序驱动程序的自动重新启动 - 要自动从驱动程序故障中恢复,用于运行流应用程序的部署基础结构必须监视驱动程序进程并在驱动程序失败时重新启动驱动程序。不同的cluster managers有不同的工具来实现这一目标。
Spark Standalone - 可以提交Spark应用程序驱动程序 在Spark Standalone集群中运行(参见cluster deploy mode),即应用程序驱动程序本身在其中一个集群上运行 工人节点。此外,独立集群管理器也可以 指示监督司机,如果司机,重新启动它 由于退出代码非零或由于失败而导致失败 运行驱动程序的节点。请参阅集群模式并在Spark中进行监督 独立guide了解更多详情。
YARN - Yarn支持类似的机制来自动重启应用程序。请参阅YARN文档 更多细节。
Mesos - Marathon已用于与Mesos实现这一目标。
您需要配置如下的预写日志,您需要遵循S3的特殊说明。
在使用S3(或任何不支持刷新的文件系统)进行预写日志时,请记得启用
<强> spark.streaming.driver.writeAheadLog.closeFileAfterWrite spark.streaming.receiver.writeAheadLog.closeFileAfterWrite 强>
有关更多详细信息,请参阅Spark Streaming Configuration。
答案 1 :(得分:0)
该问题看起来比Kryo Serializer问题而不是检查点损坏。 在代码示例(包括GitHub项目)中,未配置Kryo序列化。 由于未配置 KryoException 异常无法发生。
当使用“预写日志”并从目录恢复时,所有Spark配置都从那里开始。 在您的示例中,从检查点开始时, createContext 方法不会调用。
我认为问题是另一个应用程序之前使用相同的检查点目录进行了测试,其中配置了Kryo Serializer。 并且当前的应用程序无法从该检查点恢复。