当我使用从hbase读取spark时序列化的一些问题

时间:2016-10-13 15:10:34

标签: apache-spark hbase

我想实现一个class有一个函数,可以通过spark读取hbase,如下所示:

public abstract class QueryNode implements Serializable{
  private static final long serialVersionUID = -2961214832101500548L;
  private int id;
  private int parent;
  protected static Configuration hbaseConf;
  protected static Scan scan;
  protected static JavaSparkContext sc;
  public abstract RDDResult query();
  public int getParent() {
      return parent;
  }

  public void setParent(int parent) {
      this.parent = parent;
  }

  public int getId() {
      return id;
  }

  public void setId(int id) {
      this.id = id;
  }
  public void setScanToConf() {
     try {
          ClientProtos.Scan proto = ProtobufUtil.toScan(scan);
          String scanToString = Base64.encodeBytes(proto.toByteArray());
          hbaseConf.set(TableInputFormat.SCAN, scanToString);
      } catch (IOException e) {
        e.printStackTrace();
      }
  }}

这是一个父类,我有一些子类实现了从hbase读取的menthod query(),但如果我设置ConfigurationScanJavaSparkContext不是静态的,我会收到一些错误:这些类没有序列化

为什么这些类必须是静态的?我有其他方法可以解决这个问题吗? THKS。

1 个答案:

答案 0 :(得分:0)

您可以尝试为这些字段设置transient以避免序列化异常,例如

  

引起:java.io.NotSerializableException:   org.apache.spark.streaming.api.java.JavaStreamingContext

所以你对java说你只是不想序列化这些字段:

  protected transient Configuration hbaseConf;
  protected transient Scan scan;
  protected transient JavaSparkContext sc;

您是在main或任何静态方法中初始化JavaSparkContextConfigurationScan吗?使用静态,您的字段将在所有实例中共享。但是,如果应该使用static,则取决于您的使用情况。

但是使用transient方式,它优于static,因为JavaSparkCOntext序列化没有意义,因为这是在驱动程序上创建的。

- 在评论讨论后编辑

java doc for newAPIHadoopRDD

public <K,V,F extends org.apache.hadoop.mapreduce.InputFormat<K,V>> JavaPairRDD<K,V> newAPIHadoopRDD(org.apache.hadoop.conf.Configuration conf,
                                                                                            Class<F> fClass,
                                                                                            Class<K> kClass,
                                                                                            Class<V> vClass)
  

conf - 用于设置数据集的配置。注意:这个会   被放入广播。因此,如果您打算重复使用此conf to create multiple RDDs,则需要确保不会修改   CONF 即可。一种安全的方法是始终为新的创建新的conf   RDD

广播:

  

广播变量允许程序员在每台计算机上保留只读变量缓存 ,而不是随副本一起发送它的副本。

所以基本上我认为对于那种情况static是可以的(你只创建一次hbaceConf),但是如果你想避免static,你可以按照javadoc中的建议来总是为了一个新的conf而烦恼一个新的RDD。