Некоторые проблемы с сериализацией при использовании чтения spark из hbase

#apache-spark #hbase

#apache-искра #hbase

Вопрос:

Я хочу реализовать class функцию have, которая считывает данные из hbase с помощью spark, например:

 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 не является статическим, я получу некоторые ошибки: эти классы не сериализуются.

Почему эти классы должны быть статическими? Есть ли у меня другие способы решения этой проблемы? спасибо.

Ответ №1:

Вы можете попробовать установить 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 в main или в любом статическом методе? При использовании static ваши поля совместно используются во всех инстансах. Но это зависит от ваших вариантов использования, если static их следует использовать.

Но с transient way это лучше, чем static потому, что сериализация JavaSparkCOntext не имеет смысла, потому что это создается в драйвере.


— редактировать после обсуждения в комментарии:

java-документ для 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.

Комментарии:

1. я тестирую переходный процесс в hbaseconf, но в режиме кластера это произойдет с ошибкой, что класс не найден для конфигурации hbase, если я использую static, не хава этой проблемы. знаете ли вы общий процесс, который spark соединяет hbase? я понимаю, что если я не использую static, каждый узел должен создавать hbaseconf в локальной JVM, зачем spark сериализовать hbaseconf?

2. 1, Используете ли вы newAPIHadoopRDD в public abstract RDDResult query(); реализации в дочернем элементе? 2, вы сказали «класс не найден для конфигурации hbase» — какой класс не был найден?

3. 1. да, я использую newAPIHadoopRDD в реализации query() в дочернем элементе.

4. 2. класс является встроенным ‘org.apache.hadoop.conf. Конфигурация ‘

5. 2. класс ‘org.apache.hadoop.conf. Конфигурация ‘