spark 获取广播变量_为什么在Spark Streaming中读取广播变量在运行几天后得到异常?...

I am using Spark Streaming (Spark V1.6.0) along with HBase in my project, and HBase(HBase V1.1.2) configurations are transferred among executors with broadcast variable. The Spark Streaming application works at first, while about 2 days later, exception will appear.

val hBaseContext: HBaseContext = new HBaseContext(sc, HBaseCock.hBaseConfiguration())

private def _materialDStream(dStream: DStream[(String, Int)], columnName: String, batchSize: Int) = {

hBaseContext.streamBulkIncrement[(String, Int)](

dStream,

hTableName,

(t) => {

val rowKey = t._1

val incVal = t._2

val increment = new Increment(Bytes.toBytes(rowKey))

increment.addColumn(Bytes.toBytes(hFamily), Bytes.toBytes(columnName), incVal)

increment

}, batchSize)

}

Whole source file for HBaseContext could be found HBaseContext.scala, and some snippets could be found below.

And after days of running, exception will appear and the stack trace is:

Unable to getConfig from broadcast

16/02/01 10:08:10 ERROR Executor: Exception in task 3.0 in stage 187175.0 (TID 561527)

The logic is as follows:

Create HBaseContext with config (HBaseContext) and broadcast the config (save the config to file if file path is specified)

Before connecting HBase, first it will check if the field config is null, and if so, restore it from the specified file, or if no file path is specified, restore it from the broadcast variable.

The problem happens when restoring configuration from broadcast variables, and exception happens reading value from broadcast, in "configBroadcast.value.value".

I guess if Spark Streaming won't restore the broadcast variables if master failed, while the getOrCreate() is used to get a SparkStreaming instance. I am more curious about in HBaseContext.scala source code, that file is preferred to broadcast variable to restore values. So what is the best practise using broadcast in Spark Streaming? Do I need to store them in files, say files in HDFS?

class HBaseContext(@transient sc: SparkContext, @transient config: Configuration, val tmpHdfsConfgFile: String = null) extends Serializable{

@transient var tmpHdfsConfiguration: Configuration = config

val broadcastedConf = sc.broadcast(new SerializableWritable(config))

if(tmpHdfsConfgFile != null && config != null){

// save config to file

}

private def getConf(configBroadcast: Broadcast[SerializableWritable[Configuration]]): Configuration = {

if (tmpHdfsConfiguration != null) {

tmpHdfsConfiguration

} else if (tmpHdfsConfgFile != null) {

// read config from file

tmpHdfsConfiguration

}

if (tmpHdfsConfiguration == null) {

try {

// Exception happens here!!!

tmpHdfsConfiguration = configBroadcast.value.value

tmpHdfsConfiguration

} catch {

case ex: Exception => {

println("Unable to getConfig from broadcast")

}

}

}

tmpHdfsConfiguration

}

}

解决方案

Broadcast variables are reset after spark job is restarted for some reason. Or Driver is re-associated with attempt after job failure.

In case of streaming job, to use broadcast variable one should initialize the broadcast from sprarkContext just before creating StreamingContext. This will ensure the broadcast variables are available when the streaming starts.

JavaSparkContext javaSparkContext = createSparkContext();

Broadcast broadcastContext = getBroadcastContext(javaSparkContext);

JavaStreamingContext javaStreamingContext = JavaStreamingContext.getOrCreate(sparkCheckPointDir,

() -> processor.create(sparkCheckPointDir, javaSparkContext));

### 回答1: 动态广播变量Spark Streaming非常有用的功能。它可以让我们在流处理过程动态地更新广播变量的值,从而提高程序的性能和灵活性。 在Spark Streaming,我们可以使用SparkContext的broadcast方法来创建广播变量。然后,我们可以在DStream的foreachRDD方法使用广播变量来进行一些计算。 当我们需要动态地更新广播变量的值时,我们可以使用Spark Streaming的transform方法。这个方法可以让我们在DStream使用任意的RDD转换操作,包括更新广播变量的值。 例如,我们可以使用transform方法来读取一个外部的配置文件,并将其转换为一个广播变量。然后,我们可以在DStream的foreachRDD方法使用这个广播变量来进行一些计算。当配置文件发生变化时,我们可以重新读取它,并使用transform方法来更新广播变量的值。 总之,动态广播变量Spark Streaming非常有用的功能,可以帮助我们提高程序的性能和灵活性。 ### 回答2: Spark Streaming的动态广播变量允许我们将一个可变的变量发送到Spark集群的每个节点上,并在每个节点上更新它。这使得我们能够在流数据处理过程共享和更新全局状态。 动态广播变量使用步骤如下: 1. 创建一个广播变量使用SparkContext的broadcast方法将一个可变的变量广播到整个集群。例如,可以将一个关键字列表广播Spark Streaming的每个节点上。 2. 在转换操作使用广播变量:在Spark Streaming的转换操作可以通过使用广播变量的value属性来访问广播变量的值。例如,在DStream的foreachRDD操作可以访问广播变量并执行与广播变量相关的计算。 3. 更新广播变量:通过在driver程序修改广播变量的值,然后使用新值再次调用广播方法来更新广播变量的内容。这样,新值将在下一次广播时传播到集群的每个节点。 使用动态广播变量的好处是可以将一些全局状态共享到整个Spark Streaming应用程序,而无需将其传递给每个节点。这样可以减少网络传输的开销,并提高应用程序的性能。 总结起来,动态广播变量Spark Streaming管理全局状态的一个强大工具。它可以实现在流数据处理过程对全局状态进行共享和更新,从而提高应用程序的性能和效率。 ### 回答3: Spark Streaming的动态广播变量是一种在Spark Streaming作业共享变量的机制。它可以用于将某个变量广播给所有的工作节点,这样每个节点都可以在本地访问该变量而不需要通过网络传输。动态广播变量在一些需要频繁更新的场景特别有用。 在Spark Streaming,要使用动态广播变量,需要首先创建一个Broadcast变量,并通过前端驱动程序将其广播到所有工作节点。然后,在每个工作节点的任务,可以直接引用该变量而不需要序列化和传输。 动态广播变量使用步骤如下: 1. 在Spark Streaming应用程序的驱动程序,通过创建一个共享的变量Broadcast来定义需要广播变量。 2. 使用Spark Streaming的dstream.foreachRDD方法迭代每一个RDD。 3. 在每一个RDD的foreachPartition方法内,通过调用Broadcast.value方法访问广播变量。 这样,每个工作节点都可以在本地获取广播变量,而无需将变量从驱动程序传输到工作节点。 动态广播变量Spark Streaming的应用场景非常广泛,例如在进行实时机器学习或实时数据分析时,可以使用动态广播变量来保存模型参数或预定义的规则等,以便在每个工作节点上进行使用,提高计算的效率和性能。 总的来说,Spark Streaming动态广播变量使用可以帮助我们在作业共享变量,并且在处理实时数据时提高作业的效率和性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值