项目背景架构
数据源:数据源通过sqoop同步到hbase中。
标签存储:hbase:用于存储标签。mysql:存储标签元数据。es:标签检索。
标签开发:采用spark引擎进行开发。
一、数据导入
将数据同步至hbase中。有以下几种方式。1、sqoop直接迁移。2将数据迁移至hdfs中,然后通过hbase提供的importtsv工具将数据导入至hbase中,这里也有两种方式,默认的方式是直接put的形式,还有一种是bulkload的方式,将文件转换成hfile后再加载到hbase中。
二、标签开发
1、开发一个工具类 提供两个方法(1)向hbase写入数据。(2)读取hbase中的数据
object HbaseTools{
def read(spark:SparkSession,zkHost:String,zkPort:String,table:String,family:String,fields:Seq[String]):DataFrame={
val sc:SparkContext=spark.sparkContext
//1、设置hbase配置信息 zk地址和端口号
val conf=HbaseConfiguration.create()
conf.set("hbase.zookeeper.quorum",zkHost)
conf.set("hbase.zookeeper.property.clientPort",zkPort)
//2、设置表的名称
conf.set(TableInputFormat.Input_Table,table)
//3、设置读取的列簇和列名称
val scan:Scan=new Scan()
//4、设置列簇
val cfBytes:Array[Byte]=Bytes.toBytes(family)
scan.addFamily(cfBytes)
//5、设置列名称
fields.foreach{
field=>
scan.addColumn(cfBytes,Bytes.toBytes(filed))
}
//6、设置scan过滤数据
conf.set(TableInputFormat.SCAN,Base64.encodeBytes(ProtobufUtil.toScan(scan).toByteArray()))
val hbaseRdd=sc.newApiHadoopRDD(conf,classOf(TableInputFormat),classOf(ImmutableBytesWritable),classOf(Result))
)
//将rdd转化成dataframe
val rowsRdd=hbaseRdd.map{
case (_,result)=>
val values:Seq[String]=fields.map{
field=>
val value=result.getValue(cfBytes,Bytes.toBytes(field))
Bytes.toString(value)
}
//将values转换成row
Row.fromSeq(values)
}
//自定义schema
val schema:StructType=StructType(fields.map{
filed=>
StructField(filed,StringType,nullable=true)
})
//返回df
spark.createDataFrame(rowsRdd,schema)
}
def write(dataframe:DataFrame,zkHost:String,zkPort:String,table:String,family:String,rowkeyColumn:String):Unit={
val conf=HbaseConfiguration.create()
conf.set("hbase.zookeeper.quorum",zkHost)
conf.set("hbase.zookeeper.property.clientPort",zkPort)
//2、设置表的名称
conf.set(TableOutputFormat.Output_Table,table)
//将datafram转换为rdd
val cfbytes=Bytes.toBytes(family)
val columns:Array[String]=datatrame.columns
val datasrdd=dataframe.rdd.map{
row=>
val rowkey=row.getAs[String](rowkeyColumn)
val rkBytes:Array[Byte]=Bytes.toBytes(rowkey)
//构建put对象
val put=new Put(rkBytes)
columns.foreach{
column=>
val value=