无法连接
1. 先检查集群中的 HBase 服务、ZooKeeper 服务是否正常启动,有没有挂掉。
2. Spark 中的 HBase 版本是否与集群一致,代码中的相关包是否导入正确。
3. 连接参数(地址、端口)是否设置正确,如下所示:
val hbaseConf: Configuration = HBaseConfiguration.create()
// 本地没配置映射就写ip
hbaseConf.set("hbase.zookeeper.quorum","master,slave1,slave2")
hbaseConf.set("hbase.zookeeper.property.clientPort","2181")
// 可选参数,跳过 HBase 版本不一致的验证
hbaseConf.set("hbase.defaults.for.version.skip","true")
Spark 能正常写入 HBase,但 Spark 读取后数据为空。
先说结论:
Spark 3.3.x
写入 HBase 2.x
中时,数据存储成功(HBase Shell 中可以查询到)。但在代码中查询时,数据量为空,无任何报错提示。这是由于 Spark 版本太高,不兼容,将 Spark 版本更换成 Spark 3.1.x
或 Spark 3.0.x
,问题得到解决,读写都正常。
有趣的故事:
我今天就遇到了这种让我想破头的 BUG!在我使用 Spark 写入 HBase 时,一切都正常,我进入 HBase Shell 界面进行验证,发现刚刚的数据已经写入了进来,如下所示:
于是,我便写了一段 Spark 查询的代码,如下所示:
object ReadHBaseTest {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder().appName("ReadHBaseTest").master("local[*]").getOrCreate()
val hbaseConf: Configuration = HBaseConfiguration.create()
hbaseConf.set("hbase.zookeeper.quorum", "192.168.0.200,192.168.0.201,192.168.0.202")
hbaseConf.set("hbase.zookeeper.property.clientPort", "2181")
hbaseConf.set("hbase.defaults.for.version.skip", "true")
hbaseConf.set(TableInputFormat.INPUT_TABLE,"test")
val hbaseRdd = spark.sparkContext.newAPIHadoopRDD(hbaseConf, classOf[TableInputFormat], classOf[ImmutableBytesWritable], classOf[Result])
println("数据量:",hbaseRdd.count())
import spark.implicits._
hbaseRdd.map{
case (_, result) =>
val row = Bytes.toString(result.getRow)
val name = Bytes.toString(result.getValue("info".getBytes,"name".getBytes))
val sex = Bytes.toString(result.getValue("info".getBytes,"sex".getBytes))
val age = Bytes.toString(result.getValue("info".getBytes,"age".getBytes))
(row,name,sex,age)
}.toDF("row","name","sex","age").show()
spark.stop()
}
}
运行后查询结果如下:
没有任何报错提示,但就是没有数据。
我一度怀疑集群是否出现了故障,可是我查了一圈下来服务都正常,这么简单的查询代码我愣是看了几遍也没有发现啥问题,以前我都这样写的,也没出现问题啊。
正当我毫无头绪的时候,突然想到是不是因为我的 Spark 版本太高(spark 3.3.1
)而导致的。于是,我更换 Spark 的版本为:spark 3.1.1
,你猜这么着?还真是!读出来了!
呜呜呜~