背景
Spark支持多種數(shù)據(jù)源,但是Spark對HBase 的讀寫都沒有相對優(yōu)雅的api,但spark和HBase整合的場景又比較多,故通過spark的DataSource API自己實現(xiàn)了一套比較方便操作HBase的API。
寫 HBase
寫HBase會根據(jù)Dataframe的schema寫入對應數(shù)據(jù)類型的數(shù)據(jù)到Hbase,先上使用示例:
import spark.implicits._
import org.apache.hack.spark._
val df = spark.createDataset(Seq(("ufo", "play"), ("yy", ""))).toDF("name", "like")
// 方式一
val options = Map(
"hbase.table.rowkey.field" -> "name",
"hbase.table.numReg" -> "12",
"hbase.table.rowkey.prefix" -> "00",
"bulkload.enable" -> "false"
)
df.saveToHbase("hbase_table", Some("XXX:2181"), options)
// 方式二
df1.write.format("org.apache.spark.sql.execution.datasources.hbase")
.options(Map(
"hbase.table.rowkey.field" -> "name",
"hbase.table.name" -> "hbase_table",
"hbase.zookeeper.quorum" -> "XXX:2181",
"hbase.table.rowkey.prefix" -> "00",
"hbase.table.numReg" -> "12",
"bulkload.enable" -> "false"
)).save()
上面兩種方式實現(xiàn)的效果是一樣的,下面解釋一下每個參數(shù)的含義:
- hbase.zookeeper.quorum:zookeeper地址
- hbase.table.rowkey.field:spark臨時表的哪個字段作為hbase的rowkey,默認第一個字段
- bulkload.enable:是否啟動bulkload,默認不啟動,當要插入的hbase表只有一列rowkey時,必需啟動
- hbase.table.name:Hbase表名
- hbase.table.family:列族名,默認info
- hbase.table.startKey:預分區(qū)開始key,當hbase表不存在時,會自動創(chuàng)建Hbase表,不帶一下三個參數(shù)則只有一個分區(qū)
- hbase.table.endKey:預分區(qū)開始key
- hbase.table.numReg:分區(qū)個數(shù)
- hbase.table.rowkey.prefix: 當rowkey是數(shù)字開頭,預分區(qū)需要指明前綴的formate形式,如 00
- hbase.check_table: 寫入hbase表時,是否需要檢查表是否存在,默認 false
讀 HBase
示例代碼如下:
// 方式一
import org.apache.hack.spark._
val options = Map(
"spark.table.schema" -> "appid:String,appstoreid:int,firm:String",
"hbase.table.schema" -> ":rowkey,info:appStoreId,info:firm"
)
spark.hbaseTableAsDataFrame("hbase_table", Some("XXX:2181")).show(false)
// 方式二
spark.read.format("org.apache.spark.sql.execution.datasources.hbase").
options(Map(
"spark.table.schema" -> "appid:String,appstoreid:int,firm:String",
"hbase.table.schema" -> ":rowkey,info:appStoreId,info:firm",
"hbase.zookeeper.quorum" -> "XXX:2181",
"hbase.table.name" -> "hbase_table"
)).load.show(false)
spark和hbase表的schema映射關系指定不是必須的,默認會生成rowkey和content兩個字段,content是由所有字段組成的json字符串,可通過field.type.fieldname
對單個字段設置數(shù)據(jù)類型,默認都是StringType。這樣映射出來還得通過spark程序轉一下才是你想要的樣子,而且所有字段都會去掃描,相對來說不是特別高效。
故我們可自定義schema映射來獲取數(shù)據(jù):
- hbase.zookeeper.quorum:zookeeper地址
- spark.table.schema:Spark臨時表對應的schema eg: "ID:String,appname:String,age:Int"
- hbase.table.schema:Hbase表對應schema eg: ":rowkey,info:appname,info:age"
- hbase.table.name:Hbase表名
- spark.rowkey.view.name:rowkey對應的dataframe創(chuàng)建的tempview名(設置了該值后,只獲取rowkey對應的數(shù)據(jù))
注意這兩個schema是一一對應的,Hbase只會掃描hbase.table.schema
對應的列。
源碼在我的 GitHub,歡迎star