我正在尝试使用Spark(在Scala中)。我有一个Transformer
类看起来像这样:
class Transformer(transformerParameters: TransformerParameters) {
// Process the parameters
def transform(element: String): String = {
// Do stuff
}
}
我想做点什么
val originalRDD = sc.textFile("blah")
val transformer = new Transformer(parameters)
val transformedRDD = originalRDD.map(transformer.transform)
假设我不想或不能使Transformer
类可序列化,并且进一步假设TransformerParameters
实际上是可序列化的,我看到人们建议改写(或者我可以误解了):
val transformedRDD = originalRDD.map(new Transformer(parameters).transform)
我可以在群集的每个JVM上创建一个新的Transformer
实例,但看起来这会为每一行创建一个新的Transformer
,这似乎是不必要的,而且可能非常昂贵。这实际上是它的作用吗?有没有办法不为每一行创建一个新实例?
谢谢!
答案 0 :(得分:2)
您可以(隐式或显式)广播具有参数字段的对象,以及对Transformer的瞬态字段引用。
你有一个方法在这个对象上委托转换Transformer,但首先对Transformer进行延迟初始化(检查Transformer引用是否已初始化,如果没有创建一个带参数,则调用transform)。
在map方法中,然后调用wrapper.transform而不是Transformer.transform - 这会在每次调用时保存对象创建,并解决序列化问题,因为每个任务都会获得它自己的包装器实例,因此它&# 39;自己的Transformer将被重用。