Spark整合HBase(自定義HBase DataSource)

背景

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

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容