Spark DataFrame 写入 HBase 的常用方式
Spark 是目前最流行的分布式计算框架, 而 HBase 则是在 HDFS 之上的列式分布式存储引擎, 基于 Spark 做离线或者实时计算, 数据结果保存在 HBase 中是目前很流行的做法例如用户画像单品画像推荐系统等都可以用 HBase 作为存储媒介, 供客户端使用
因此 Spark 如何向 HBase 中写数据就成为很重要的一个环节了本文将会介绍三种写入的方式, 其中一种还在期待中, 暂且官网即可...
代码在 spark 2.2.0 版本亲测
1. 基于 HBase API 批量写入
第一种是最简单的使用方式了, 就是基于 RDD 的分区, 由于在 spark 中一个 partition 总是存储在一个 excutor 上, 因此可以创建一个 HBase 连接, 提交整个 partition 的内容
大致的代码是:
rdd.foreachPartition{records=>
val config=HBaseConfiguration.create
config.set("hbase.zookeeper.property.clientPort","2181")
config.set("hbase.zookeeper.quorum","a1,a2,a3")
val connection=ConnectionFactory.createConnection(config)
val table=connection.getTable(TableName.valueOf("rec:user_rec"))
// 举个例子而已, 真实的代码根据 records 来
val list=newjava.util.ArrayList[Put]
for(i
val put=newPut(Bytes.toBytes(i.toString))
put.addColumn(Bytes.toBytes("t"),Bytes.toBytes("aaaa"),Bytes.toBytes("1111"))
list.add(put)
}
// 批量提交
table.put(list)
// 分区数据写入 HBase 后关闭连接
table.close()
}
这样每次写的代码很多, 显得不够友好, 如果能跟 dataframe 保存 parquetcsv 之类的就好了下面就看看怎么实现 dataframe 直接写入 hbase 吧!
2. Hortonworks 的 SHC 写入
由于这个插件是 hortonworks 提供的, maven 的中央仓库并没有直接可下载的版本需要用户下载源码自己编译打包, 如果有 maven 私库, 可以上传到自己的 maven 私库里面具体的步骤可以参考如下:
2.1 下载源码编译上传
去官网 github 下载即可: https://github.com/hortonworks-spark/shc
可以直接按照下面的 readme 说明来, 也可以跟着我的笔记走
下载完成后, 如果有自己的私库, 可以修改 shc 中的 distributionManagement 然后点击旁边的 maven 插件 deploy 发布工程, 如果只想打成 jar 包, 那就直接 install 就可以了
2.2 引入
在 pom.xml 中引入:
com.hortonworks
shc-core
1.1.2-2.2-s_2.11-SNAPSHOT
2.3
首先创建应用程序,
然后再 resources 目录下, 添加 hbase-site.xmlhdfs-site.xmlcore-site.xml 等配置文件主要是获取 Hbase 中的一些连接地址
Application.scalaobjectApplication{
defmain(args:Array[String]):Unit={
val spark=SparkSession.builder().master("local").appName("normal").getOrCreate()
spark.sparkContext.setLogLevel("warn")
val data=(0to255).map{i=>HBaseRecord(i,"extra")}
val df:DataFrame=spark.createDataFrame(data)
df.write
.mode(SaveMode.Overwrite)
.options(Map(HBaseTableCatalog.tableCatalog->catalog))
.format("org.apache.spark.sql.execution.datasources.hbase")
.save()
}
defcatalog=s"""{
|"table":{"namespace":"rec", "name":"user_rec"},
|"rowkey":"key",
|"columns":{
|"col0":{"cf":"rowkey", "col":"key", "type":"string"},
|"col1":{"cf":"t", "col":"col1", "type":"boolean"},
|"col2":{"cf":"t", "col":"col2", "type":"double"},
|"col3":{"cf":"t", "col":"col3", "type":"float"},
|"col4":{"cf":"t", "col":"col4", "type":"int"},
|"col5":{"cf":"t", "col":"col5", "type":"bigint"},
|"col6":{"cf":"t", "col":"col6", "type":"smallint"},
|"col7":{"cf":"t", "col":"col7", "type":"string"},
|"col8":{"cf":"t", "col":"col8", "type":"tinyint"}
|}
|}""".stripMargin
}
caseclassHBaseRecord(
col0:String,
col1:Boolean,
col2:Double,
col3:Float,
col4:Int,
col5:Long,
col6:Short,
col7:String,
col8:Byte)
objectHBaseRecord
{
defapply(i:Int,t:String):HBaseRecord={
val s=s"""row${"%03d".format(i)}"""
HBaseRecord(s,
i%2==0,
i.toDouble,
i.toFloat,
i,
i.toLong,
i.toShort,
s"String$i: $t",
i.toByte)
}
}
3. HBase 2.x + 即将发布的 hbase-spark
如果有浏览官网习惯的同学, 一定会发现, HBase 官网的版本已经到了 3.0.0-SNAPSHOT, 并且早就在 2.0 版本就增加了一个 hbase-spark 模块, 使用的方法跟上面 hortonworks 一样, 只是 format 的包名不同而已, 猜想就是把 hortonworks 给拷贝过来了
另外 Hbase-spark 2.0.0-alpha4 目前已经公开在 maven 仓库中了
http://mvnrepository.com/artifact/org.apache.hbase/hbase-spark
不过, 内部的 spark 版本是 1.6.0, 太陈旧了!!!! 真心等不起了...
期待 hbase-spark 官方能快点提供正式版吧
参考
hortonworks-spark/shc github:https://github.com/hortonworks-spark/shc
maven 仓库地址: http://mvnrepository.com/artifact/org.apache.hbase/hbase-spark
Hbase spark sql/ dataframe 官方文档: https://hbase.apache.org/book.html#_sparksql_dataframes