Spark導入導出Hbase

本文代碼通過spark-shell運行

spark-shell --master yarn --driver-class-path /home/hadoop/software/spark/spark-2.4.4-bin-hadoop2.7/jars/hbase/*:/home/hadoop/software/hbase-1.4.10/conf

1.Put API

Put API可能是將數據快速導入HBase表的最直接的方法。但是在導入大量數據時不建議使用!但是可以作爲簡單數據遷移的選擇,直接寫個代碼批量處理,開發簡單、方便、可控強。

使用saveAsHadoopDataset寫入數據

// 這裏我在spark-shell,所以沒有引用SparkContext和SparkConf
import org.apache.hadoop.hbase.HBaseConfiguration
import org.apache.hadoop.hbase.client.Put
import org.apache.hadoop.hbase.io.ImmutableBytesWritable
import org.apache.hadoop.hbase.mapred.TableOutputFormat
import org.apache.hadoop.hbase.util.Bytes
import org.apache.hadoop.mapred.JobConf

val conf = HBaseConfiguration.create()
//設置連接的節點和端口,也可以將hbase-site.xml導入classpath
conf.set("hbase.zookeeper.quorum","master,slave1,slave2")
conf.set("hbase.zookeeper.property.clientPort","2181")
val tablename = "info"
val jobConf = new JobConf(conf)
jobConf.setOutputFormat(classOf[TableOutputFormat])
jobConf.set(TableOutputFormat.OUTPUT_TABLE,tablename)
val indataRDD = sc.makeRDD(Array("1,Jack,15","2,Lily,16","3,Mike,16"))
val rdd = indataRDD.map(_.split(",")).map{arr=>{
	// Put建立一行,並輸入指定的rowkey--主鍵
	val put = new Put(Bytes.toBytes(arr(0).toInt))
	// 所有數據需要通過toBytes轉換 按照格式:(列簇,列名,數據)
	put.add(Bytes.toBytes("cf"),Bytes.toBytes("name"),Bytes.toBytes(arr(1)))
	put.add(Bytes.toBytes("cf"),Bytes.toBytes("age"),Bytes.toBytes(arr(2).toInt))
	// 轉化成RDD[(ImmutableBytesWritable,Put)]類型才能調用saveAsHadoopDataset
	(new ImmutableBytesWritable,put)
}}
rdd.saveAsHadoopDataset(jobConf)

使用saveAsNewAPIHadoopDataset寫入數據

import org.apache.hadoop.hbase.HBaseConfiguration
import org.apache.hadoop.hbase.mapreduce.TableOutputFormat
import org.apache.spark._
import org.apache.hadoop.mapreduce.Job
import org.apache.hadoop.hbase.io.ImmutableBytesWritable
import org.apache.hadoop.hbase.client.Result
import org.apache.hadoop.hbase.client.Put
import org.apache.hadoop.hbase.util.Bytes

val tablename = "account"
sc.hadoopConfiguration.set("hbase.zookeeper.quorum","master,slave1,slave2")
sc.hadoopConfiguration.set("hbase.zookeeper.property.clientPort","2181")
sc.hadoopConfiguration.set(TableOutputFormat.OUTPUT_TABLE,tablename)
val job = new Job(sc.hadoopConfiguration)
job.setOutputKeyClass(classOf[ImmutableBytesWritable])
job.setOutputValueClass(classOf[Result])
job.setOutputFormatClass(classOf[TableOutputFormat[ImmutableBytesWritable]])
val inputRDD = sc.makeRDD(Array("1,Jack,15","2,Lily,16","3,Mike,16"))
val rdd = innputRDD.map(_.split(',')).map{arr=>{
	val put = new Put(Bytes.toBytes(arr(0)))
	put.add(Bytes.toBytes("cf"),Bytes.toBytes("name"),Bytes.toBytes(arr(1)))
	put.add(Bytes.toBytes("cf"),Bytes.toBytes("age"),Bytes.toBytes(arr(2)))
	(new ImmutableBytesWritable,put)
}}
rdd.saveAsNewAPIHadoopDataset(job.getConfiguration())

從hbase讀取數據轉化爲RDD

import org.apache.hadoop.hbase.{HBaseConfiguration,HTableDescriptor,TableName}
import org.apache.hadoop.hbase.client.HBaseAdmin
import org.apache.hadoop.hbase.mapreduce.TableInputFormat
import org.apache.spark._
import org.apache.hadoop.hbase.client.HTable
import org.apache.hadoop.hbase.client.Put
import org.apache.hadoop.hbase.util.Bytes
import org.apache.hadoop.hbase.io.ImmutableBytesWritable
import org.apache.hadoop.hbase.mapreduce.TableOutputFormat
import org.apache.hadoop.mapred.JobConf
import org.apache.hadoop.io._

val tablename = "account"
val conf = HBaseConfiguration.create()
conf.set("hbase.zookeeper.quorum","master,slave1,slave2")
conf.set("hbase.zookeeper.property.clientPort","2181")
conf.set(TableInputFormat.INPUT_TABLE,tablename)
val admin = new HBaseAdmin(conf)
if(!admin,isTableAvailable(tablename)){
	// 表描述:表名
	val tableDesc = new HTableDescriptor(TableName.valueOf(tablename))
	admin.createTable(tableDesc)}
val hBaseRDD = sc.newAPIHadoopRDD(conf,classOf[TableInputFormat],classOf[org.apache.hadoop.hbase.io.ImmutableBytesWritable],classOf[org.apache.hadoop.hbase.client.Result])
val count = hBaseRDD.count()
println(count)
hBaseRDD.foreach{case (_,result)=>{
	val key = Bytes.toString(result.getRow)
	val name = Bytes.toString(result.getValue("cf".getBytes,"name".getBytes))
	
	val age = Bytes.toInt(result.getValue("cf".getBytes,"age".getBytes))
	println("Row key:"+key+" Name:"+name+" Age:"+age)
}}

參考spark將數據寫入hbase以及從hbase讀取數據
未完待續…

2、MapReduce Job
推薦使用sqoop,它的底層實現是mapreduce,數據並行導入的,這樣無須自己開發代碼,過濾條件通過query參數可以實現。
Sqoop是一款開源的工具,主要用於在Hadoop(Hive)與傳統的數據庫(mysql、postgresql…)間進行數據的傳遞,可以將MySQL中的數據導進到Hadoop的HDFS中,也可以將HDFS的數據導進到Mysql中。
參考Index of /docs。
採用如下命令:sqoop import
–connect jdbc:mysql://localhost/db
–username root -P
–table mysql_order
–columns “id,name”
–hbase-table hbase_order
–column-family f
–hbase-row-key id
–query “select id,name from mysql_order where…”
-m 1
3、採用Bulk load裝載數據
bulk-load的作用是用mapreduce的方式將hdfs上的文件裝載到hbase中,對於海量數據裝載入hbase非常有用。
需要將MySQL的表數據導出爲TSV格式(因爲後面使用Import TSV工具),還需要確保有一個字段可以表示HBase錶行的row key。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章