我们已经从HBase表创建了一个SparkRDD,现在想要访问它的元素。以下是我们所做的:
val hBaseRDD = sc.newAPIHadoopRDD(conf, classOf[TableInputFormat], classOf[ImmutableBytesWritable], classOf[Result])
println("hbase RDD:")
hBaseRDD.collect().foreach(println)
hBaseRDD
的o / p如下:(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})
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表中获取实际数据?
答案 0 :(得分:1)
收集RDD时,您将获得Array[Result]
您可以将columnFamily
和columnName
作为参数传递给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
函数,然后打印字节数组,直接以原始格式打印值。