未加星标

Spark DataFrame便捷整合HBase

字体大小 | |
[大数据技术 所属分类 大数据技术 | 发布者 店小二03 | 时间 2017 | 作者 红领巾 ] 0人收藏点击收藏

Spark DataFrame便捷整合HBase

阅读:14

HBase的介绍及使用场景;Spark on HBase介绍;以及如何通过Spark的DataFrame访问HBase表。

文章目录

二. HBase的选型依据
三. SHC:Spark on HBase简介
四. SHC+DataFrame便捷使用

一. HBase简介

HBase的介绍在网上随处可见,借用《HBase企业应用实战》中的描述,如下:

“HBase(hadoop Database)是一个高可靠、高性能、面向列、可伸缩的分布式数据库,利用HBase技术可在廉价PC上搭建起大规模结构化存储集群。HBase参考Google的BigTable建模,使用类似GFS的HDFS作为底层文件存储系统,在其上可以运行MapReduce批量处理数据,使用ZooKeeper作为协同服务组件。

HBase的整个项目使用Java语言实现,它是Apache基金会的Hadoop项目的一部分,既是模仿Google BigTable的开源产品,同时又是Hadoop的衍生产品。而Hadoop作为批量离线计算系统已经得到了业界的普遍认可,并经过了工业上的验证,所以HBase具备“站在巨人肩膀之上”的优势,其发展势头非常迅猛。

HBase还是一种非关系型数据库,即NoSQL数据库。在Eric Brewer的CAP理论中,HBase属于CP类型的系统,其NoSQL的特性非常明显,这些特性也决定了其独特的应用场景。接下来的内容将详细讲解HBase的发展历史、发行版本和特性”

Spark DataFrame便捷整合HBase

CAP

二. HBase的选型依据
2.1 使用场景

《HBase企业应用实战》中提到HBase较为适合如下几种使用需求,笔者加入相应自己的理解,描述如下:

存储大量的数据(PB级数据)且能保证良好的随机访问性能:存储量级由HDFS的良好扩展性和容错性支撑,随机访问性能良好是由于其Rowkey根据字符串大小排列,同时有MemStore进行内存缓存加持。
需要很高的写吞吐量,瞬间写入量很大,传统数据库不能支撑或需要很高成本支撑的场景:瞬间写入并发性能高得益于WAL机制(详见HBase-数据写入流程解析)。
可以进行优雅的数据扩展,动态扩展整个存储系统容量:同样由HDFS支撑。
数据格式无限制,支持半结构化和非结构化的数据:HBase中存储值均为Bytes类型,读写两端协商好如何转换即可支持任意类型的数据。
业务场景简单,不需要全部的关系型数据库特性,例如交叉列、交叉表,事务、连接等。

具体使用场景如用户画像、实时指标计算、更新计算和增量计算,HBase都比较适合。

那么,哪些场景是不适合HBase的,主要有如下两个场景:

大量读大量写:HBase的写性能由WAL机制保证,其Rowkey、MemStore和StoreFile两级缓存+存储保证了随机读性能。然而,批量读操作在HBase中对应Scan动作,每次Scan操作都都是一个RPC操作,会返回n行,此处的n由client.scanner.caching设置,默认是1。这就意味着默认100万行的数据需要100万次RPC操作。随机读和顺序读基本上两难全。(参见Hive over HBase和Hive over HDFS性能比较分析)。同时,如果默认通过Region Server去进行HBase的批量读取,HBase会需要使用大量的资源,例如WAL、合并(Compaction)和刷出(Flush)队列、服务器内存、还会触发大量的JVM垃圾回收,此时性能影响的将不仅仅是HBase,还有其余Java程序(详见Efficient bulk load of HBase using Spark和How-to: Use HBase Bulk Loading, and Why)。HBase支持批量读写,在指定了RowKey范围下的批量读性能也尚可,但最优的场景还是大量写少量读。
多表关联与复杂统计:HBase并未内置关联查询,虽可以通过客户端实现多表关联,例如当年基于HBase的图数据库Titan,实现的复杂性和机理限制导致基于HBase的关联查询并不常见。

以上两个场景,其实正是Spark+HDFS+Hive的强项。Spark+HDFS+Hive应对离线批处理和复杂统计计算场景,HBase应对准实时的并发查询和简单计算场景,也是实践中比较好的方式。

2.2 性能

网上已有许多不同的NoSql数据库之间的性能比较:

2016-11:Performance Comparison between Five NoSQL Databases

2014-09:性能测试:SequoiaDB vs. MongoDB vs. Cassandra vs. HBase

2014-08:datastax的评测

2014-02:Sergey Sverchkov的评测

评测的结果都差不多,HBase在NoSQL中属于较为中庸的,各种场景都适合,可以作为Spark+Hadoop生态系统的Key-Value数据库选择。当然,选择其他类型的KV数据库,可能可以获得某方面的极致性能,同时也要考虑学习成本和易用性。

2.3 生态系统兼容

HBase基于Hadoop系统构建,安装极为简单。Spark有多种方式操作HBase,接下来会介绍HORTONWORKS开源出来的SPARK-ON-HBASE: DATAFRAME BASED HBASE CONNECTOR。在Hive中,我们可以使用HQL语句在HBase表上进行查询、插入操作,同时可以将HBase中的数据导出至Hive进行离线批处理分析,详见HBaseIntegration和LanguageManual ImportExport。

Spark DataFrame便捷整合HBase

图 HBase架构

三. SHC:Spark on HBase简介

SHC是hortonworks给Spark做的一个HBase的Connector,其优势是可以通过用DataFrame的API直接对HBase进行读写操作,相对Spark原生的API(saveAsHadoopDataset和saveAsNewAPIHadoopDataset)而言,极大增强了易用性,Github上的地址如下shc。

详细的介绍可以看SPARK-ON-HBASE: DATAFRAME BASED HBASE CONNECTOR,想要一目十行看中文的同学可以移步相对应的译文Spark-on-HBase:通过Spark的DataFrame访问HBase表。

四. SHC+DataFrame便捷使用

使用SHC+DataFrame非常简单,基本只需要关注HBaseTableCatalog,即定义出DataFrame的每一列应该输出到HBase中的表名、RowKey,列族、列名、类型以及命名空间与编码格式。该格式可以从JSON数据读入,具体格式如下,详细样例请移步官方基础样例:

defcatalog=s”””{
|”table”:{“namespace”:”default”,“name”:”shcExampleTable”,“tableCoder”:”PrimitiveType”},
|”rowkey”:”key1:key2″,
|”columns”:{
|”col00″:{“cf”:”rowkey”,“col”:”key1″,“type”:”string”,“length”:”6″},
|”col01″:{“cf”:”rowkey”,“col”:”key2″,“type”:”int”},
|”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”:”string”},
|”col8″:{“cf”:”cf8″,“col”:”col8″,“type”:”tinyint”}
|}
|}”””.stripMargin

HBase中跨列族访问是非常低效的,所以在实际应用的过程中,往往需要进行存储的DataFrame中列都是一个列族的。同时有些时候DataFrame会产生不固定的列,频繁手动更改HBaseTableCatalog的Schema也是一个无趣的活。DataFrame的优势在这个时候就体现出来了,我们可以根据DataFrame的Schema自动化生成HBase的映射关系以及列值类型,其余的自己指定就好。代码如下:

importapache.spark.sql.execution.datasources.HBase._
importapache.spark.sql._
importapache.spark.sql.types._
importapache.spark.sql.functions._
importapache.spark.{SparkConf,SparkContext}
importalibaba.fastjson.{JSON,JSONArray,JSONObject}
importcollection.JavaConversions._
importcollection.JavaConverters._
/**
*保存DataFrame到HBase
*@paramdf_2_be_save需要保存的DataFrame
*@paramtablename_hb需要存入的表名,需要提前建好
*@paramnamespace_hbdefault,根据需要更改,一般默认就好
*@paramtableCoder_hbPrimitiveType,根据需要更改,一般默认就好
*@paramrowkey_hb主键名字
*@paramcolumFamily_hb列族名,在该函数中,DataFrame的所有列都只能插入到同一个列族中,列族需要预先定义好
*@paramnewtablecount
*/
defDataFrame_Save_To_HBase(df_2_be_save:DataFrame)(tablename_hb:String, namespace_hb:String=“default”,tableCoder_hb:String=“PrimitiveType”,rowkey_hb:String,columFamily_hb:String,newtablecount:Int=5):Unit={
valcolumn_json=df_2_be_save.schema.map{
stf=>{
if(stf.name==rowkey_hb){
(stf.name->JSON.toJSON(Map(“cf”->“rowkey”,
“col”->rowkey_hb,
“type”->stf.dataType.simpleString).asJava))
}else{
(stf.name->JSON.toJSON(Map(“cf”->columFamily_hb,
“col”->stf.name,
“type”->stf.dataType.simpleString).asJava))
}.toMap.asJava
valdf_HBase_schema=JSON.toJSON(Map(“table”->JSON.toJSON(Map(“name”->tablename_hb,
“namespace”->namespace_hb,”tableCoder”->tableCoder_hb).asJava),
“rowkey”->rowkey_hb,
“columns”->column_json).asJava)
// println(df_HBase_schema)
options(
Map(HBaseTableCatalog.tableCatalog->df_HBase_schema.toString,HBaseTableCatalog.newTable->newtablecount.toString)).
format(“org.apache.spark.sql.execution.datasources.HBase”).
save()

至此,诸位读者应该可以拿着SHC和Spark愉快的玩耍了。周末愉快。


Spark DataFrame便捷整合HBase
主题: HBaseSparkJavaHadoopHDFSHiveSQL数据RPC企业应用
tags: HBase,gt,hb,DataFrame,col,type,Spark,cf,rowkey,场景,stf,spark,name,列族,JSON
分页:12
转载请注明
本文标题:Spark DataFrame便捷整合HBase
本站链接:http://www.codesec.net/view/568797.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 大数据技术 | 评论(0) | 阅读(116)