Hbase 火花序列化错误

Hbase 火花序列化错误,hbase,apache-spark,Hbase,Apache Spark,我正在努力学习spark+scala。我想从HBase读取,但不需要mapreduce。 我创建了一个简单的HBase表“test”,并在其中进行了3次输入。我想通过spark阅读它(没有使用mapreduce的HBaseTest)。我尝试在shell上运行以下命令 val numbers = Array( new Get(Bytes.toBytes("row1")), new Get(Bytes.toBytes("row2")), new Get(Bytes.toBytes("

我正在努力学习spark+scala。我想从HBase读取,但不需要mapreduce。 我创建了一个简单的HBase表“test”,并在其中进行了3次输入。我想通过spark阅读它(没有使用mapreduce的HBaseTest)。我尝试在shell上运行以下命令

val numbers = Array(
  new Get(Bytes.toBytes("row1")), 
  new Get(Bytes.toBytes("row2")), 
  new Get(Bytes.toBytes("row3")))
val conf = new HBaseConfiguration()
val table = new HTable(conf, "test")
sc.parallelize(numbers, numbers.length).map(table.get).count()
我总是出错- org.apache.spark.sparkeexception:作业中止:任务不可序列化:java.io.notserializableeexception:org.apache.hadoop.hbase.HBaseConfiguration

有人能帮我吗,我如何创建一个使用可序列化配置的Htable


谢谢

当你这样做时会发生什么

@transientval conf=新的HBaseConfiguration

更新显然,HBase提交任务的其他部分也不可序列化。每一个问题都需要解决

  • 考虑实体在连线两侧是否具有相同的含义/语义。任何连接都不会。不应序列化HBaseConfiguration。但是基本体和构建在基本体之上的简单对象(不包含上下文敏感数据)可以包含在序列化中

  • 对于上下文敏感的实体(包括HBaseConfiguration和任何面向连接的数据结构),应将它们标记为@transient,然后在readObject()方法中,应使用与客户端环境相关的值实例化它们


您的问题是
不可序列化(而是它的成员
conf
),您试图通过在
映射中使用它来序列化它。他们认为您尝试读取HBase的方式不太正确,看起来您尝试了一些特定的Get,然后尝试并行执行。即使您确实做到了这一点,这也不会随着您执行随机读取而扩展。您要做的是使用Spark执行表扫描,下面是一段代码片段,可以帮助您完成此操作:

val conf = HBaseConfiguration.create()
conf.set(TableInputFormat.INPUT_TABLE, tableName)

sc.newAPIHadoopRDD(conf, classOf[TableInputFormat],
  classOf[org.apache.hadoop.hbase.io.ImmutableBytesWritable],
  classOf[org.apache.hadoop.hbase.client.Result])
这将为您提供一个RDD,其中包含构成行的NaviagableMap。以下是如何将NaviagbleMap更改为字符串的普通Scala映射:

...
.map(kv => (kv._1.get(), navMapToMap(kv._2.getMap)))
.map(kv => (Bytes.toString(kv._1), rowToStrMap(kv._2)))

def navMapToMap(navMap: HBaseRow): CFTimeseriesRow =
  navMap.asScala.toMap.map(cf =>
    (cf._1, cf._2.asScala.toMap.map(col =>
      (col._1, col._2.asScala.toMap.map(elem => (elem._1.toLong, elem._2))))))

def rowToStrMap(navMap: CFTimeseriesRow): CFTimeseriesRowStr =
  navMap.map(cf =>
    (Bytes.toString(cf._1), cf._2.map(col =>
      (Bytes.toString(col._1), col._2.map(elem => (elem._1, Bytes.toString(elem._2)))))))

最后一点,如果您确实想尝试并行执行随机读取,我相信您可能能够将HBase表初始化放在
映射中

您好,尝试一下。现在错误是-org.apache.spark.SparkException:Job aborted:Task not serializable:java.io.notserializableeexception:org.apache.hadoop.hbase.client.Get需要一些机制,我可以通过这些机制来创建serializablehm类,它应该可以在@javadba工作,你从哪里学到的?我读了这篇文章,它说它应该可以工作(也请参见)@user3529980尝试在
val表
上方添加@transient,并将
new Get
移动到lambda中
Get
也不能序列化,因此您需要在lamda中创建
Get
。@samthebest感谢您的补充意见。我已经更新了我的答案,以获得一些一般性的提示。您好,很抱歉延迟了回复。我想尝试这种阅读方式,你能帮我用一种可序列化的方式定义这个类吗。我想尝试分发密钥,并将其性能与标准方式进行比较。任何这样做的想法都将受到极大的赞赏。