spark读写HBase之使用hortonworks的开源框架shc(二):入门案例

shc测试环境的搭建参考:
spark读写HBase之使用hortonworks的开源框架shc(一):源码编译以及测试工程创建

读写HBase需要两个核心的元素:

  • 用户描述数据结构的schema字符串
  • 与schema字符串相对应的实体类

1. 定义schema字符串

object Catalog {

  val schema = s"""{
                  |   "table":{"namespace":"default", "name":"test1", "tableCoder":"PrimitiveType"},
                  |   "rowkey":"key",
                  |   "columns":{
                  |       "col0":{"cf":"rowkey", "col":"key", "type":"string"},
                  |       "col1":{"cf":"cf1", "col":"col1", "type":"boolean"},
                  |       "col2":{"cf":"cf2", "col":"col2", "type":"double"},
                  |       "col3":{"cf":"cf3", "col":"col3", "type":"float"},
                  |       "col4":{"cf":"cf4", "col":"col4", "type":"int"},
                  |       "col5":{"cf":"cf5", "col":"col5", "type":"bigint"},
                  |       "col6":{"cf":"cf6", "col":"col6", "type":"smallint"},
                  |       "col7":{"cf":"cf7", "col":"col7", "type":"tinyint"},
                  |       "col8":{"cf":"cf8", "col":"col8", "type":"byte"}
                  |   }
                  |}""".stripMargin

}

schema字符串说明:

2. 定义与schema字符串对应的实体类

case class HBaseRecord(
      col0: String,  // sql: string
      col1: Boolean, // sql: boolean
      col2: Double, // sql: double
      col3: Float, // sql: float
      col4: Int, // sql: int
      col5: Long, // sql: bigint
      col6: Short, // sql: smallint
      col7: Byte, // sql: tinyint
      col8: Array[Byte]) // sql: byte

  object HBaseRecord {
    def apply(i: Int): HBaseRecord = {
      HBaseRecord(i + "",
        i % 2 == 0,
        i.toDouble,
        i.toFloat,
        i,
        i.toLong,
        i.toShort,
        i.toByte,
        (i + "").getBytes("UTF-8"))
    }
  }

3. 写数据到HBase表完整代码

import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.execution.datasources.hbase.HBaseTableCatalog

/**
  * Author: YangYunhe
  * Description: 
  * Create: 2018/8/17 12:54
  */
object WriteHBase {

  def main(args: Array[String]): Unit = {

    val spark = SparkSession.builder().appName("WriteHBase").getOrCreate()
    val sc = spark.sparkContext
    val sqlContext = spark.sqlContext
    import sqlContext.implicits._

    // 模拟一批数据
    val data = (0 to 9).map(HBaseRecord(_))

    // 写数据
    sc.parallelize(data)
      .toDF
      .write
      .options(Map(HBaseTableCatalog.tableCatalog -> Catalog.schema, HBaseTableCatalog.newTable -> "5"))
      .format("org.apache.spark.sql.execution.datasources.hbase")
      .save()

    spark.stop()

  }

}

说明:

Map(HBaseTableCatalog.tableCatalog -> Catalog.schema, HBaseTableCatalog.newTable -> "5")

这个代码意味着HBase表是不存在的,也就是我们在schema字符串中定义的"test1"这个表不存在,程序帮我们自动创建,5是region的个数,如果你提前创建好了表,那么这里的代码是这样的:

Map(HBaseTableCatalog.tableCatalog -> Catalog.schema)

当表存在的时候,数据会追加进去。

执行完以上程序后,检查一下hbase表中的内容:

hbase(main):003:0> scan 'test1'
ROW                                         COLUMN+CELL                                                                                                                 
 0                                          column=cf1:col1, timestamp=1534732543615, value=\xFF                                                                        
 0                                          column=cf2:col2, timestamp=1534732543615, value=\x00\x00\x00\x00\x00\x00\x00\x00                                            
 0                                          column=cf3:col3, timestamp=1534732543615, value=\x00\x00\x00\x00                                                            
 0                                          column=cf4:col4, timestamp=1534732543615, value=\x00\x00\x00\x00                                                            
 0                                          column=cf5:col5, timestamp=1534732543615, value=\x00\x00\x00\x00\x00\x00\x00\x00                                            
 0                                          column=cf6:col6, timestamp=1534732543615, value=\x00\x00                                                                    
 0                                          column=cf7:col7, timestamp=1534732543615, value=\x00                                                                        
 0                                          column=cf8:col8, timestamp=1534732543615, value=0                                                                           
 1                                          column=cf1:col1, timestamp=1534732543615, value=\x00                                                                        
 1                                          column=cf2:col2, timestamp=1534732543615, value=?\xF0\x00\x00\x00\x00\x00\x00
 ......

说明:程序本地执行会报以下错误

java.lang.IllegalArgumentException: Pathname /C:/Users/bonc/AppData/Local/Temp/spark-9fa1e56c-ce87-43e8-a936-f947b62e1af5/outputDataset/.spark-staging-5 
from C:/Users/bonc/AppData/Local/Temp/spark-9fa1e56c-ce87-43e8-a936-f947b62e1af5/outputDataset/.spark-staging-5 is not a valid DFS filename.

这是因为本地运行把临时文件夹创建在本地,而删除临时文件夹时认为这个文件夹是一个HDFS的路径,所以报错,这个错误不影响读写数据,当在集群上跑这个程序就不会报错

4. 从HBase表读数据完整代码

import org.apache.spark.sql.{DataFrame, SparkSession}
import org.apache.spark.sql.execution.datasources.hbase.HBaseTableCatalog

/**
  * Author: YangYunhe
  * Description: 
  * Create: 2018/8/20 10:41
  */
object ReadHBase {

  def main(args: Array[String]): Unit = {

    val spark = SparkSession.builder().appName("ReadHBase").master("local").getOrCreate()
    val sc = spark.sparkContext
    val sqlContext = spark.sqlContext
    import sqlContext.implicits._

    val df: DataFrame = sqlContext
      .read
      .options(Map(HBaseTableCatalog.tableCatalog -> Catalog.schema))
      .format("org.apache.spark.sql.execution.datasources.hbase")
      .load()

    df.createOrReplaceTempView("test1")

    spark.sql("select * from test1").show()

    spark.stop()

  }

}

执行结果如下:

+----+-----+----+----+----+----+----+----+----+
|col0| col1|col2|col3|col4|col5|col6|col7|col8|
+----+-----+----+----+----+----+----+----+----+
|   0| true| 0.0| 0.0|   0|   0|   0|   0|  48|
|   1|false| 1.0| 1.0|   1|   1|   1|   1|  49|
|   2| true| 2.0| 2.0|   2|   2|   2|   2|  50|
|   3|false| 3.0| 3.0|   3|   3|   3|   3|  51|
|   4| true| 4.0| 4.0|   4|   4|   4|   4|  52|
|   5|false| 5.0| 5.0|   5|   5|   5|   5|  53|
|   6| true| 6.0| 6.0|   6|   6|   6|   6|  54|
|   7|false| 7.0| 7.0|   7|   7|   7|   7|  55|
|   8| true| 8.0| 8.0|   8|   8|   8|   8|  56|
|   9|false| 9.0| 9.0|   9|   9|   9|   9|  57|
+----+-----+----+----+----+----+----+----+----+

我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1l56pocon0wmn

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容