Spark广播HashMap没有nullpointer但它不会获取任何值

时间:2016-05-27 21:40:05

标签: apache-spark apache-spark-sql spark-streaming

我正在播放一个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序列化器

1 个答案:

答案 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;。在你的情况下,他们是:

  1. 使用初始化为null的可变变量
  2. 使用try catch来记录错误但不要重新抛出它们。只是让异常冒出来。
  3. 在将其作为一种方法工作之前,过早地将事物分解为许多不同的方法。
  4. 仅仅因为某些在本地工作并不意味着它在分发时会起作用。在本地运行和跨集群运行之间存在很多差异,例如:a)数据局部性b)序列化c)关闭捕获d)线程数e)执行顺序......等