使用Spark RDD在Scala中读取Hbase表值

时间:2018-02-09 09:21:54

标签: scala apache-spark hbase rdd

我们已经从HBase表创建了一个SparkRDD,现在想要访问它的元素。以下是我们所做的:

  1. 创建RDD
  2. val hBaseRDD = sc.newAPIHadoopRDD(conf, classOf[TableInputFormat], classOf[ImmutableBytesWritable], classOf[Result])
    println("hbase RDD:")
    hBaseRDD.collect().foreach(println)
    
    1. hBaseRDD的o / p如下:
    2. (31 30 31,keyvalues={100/f1:id/1518081262631/Put/vlen=3/seqid=0, 
      100/f1:name/1518081278652/Put/vlen=3/seqid=0})
      (31 30 31,keyvalues={101/f1:id/1518081307150/Put/vlen=3/seqid=0, 
      101/f1:name/1518081291946/Put/vlen=3/seqid=0})
      
      1. HBase表中的数据是:
      2.  ROW                      COLUMN+CELL
         100                      column=f1:id, timestamp=1518081262631, value=100
         100                      column=f1:name, timestamp=1518081278652, value=abc
         101                      column=f1:id, timestamp=1518081307150, value=102
         101                      column=f1:name, timestamp=1518081291946, value=def
        

        因此Spark RDD返回HBase表中实际数据的长度,但不返回实际数据本身。如何从HBase表中获取实际数据?

2 个答案:

答案 0 :(得分:1)

收集RDD时,您将获得Array[Result]

您可以将columnFamilycolumnName作为参数传递给Result.getValue方法,以检索每列的值:

hBaseRDD.collect().foreach(r => {
  val columnValue = r.getValue(Bytes.toBytes(columnFamily), Bytes.toBytes(columnName))
})

答案 1 :(得分:0)

您正在做的是隐式调用toString的{​​{1}}方法(代码为here),后者又调用Result方法实现toString 1}}(最可能是Cell,其代码为here)。

如您所见,KeyValue方法的实现不会打印该值,即使它存在。

HBase将所有内容存储为原始字节,因此要完全打印它们,您必须在结果上调用toString方法,然后将其从value解码为您感兴趣的内容。

Array[Byte]

您必须根据您的架构实施def decodeValue(result: Result): Any = ??? hBaseRDD.map(result => s"$result -> ${decodeValue(result)}").foreach(println)

要获得有关如何解码您的价值的一些灵感,您可以查看它们如何解码source code of Eel中的HBase值。

或者,您可以通过调用单元格上的decodeValue方法实现decodeValue函数,然后打印字节数组,直接以原始格式打印值。