我正在播放一个hashmap并从下面的方法返回一个地图
public static Map<Object1, Object2> lkpBC (JavaSparkContext ctx, String FilePath) {
Broadcast<Map<Object1, Object2>> CodeBC = null;
Map<Object1, Object2> codePairMap=null;
try {
Map<Object1, Object2> CodepairMap = LookupUtil.loadLookup(ctx, FilePath);
CodeBC = ctx.broadcast(codePairMap);
codePairMap= CodeBC.value();
} catch (Exception e) {
LOG.error("Error while broadcasting ", e);
}
return codePairMap;
}
并将地图传递给下面的方法
public static JavaRDD<Object3> fetchDetails(
JavaSparkContext ctx,
JavaRDD<Object3> CleanFileRDD,
String FilePath,
Map<Object1, Object2> BcMap
) {
JavaRDD<Object3r> assignCd = CleanFileRDD.map(row -> {
object3 FileData = null;
try {
FileData = row;
if (BCMap.containsKey("some key")) {......}
} catch (Exception e) {
LOG.error("Error in Map function ", e);
}
return some object;
});
return assignCd;
}
在本地模式下它没有任何问题,但是当我在EC2上的一个火花独立集群(1个主3个从服务器)上运行它时,这不会获取任何值也不会引发错误。您在方法中看到的所有对象都是序列化的。如果我从主类或任何其他不同的类调用这些方法,这是否重要?
PS:我们在spark conf中使用Kyro序列化器
答案 0 :(得分:3)
我认为你正在进行的是你没有在map函数的闭包内访问广播变量。我认为你是直接访问基础BcMap
(或BCMap
,不确定它们是否应该是不同的。)
行if (BCMap.containsKey("some key"))
无法访问广播变量CodeBC
。由于BCMap
的类型似乎是Map
,而不是Broadcast
。
要访问广播变量,您可以拨打CodeBC.value.containsKey
。
Spark是以功能性的方式设计的,它没有&#34;做&#34;做&#34;对底层地图的任何内容,它都会复制它,广播副本,并以Broadcast
类型包装该副本。
我不知道LookupUtil.loadLookup
做了什么,但我想如果该文件不存在或为空,它会返回一张空地图吗?
以下是如何在Scala中执行此操作的示例:
val bcMap = ctx.broadcast(LookupUtil.loadLookup(ctx, FilePath))
cleanFileRDD.map(row =>
if (bcMap.value.containsKey("some key") ...
else ...)
我认为你会按照我的一个朋友的明智的话来解决你的情况;首先解决所有明显的问题,然后更难的问题似乎解决了自己&#34;。在你的情况下,他们是:
仅仅因为某些在本地工作并不意味着它在分发时会起作用。在本地运行和跨集群运行之间存在很多差异,例如:a)数据局部性b)序列化c)关闭捕获d)线程数e)执行顺序......等