使用Spark,从HIVE中获取数据写入HBase过程中遇到的坑

本文分享了在使用Spark处理Hive数据并写入HBase时遇到的问题及解决方案,包括已存在数据库、数据节点信息不一致和表已存在的错误处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在学习大数据的过程中,通过提交spark-submit提交jar包,将hive中的数据写入HBase的过程中遇到诸多问题,与大家分享。

首先,在跑任务的过程中发现错误。

ERROR metastore.RetryingHMSHandler: AlreadyExistsException(message:Database default already exists) 

 

该问题是在创建默认数据库时发现hive中已经创建导致的,该问题可以忽略不计。

后续过程中发现spark的任务一直在accepted状态,查看日志发现提示以下错误:

There are 2 datanode(s) running and no node(s) are excluded in this operation.

该问题的原因是因为进行了hadoop namenode -format导致主节点的$HADOOP_HOME/dfs/name/current文件内的信息和从节点中$HADOOP_HOME/dfs/data/current的信息不一致导致。这两个地址根据配置因人而异,可以参考配置文件hdfs-site.xml文件中的dfs.namenode.name.dir及dfs.datanode.data.dir中所配置的目录。

暴力的处理方式是,首先停掉hadoop记全,分别删除对应的current文件夹下的所有文件。然后执行hadoop namenode -format,然后重新启动集群,之后问题得到解决。

在创建HBase表的时候,提示Table already exists

原因是在删除hdfs后,hbase的元数据在zookeeper集群中仍然有保留。

此时执行,bin/zkCli.sh

ls /hbase/table,查看是否有要新建的表名,如果有使用rmr命令删除,之后重启Hbase,使用create即可成功。

Spark可以通过HiveContext来读取Hive数据,然后通过HBase API将数据写入HBase。具体步骤如下: 1. 创建SparkConf和SparkContext对象。 2. 创建HiveContext对象,通过HiveContext对象读取Hive数据。 3. 将Hive数据转换为RDD。 4. 创建HBaseConfiguration对象,设置HBase相关配置。 5. 创建HBase表,如果表已经存在,则不需要创建。 6. 将RDD中的数据写入HBase表中。 示例代码如下: ``` import org.apache.hadoop.hbase.{HBaseConfiguration, TableName} import org.apache.hadoop.hbase.client.{ConnectionFactory, Put} import org.apache.hadoop.hbase.util.Bytes import org.apache.spark.{SparkConf, SparkContext} import org.apache.spark.sql.hive.HiveContext object SparkHiveToHBase { def main(args: Array[String]): Unit = { val sparkConf = new SparkConf().setAppName("SparkHiveToHBase") val sc = new SparkContext(sparkConf) val hiveContext = new HiveContext(sc) // 读取Hive数据 val df = hiveContext.sql("SELECT * FROM my_table") // 将DataFrame转换为RDD val rdd = df.rdd // 创建HBaseConfiguration对象 val hbaseConf = HBaseConfiguration.create() // 设置HBase相关配置 hbaseConf.set("hbase.zookeeper.quorum", "localhost") hbaseConf.set("hbase.zookeeper.property.clientPort", "2181") // 创建HBase表 val tableName = TableName.valueOf("my_table") val connection = ConnectionFactory.createConnection(hbaseConf) val admin = connection.getAdmin if (!admin.tableExists(tableName)) { val tableDesc = new HTableDescriptor(tableName) tableDesc.addFamily(new HColumnDescriptor("cf".getBytes)) admin.createTable(tableDesc) } // 将RDD中的数据写入HBase表中 rdd.foreachPartition(partition => { val connection = ConnectionFactory.createConnection(hbaseConf) val table = connection.getTable(tableName) partition.foreach(row => { val put = new Put(Bytes.toBytes(row.getString())) put.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("col1"), Bytes.toBytes(row.getString(1))) put.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("col2"), Bytes.toBytes(row.getString(2))) table.put(put) }) table.close() connection.close() }) sc.stop() } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值