#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
повторно, вам нужно убедиться, что вы не будете изменять conf. Безопасный подход всегда заключается в создании нового conf для нового RDD.
to create multiple RDDs
Трансляция:
Широковещательные переменные позволяют программисту сохранять переменную, доступную только для чтения, в кэше на каждом компьютере, а не отправлять ее копию с задачами.
Так что в принципе я думаю, что для этого случая 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. Конфигурация ‘