一. 项目背景及概要
在互联网逐步步入大数据时代后,不可避免的给企业和用户行为带来一系列改变与重塑;其中最大的变化莫过于,用户的一切行为在企业面前是“可视化”的.随着大数据技术的深入研究与应用,企业的专注点日益聚焦于怎样利用大数据来为精细化运营及精准营销服务,进而深入挖掘潜在的商业价值.于是,用户画像的概念也就应运而生
二. 项目目标
全业务运营下,用户画像及应用基于PG(关系型数据库)和大数据平台采集分析,把用户特征标签封装成数据接口服务,实时推送到一线,使信息数据变成生产力,项目实现目标如下:
一、用户画像模型封装
(1)基于PG(关系型数据库)和大数据平台(hive、impala)
包含基础标签与分析类知识标签,实现用户特征全貌刻画;
(2)多种封装角度
分用户类别、渠道内容、业务场景进行封装配置.
二、接口数据实时推送
实现用户画像数据实时更新至运营及营销统一视图(WeMeta、WeData、WeSearch等)中进行展现,并实时反馈运营及营销信息问题,保证数据应用的时效性.
三、展现UI封装
依托用户画像,将推荐信息配置应用端进行可视化展现,集中活动运营,实现千人千面的运营效果.
三. Mysql表设计
1. 业务方案配置表
2. 方案关联权重配置明细表
3. 权重关联用户标签表
四. Hive表设计
五. 标签统计
六. 用户画像产品化
1.1 用户标签查询页面
1.2 用户标签查询代码(第一种 : 写入Hbase)
1.3 用户标签查询代码(第二种 : 写入ElasticSearch)
object UserTagToEs {
// ElasticSearch中的Index名称
val ES_TYPE_NAME = "user_tag"
// 配置主机名:端口号的正则表达式
val ES_HOST_PORT_REGEX = "(.+):(\\d+)".r
/**
* Store Data In ElasticSearch
*
* @param data. 用户标签数据集
* @param esConf. ElasticSearch的配置对象
*/
private def storeUserTagDataInES(data: DataFrame)(implicit esConf: ESConfig): Unit = {
// 需要操作的Index名称
val indexName = esConf.index
// 新建一个到ES的连接配置
var settings: Settings = Settings.builder().put("cluster.name", esConf.clusterName).build()
// 创建到ES的连接客户端
val esClient = new PreBuiltTransportClient(settings)
//对于设定的多个Node分别通过正则表达式进行模式匹配,并添加到客户端实例
esConf.transportHosts.split(";")
.foreach {
case ES_HOST_PORT_REGEX(host: String, port: String) =>
esClient.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(host), port.toInt))
}
// 检查如果Index存在,那么删除Index
if (esClient.admin().indices().exists(new IndicesExistsRequest(indexName)).actionGet().isExists) {
// 删除Index
esClient.admin().indices().delete(new DeleteIndexRequest(indexName)).actionGet()
}
// 创建Index
esClient.admin().indices().create(new CreateIndexRequest(indexName)).actionGet()
// 声明写出时的ES配置信息
val tagOptions = Map("es.nodes" -> esConf.httpHosts,
"es.http.timeout" -> "100m",
"es.mapping.id" -> "user_id")
// 数据写出时的Type名称【表】
val movieTypeName = s"$indexName/$ES_TYPE_NAME"
// 将用户标签数据保存到ES
data
.write.options(tagOptions)
.mode("overwrite")
.format("org.elasticsearch.spark.sql")
.save(movieTypeName)
}
def main(args: Array[String]): Unit = {
System.setProperty("hadoop.home.dir", "D:\\hadoop-common-2.2.0-bin-master")
//如果想让hive运行在spark上,一定要开启spark对hive的支持
val hiveContext = SparkSession.builder()
.enableHiveSupport()
.appName("UserTagToEs")
.master("local[*]")
.getOrCreate()
//创建全局配置
val params = scala.collection.mutable.Map[String, Any]()
params += "spark.cores" -> "local[*]"
params += "es.httpHosts" -> "spark01:9200"
params += "es.transportHosts" -> "spark01:9300"
params += "es.index" -> "user_draw_tag"
params += "es.cluster.name" -> "es-cluster"
// 定义ElasticSearch的配置对象
implicit val esConf = new ESConfig(params("es.httpHosts").asInstanceOf[String],
params("es.transportHosts").asInstanceOf[String],
params("es.index").asInstanceOf[String],
params("es.cluster.name").asInstanceOf[String])
//查询每个用户相关标签
val resDF = hiveContext.sql(
"""
| SELECT
| t.user_id,
| concat_ws(',',collect_set(tag_par)) AS tag_par
| FROM
| (
| SELECT user_id,
| concat_ws(':',tag_id,CAST(tag_value AS string)) AS tag_par
| FROM
| bigdata.hive_business_project_action_tag
| WHERE dt = '2020-03-24'
| ) t
| GROUP BY t.user_id
""".stripMargin)
resDF.cache()
storeUserTagDataInES(resDF);
resDF.unpersist()
hiveContext.close()
}
}