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

cnjp1d6j  于 2021-06-10  发布在  Hbase
关注(0)|答案(1)|浏览(412)

我想实现一个 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();
      }
  }}

这是一个父类,我有一些子类实现了这个方法 query() 从hbase读取,但如果我设置 Configuration , Scan 以及 JavaSparkContext 不是静态的,我会得到一些错误:这些类没有序列化。
为什么这些类必须是静态的?我有别的办法解决这个问题吗?厚度。

e4eetjau

e4eetjau1#

你可以试着 transient 以避免序列化异常,如
原因:java.io.notserializableexception:org.apache.spark.streaming.api.java.javastreamingcontext
所以你对java说你只是不想序列化这些字段:

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

你在初始化吗 JavaSparkContext , Configuration 以及 Scan 主要还是静态方法?使用static,您的字段通过所有示例共享。但这取决于你的用例如果 static 应该使用。
但与 transient 这样比 static 因为 JavaSparkCOntext 没有意义,因为这是在驱动程序上创建的。
--在评论中讨论后编辑:
用于newapihadooprdd的java文档

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。安全的方法总是为新rdd创建新conf。
广播:
广播变量允许程序员在每台机器上缓存一个只读变量,而不是将其副本与任务一起发送。
所以基本上我认为 `static` 可以(只创建一次hbaceconf),但是如果要避免 `static` ,您可以按照javadoc中的建议始终为新rdd创建一个新conf。

相关问题