文章目录
- 1.1、新建标签
- 1.1.1、新建业务标签: 性别标签 ,相关字段信息如下:
- 1.1.2、新建属性标签: 男、女 ,相关字段信息如下:
- 1.1.3、对应到数据库中插入语句如下:
- 1.2、模型主类
- 1.2.1、标签数据读取
- 1.2.2、业务标签规则解析
- 1.2.2.1、HBase数据源Meta
- 1.2.2.2、依据inType类型解析为HBaseMeta,加载业务数据,核心代码如下:
- 1.2.3、构建标签
- 1.2.4、保存标签数据至HBase
先以 规则匹配(rule match) 中性别标签为例,开发整个标签模型,熟悉开发过程,对标签的构建整体认识,如下为在标签管理平台首先需要新建标签【业务标签:4级标签和属性标签:5级标签】页面截图:
标签模型开发完成具体 数据流程详细图 如下所示:
分为四个主要的步骤:
// 1、依据TagId,从MySQL读取标签数据
// 2、解析标签rule,从HBase读取业务数据
// 3、业务数据结合标签属性数据,构建标签
// 4、画像标签数据存储HBase表
涉及技术核心点(难点) :
第一、如何从HBase表读取和写入数据
第二、标签匹配与标签合并
标签合并:将历史标签数据与计算标签数据进行合并
第三、基于DataFrame DSL开发
使用select,filter,groupBy,agg等函数,内置函数:functions._
1.1、新建标签
在标签管理平台WEB UI按照如下性别标签属性新建标签,具体如下所示:
1.1.1、新建业务标签: 性别标签 ,相关字段信息如下:标签名称:性别
标签分类:电商-某商城-人口属性
更新周期:
业务含义:注册会员的性别
标签规则:
inType=hbase
zkHosts=bigdata-cdh01.itcast.cn
zkPort=2181
hbaseTable=tbl_tag_users
family=detail
selectFieldNames=id,gender
程序入口:
cn.itcast.tags.models.rule.GenderModel
算法名称:
MATCH
算法引擎:
tags-model_2.11.jar
模型参数:
--driver-memory 512m --executor-memory 512m --num-executors 1 --executor-cores 1
- 1)、属性值【男】
- 标签名称:男
- 标签含义:注册会员性别男
- 标签规则:1
- 2)、属性值【女】
- 标签名称:女
- 标签含义:注册会员性别女
- 标签规则:2
-- 1、基础标签tbl_basic_tag
INSERT INTO `tbl_basic_tag` VALUES ('318', '性别', null,
'inType=hbase\nzkHosts=bigdatacdh01.itcast.cn\nzkPort=2181\nhbaseTable=tbl_tag_users\nfamily=detail\nselec
tFieldNames=id,gender', null, '4', '314', '2019-12-03 11:11:54', '2019-12-03
11:11:54', null, null);
INSERT INTO `tbl_basic_tag` VALUES ('319', '男', null, '1', null, '5',
'318', '2019-12-03 11:28:03', '2019-12-03 11:28:03', null, null);
INSERT INTO `tbl_basic_tag` VALUES ('320', '女', null, '2', null, '5',
'318', '2019-12-03 11:28:39', '2019-12-03 11:28:39', null, null);
-- 2、模型表tbl_model
INSERT INTO `tbl_model` VALUES ('1', '318', 'MATCH',
'cn.itcast.tags.models.rule.GenderModel', 'hdfs://bigdatacdh01.itcast.cn:8020/apps/temp/jars/9f0d015b-8535-4538-8722-
1d9a331069d1.jar', '4,2019-12-03 10:00:00,2029-12-03 10:00:00', '2019-12-03
11:11:54', '2019-12-03 11:11:54', '4', '--driver-memory 512m --executormemory 512m --num-executors 1 --executor-cores 1');
1.2、模型主类
1.2.1、标签数据读取
首先从基础标签表 tbl_basic_tag 中读取 性别相关的标签数据 :业务标签和属性标签。依据业务标签ID读取标签相关数据:业务标签数据和对应属性标签数据,SQL如下:
(
SELECT `id`,
`name`,
`rule`,
`level`
FROM `profile_tags`.`tbl_basic_tag`
WHERE id = 318
UNION
SELECT `id`,
`name`,
`rule`,
`level`
FROM `profile_tags`.`tbl_basic_tag`
WHERE pid = 318
ORDER BY `level` ASC, `id` ASC
) AS basic_tag
从业务标签数据中获取规则rule的值,解析为Map集合,表示标签模型从哪个数据源中读取数据及数据源的资源信息,具体代码如下:
// TODO: 3. 依据业务标签规则获取业务数据,比如到HBase数据库读取表的数据
// 3.1. 4级标签规则rule
val tagRule: String = basicTagDF
.filter($"level" === 4)
.head()
.getAs[String]("rule")
logInfo(s"==== 业务标签数据规则: {$tagRule} ====")
// 3.2. 解析标签规则,先按照换行\n符分割,再按照等号=分割
/*
inType=hbase
zkHosts=bigdata-cdh01.itcast.cn
zkPort=2181
hbaseTable=tbl_tag_users
family=detail
selectFieldNames=id,gender
*/
val ruleMap: Map[String, String] = tagRule
.split("\\n")
.map { line =>
val Array(attrName, attrValue) = line.trim.split("=")
(attrName, attrValue)
}
.toMap
logWarning(s"============ { ${ruleMap.mkString(", ")} } =========== ")
1.2.2.1、HBase数据源Meta
依据标签规则中inType属性值获取具体业务数据的数据源,此处为HBase数据源,所以编写Case Class样例类封装存储数据源的元数据:读取HBase表数据时传递参数,具体代码如下:
package com.chb.tags.meta
/**
* @Author: chb
* @Date: 2021/4/21 15:13
* @E-Mail:
* @DESC: HBase 元数据解析存储,具体数据字段格式如下所示:
* inType=hbase
* zkHosts=bigdata-cdh01.itcast.cn
* zkPort=2181
* hbaseTable=tbl_tag_users
* family=detail
* selectFieldNames=id,gender
*/
case class HBaseMeta(zkHosts: String,
zkPort: String,
hbaseTable: String,
family: String,
selectFieldNames: String
)
object HBaseMeta {
/**
* 将Map集合数据解析到HBaseMeta中
* @param ruleMap map集合
* @return
*/
def getHBaseMeta(ruleMap: Map[String, String]): HBaseMeta = {
// TODO: 实际开发中,应该先判断各个字段是否有值,没有值直接给出提示,终止程序运行,此处省略
HBaseMeta(
ruleMap("zkHosts"),
ruleMap("zkPort"),
ruleMap("hbaseTable"),
ruleMap("family"),
ruleMap("selectFieldNames")
)
}
}
1.2.2.2、依据inType类型解析为HBaseMeta,加载业务数据,核心代码如下:
// 3.3. 依据标签规则中inType类型获取数据
var businessDF: DataFrame = null
if("hbase".equals(ruleMap("inType").toLowerCase())){
// 规则数据封装到HBaseMeta中
val hbaseMeta: HBaseMeta = HBaseMeta.getHBaseMeta(ruleMap)
// 依据条件到HBase中获取业务数据
}else{
// 如果未获取到数据,直接抛出异常
new RuntimeException("业务标签未提供数据源信息,获取不到业务数据,无法计算标签")
}
businessDF.printSchema()
businessDF.show(20, truncate = false)
1.2.3、构建标签
依据获取的业务数据和属性标签数据中规则,进行关联匹配,构建每个用户的性别标签,如下图示: 代码如下
// TODO: 4. 业务数据和属性标签结合,构建标签:规则匹配型标签 -> rule match
// 4.1 获取5级标签对应tagRule和tagName
val attrTagRuleDF: DataFrame = basicTagDF
.filter($"level" === 5)
.select($"rule", $"name")
// 4.2 DataFrame 关联,依据属性标签规则rule与业务数据字段gender
val modelDF: DataFrame = businessDF
.join(
attrTagRuleDF, businessDF("gender") ===
attrTagRuleDF("rule")
)
.select(
$"id".as("userId"), //
$"name".as("gender") //
)
/*
root
|-- userId: string (nullable = true)
|-- gender: string (nullable = true)
*/
//modelDF.printSchema()
/*
+------+------+
|userId|gender|
+------+------+
|1 |女 |
|10 |女 |
|100 |女 |
|101 |男 |
*/
//modelDF.show(100, truncate = false)
basicTagDF.unpersist()
1.2.4、保存标签数据至HBase
将最后合并后的用户标签数据保存到HBase表中,此处使用TableOutputFormat方式写入数据,其中在工具类 HBaseTools 中添加写入数据方法 write ,代码如下: