我正在尝试从Hbase表中读取所有记录。以下是代码段。
SparkContext sparkContext = new SparkContext(conf);
SQLContext sqlContext = new SQLContext(sparkContext);
Configuration hbaseConf = HBaseConfiguration.create();
hbaseConf.set("hbase.master", "localhost:60000");
hbaseConf.setInt("timeout", 120000);
hbaseConf.set("hbase.zookeeper.quorum", "localhost");
hbaseConf.set("zookeeper.znode.parent", "/hbase-unsecure");
hbaseConf.set(TableInputFormat.INPUT_TABLE, "Test");
DataFrame df = sqlContext.createDataFrame(sparkContext.newAPIHadoopRDD(hbaseConf, TableInputFormat.class, ImmutableBytesWritable.class, Result.class), TestBean.class);
df.registerTempTable("TempTest");
df.show();
在df.show()
我收到错误
java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
任何指针,我为什么要面对这个问题。
答案 0 :(得分:0)
您正在尝试从由对组成的RDD创建DataFrame:
org.apache.hadoop.hbase.io.ImmutableBytesWritable
org.apache.hadoop.hbase.client.Result
您需要阅读hBaseRDD:
val hBaseRDD = sc.newAPIHadoopRDD(hbaseConf, classOf[TableInputFormat],
classOf[org.apache.hadoop.hbase.io.ImmutableBytesWritable],
classOf[org.apache.hadoop.hbase.client.Result]);
然后将(ImmutableBytesWritable,Result)元组转换为Result的RDD:
val resultRDD = hBaseRDD.map(tuple => tuple._2)
然后转换为可以转换为DataFrame的行的RDD。
作为一个例子,我们假设您有一个HBase表,其中一个键包含两个值'value1_value2',您可以使用以下方法解析Key(由'_'分配):
val keyValueRDD = resultRDD.map(result => (Bytes.toString(result.getRow()).split("_")(0), Bytes.toString(result.getRow()).split("_")(1), Bytes.toFloat(result.value())))
现在,您可以使用“_”分隔键中的值创建数据框:
import sqlContext.implicits._
val df = keyValueRDD.toDF("value1", "value2");
df.registerTempTable("Table")
sqlContext.sql("SELECT * FROM Table Limit 5").show()
为了将您的HBase表完全映射到DataFrame,您需要:
创建案例类 :(在您的对象之外)
case class TestRow(rowkey: String, value1: String, value2: String, value3: Float, value4: Float)
将列系列定义为字节:
final val cfTest = "te"
final val cfTestBytes = Bytes.toBytes(cfTest)
解析结果:
object TestRow {
def parseTestRow(result: Result): TestRow = {
val rowkey = Bytes.toString(result.getRow())
val p0 = rowkey
val p1 = Bytes.toString(result.getValue(cfTestBytes, Bytes.toBytes("currency")))
val p2 = Bytes.toString(result.getValue(cfTestBytes, Bytes.toBytes("asat")))
val p3 = Bytes.toFloat(result.getValue(cfTestBytes, Bytes.toBytes("m_aed")))
val p4 = Bytes.toFloat(result.getValue(cfTestBytes, Bytes.toBytes("m_usd")))
TestRow(p0, p1, p2, p3, p4)
}
}
创建数据框
val hBaseRDD = sc.newAPIHadoopRDD(hbaseConf, classOf[TableInputFormat],
classOf[org.apache.hadoop.hbase.io.ImmutableBytesWritable],
classOf[org.apache.hadoop.hbase.client.Result]);
val resultRDD = hBaseRDD.map(tuple => tuple._2)
val testRDD = resultRDD.map(TestRow.parseTestRow)
import sqlContext.implicits._
val testDF = testRDD.toDF()
testDF.registerTempTable("Test")
sqlContext.sql("SELECT count(*) FROM Test").show()