spark sql读hbase
项目背景
spark sql读hbase据说官网如今在写,但还没稳定,所以我基于hbase-rdd这个项目进行了一个封装,当中会区分是否为2进制,假设是就在配置文件里指定为#b,如long#b,还实用了个公司封装的Byte转其它类型,这个假设别人用须要自己实现一套方案。假设我们完毕这一步,将会得到一个DataFrame,后面就能够registerTmpTable,正常使用了使用hiveContext,是由于有一定的orc文件。我这套方案是兼容hbase和hfile的。比方:
val conf = new SparkConf
implicit val sc = new SparkContext(conf)
implicit val hiveContext = new HiveContext(sc)
HbaseMappingUtil.getHbaseDataFrame(tableName,startRow,stopRow).registerTempTable(tableName)
hiveContext.sql("select * from tableName limit 1").show()
配置文件
配置文件:
hbase {
mapping {
table {
usertriat {
name = "hb_user_trait_7days"
columnfamily = "stat"
columns = ["p_du", "p_counts", "p_period_dist"]
schemas = ["String", "int","string"]
nullable = [true,false,true]
}
toddtest {
name = "todd_test"
columnfamily = "cf1"
columns = ["name", "age"]
schemas = ["String", "int"]
nullable = [true, true]
}
user {
name = "hb_user"
columnfamily = "user"
columns = ["modifiedTime", "nickname", "isThirdparty"]
schemas = ["long#b", "string", "boolean"]
nullable = [true, true, true]
}
}
}
}
就是须要配置一些比方columnfamily。column,是否为空,一定要配,相当于自定格式的一个配置
核心代码
核心代码:
import scala.language._
import unicredit.spark.hbase._
import net.ceedubs.ficus.Ficus._
import org.apache.spark.sql.types._
import org.apache.spark.SparkContext
import com.typesafe.config.ConfigFactory
import org.apache.hadoop.hbase.client.Scan
import org.apache.spark.sql.hive.HiveContext
import org.apache.spark.sql.{DataFrame, Row}
import com.ximalaya.tran.{Bytes, PrimitiveByteTrans, Tran}
import java.lang.{Boolean ⇒ JBoolean, Double ⇒ JDouble, Float ⇒ JFloat, Long ⇒ JLong}
/**
* Created by todd.chen on 16/3/28.
* email : todd.chen@ximalaya.com
*/
object HbaseMappingUtil {
lazy val config = ConfigFactory.load()
def getHbaseDataFrame(table: String)(implicit @transient hiveContext: HiveContext,
@transient sc: SparkContext): DataFrame = {
getHbaseDataFrame(table, None, None)
}
def getHbaseDataFrame(table: String, startRow: Option[String], endRow: Option[String])
(implicit @transient hiveContext: HiveContext,
@transient sc: SparkContext): DataFrame = {
lazy val hbasePrefix = s"hbase.mapping.table.$table"
implicit val hbaseConfig = HBaseConfig()
implicit def string2Integer(str: String): Integer = new Integer(str)
val tableName = config.as[String](s"$hbasePrefix.name")
val columnFamily = config.as[String](s"$hbasePrefix.columnfamily")
val _columns = config.as[Set[String]](s"$hbasePrefix.columns")
val _names = _columns.toSeq
val _schemas = config.as[Seq[String]](s"$hbasePrefix.schemas")
val _nullAbles = config.as[Seq[Boolean]](s"$hbasePrefix.nullable")
implicit val columnsZipSchema: Map[String, Tran[_ <: AnyRef, Array[Byte]]] = schemaUtil(table)
val columns = Map(columnFamily → _columns)
val rddSchema = StructType(Seq(StructField("id", StringType, false)) ++ createSchema(_names, _schemas, _nullAbles))
val scan = if (startRow.isDefined && endRow.isDefined) Some(getScan(startRow.get, endRow.get)) else None
def row2Row(row: (String, Map[String, Map[String, Array[Byte]]])) = {
val cf = row._2(columnFamily)
val values = Seq(row._1) ++ _names.map(name ⇒ {
val bytesArray = cf.getOrElse(name, null)
arrayByte2Object(bytesArray, name)
})
Row(values: _*)
}
val rowRdd = if (scan.isDefined) {
sc.hbase[Array[Byte]](tableName, columns, scan.get).map(row2Row
)
} else {
sc.hbase[Array[Byte]](tableName, columns).map(row2Row)
}
hiveContext.createDataFrame(rowRdd, rddSchema)
}
private def createSchema(names: Seq[String], schemas: Seq[String], nullAbles: Seq[Boolean]): Seq[StructField] = {
(names, schemas, nullAbles).zipped.map {
case (name, schema, isnull) ⇒ (name, schema, isnull)
}.map(string2StructField)
}
private def string2StructField(nameAndStyle: (String, String, Boolean)): StructField = {
val (name, schema, nullAble) = nameAndStyle
schema.toLowerCase match {
case "string" ⇒ StructField(name, StringType, nullAble)
case "double" ⇒ StructField(name, DoubleType, nullAble)
case "int" | "int#b" ⇒ StructField(name, IntegerType, nullAble)
case "long" | "long#b" ⇒ StructField(name, LongType, nullAble)
case "boolean" ⇒ StructField(name, BooleanType, nullAble)
case "float" ⇒ StructField(name, FloatType, nullAble)
case "timestamp" ⇒ StructField(name, TimestampType, nullAble)
case "date" ⇒ StructField(name, DateType, nullAble)
}
}
private def arrayByte2Object(arrayBytes: Array[Byte], column: String)
(implicit columnsZipTran: Map[String, Tran[_ <: AnyRef, Array[Byte]]]) = {
val tran = columnsZipTran.get(column).get
tran.from(arrayBytes)
}
private def schemaUtil(tableName: String) = {
lazy val hbasePrefix = s"hbase.mapping.table.$tableName"
val _columns = config.as[Seq[String]](s"$hbasePrefix.columns")
val _schemas = config.as[Seq[String]](s"$hbasePrefix.schemas")
column2Tran(_columns.zip(_schemas))
}
private def column2Tran(columnZipSchema: Seq[(String, String)]) = {
var columnZipTran = Map.empty[String, Tran[_ <: AnyRef, Array[Byte]]]
columnZipSchema.foreach { cs ⇒
val (column, schema) = cs
columnZipTran += column → schema2Tran(schema)
}
columnZipTran
}
private def schema2Tran(schema: String): Tran[_ <: AnyRef, Array[Byte]] = {
schema.toLowerCase match {
case "string" ⇒ PrimitiveByteTrans.getTran(classOf[String])
case "boolean" ⇒ PrimitiveByteTrans.getTran(classOf[JBoolean])
case "double" ⇒ PrimitiveByteTrans.getTran(classOf[JDouble])
case "float" ⇒ PrimitiveByteTrans.getTran(classOf[JFloat])
case "long" ⇒ new Tran[JLong, Array[Byte]] {
override def from(to: Array[Byte]): JLong = {
val num = Bytes.toString(to)
if (num == null) null else new JLong(num)
}
override def to(from: JLong): Array[Byte] = Bytes.toBytes(from.toString)
}
case "long#b" ⇒ PrimitiveByteTrans.getTran(classOf[JLong])
case "int" ⇒ new Tran[Integer, Array[Byte]] {
override def from(to: Array[Byte]): Integer = {
val num = Bytes.toString(to)
if (num == null) null else new Integer(num)
}
override def to(from: Integer): Array[Byte] = Bytes.toBytes(from.toString)
}
case "int#b" ⇒ PrimitiveByteTrans.getTran(classOf[java.lang.Integer])
}
}
private def getScan(startRow: String, endRow: String): Scan = {
val scan = new Scan()
scan.setStartRow(Bytes.toBytes(startRow))
scan.setStopRow(Bytes.toBytes(endRow))
scan
}
}
spark sql读hbase的更多相关文章
- Spark SQL 读到的记录数与 hive 读到的不一致
问题:我用 sqoop 把 Mysql 中的数据导入到 hive,使用了--delete-target-dir --hive-import --hive-overwrite 等参数,执行了两次. my ...
- Spark SQL读parquet文件及保存
import org.apache.spark.{SparkConf, SparkContext} import org.apache.spark.sql.{Row, SparkSession} im ...
- 新闻网大数据实时分析可视化系统项目——18、Spark SQL快速离线数据分析
1.Spark SQL概述 1)Spark SQL是Spark核心功能的一部分,是在2014年4月份Spark1.0版本时发布的. 2)Spark SQL可以直接运行SQL或者HiveQL语句 3)B ...
- Spark读HBase写MySQL
1 Spark读HBase Spark读HBase黑名单数据,过滤出当日新增userid,并与mysql黑名单表内userid去重后,写入mysql. def main(args: Array[Str ...
- IDEA中Spark读Hbase中的数据
import org.apache.hadoop.hbase.HBaseConfiguration import org.apache.hadoop.hbase.io.ImmutableBytesWr ...
- IDEA中 Spark 读Hbase 报错处理:
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory] // :: ERROR RecoverableZooKeepe ...
- 使用 Spark SQL 高效地读写 HBase
Apache Spark 和 Apache HBase 是两个使用比较广泛的大数据组件.很多场景需要使用 Spark 分析/查询 HBase 中的数据,而目前 Spark 内置是支持很多数据源的,其中 ...
- Spark 读 Hbase
package com.grady import org.apache.hadoop.hbase.HBaseConfiguration import org.apache.hadoop.hbase.c ...
- Spark SQL External Data Sources JDBC官方实现读测试
在最新的master分支上官方提供了Spark JDBC外部数据源的实现,先尝为快. 通过spark-shell测试: import org.apache.spark.sql.SQLContext v ...
随机推荐
- (二)Mybatis总结之通过Dao层与数据交互
Mybatis概述 定义: Mybatis是一个支持普通sql查询,存储过程和高级映射的优秀持久层框架. Mybatis是(半自动的)跟数据库打交道的orm(object relationship m ...
- C++ const学习
概念 const就是为了直接表达“不变化的值”这一概念.也就是说该值只可读,不可直接写. 由于不可以修改,所以const常量在声明的时候必须初始化 const int a; //error exter ...
- swiper3初始化/swiper-init/用data实例化swiper/data-swiper
Framework7直接用data属性实例化swiper用起来很爽,刚好最近又用到swiper插件,自己写一个 HTML <div class="swiper-container sw ...
- Statement和PreparedStatement深入学习总结
最近在看java安全编码方面的书籍,在看到SQL注入漏洞的问题时,引发了我对Statement和PreparedStatement深入总结的欲望,废话少说,下面咱们就正式开始. 当初始的SQL查询被修 ...
- [Windows Server 2008] MySQL单数据库迁移方法
★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com ★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频. ★ 本节我们将带领大家:MySQL ...
- CPU总线
总线(Bus)是计算机各种功能部件之间传送信息的公共通信干线,它是由导线组成的传输线束.按照计算机所传输的信息种类,计算机的总线可以划分为数据总线.地址总线和控制总线,分别用来传输数据.数据地址和控制 ...
- 面试总结——Java高级工程师(一)
一.无笔试题 不知道是不是职位原因还是没遇到,面试时,都不需要做笔试题,而是填张个人信息表格,或者直接面试 二.三大框架方面问题 1.Spring 事务的隔离性,并说说每个隔离性的区别 解答:spri ...
- 【IDEA】【Git】pull代码始终无法pull到最新的代码或者提示pull no items 【解决方式】
最近pull代码老是提示pull no items,但是本地并不是最新的代码,看了各种博客始终无法解决,最后靠自己的方式解决.下面是解决方法. 方法:1.首先git --> repository ...
- Python,subprocess模块(补充)
1.subprocess模块,前戏 res = os.system('dir') 打印到屏幕,res为0或非0 os.popen('dir') 返回一个内存对象,相当于文件流 a = os.popen ...
- Tampermonkey脚本安装问题及自用脚本推荐
对于高手来说,chrome浏览器中即使没有其他任何chrome插件,可能都无关紧要.但是有一个插件必不可少, 那就是Tampermonkey油猴插件.Tampermonkey是Chrome上最流行的用 ...