Spark—GraphX实战 OneID

OneID

前面我们学习了ID Mapping,包括ID Mapping 的背景介绍和业务场景,以及如何使用Spark 实现ID Mapping,这个过程中涉及到了很多东西,当然我们都通过文章的形式介绍给大家了,所以你再学习今天这一节之前,可以先看一下前面的文章

  1. Spark实战—GraphX编程指南
  2. 数仓建模—ID Mapping(上)
  3. 数仓建模—ID Mapping(下)

在上一节我们介绍ID Mapping 的时候我们就说过ID Mapping 是为了打通用户各个维度的数据,从而消除数据孤岛、避免数据歧义,从而更好的刻画用户,所以说ID Mapping是手段不是目的,目的是为了打通数据体系,ID Mapping最终的产出就是我们今天的主角OneID,也就是说数据收集过来之后通过ID Mapping 打通,从而产生OneID,这一步之后我们的整个数据体系就将使用OneID作为用户的ID,这样我们整个数据体系就得以打通

OneData

开始之前我们先看一下阿里的OneData 数据体系,从而更好认识一下OneID,前面我们说过ID Mapping 只是手段不是目的,目的是为了打通数据体系,ID Mapping最终的产出就是OneID

其实OneID在我们整个数据服务体系中,也只是起点不是终点或者说是手段,我们最终的目的是为了建设统一的数据资产体系。

u句

没有建设统一的数据资产体系之前,我们的数据体系建设存在下面诸多问题

  1. 数据孤岛:各产品、业务的数据相互隔离,难以通过共性ID打通
  2. 重复建设:重复的开发、计算、存储,带来高昂的数据成本
  3. 数据歧义:指标定义口径不一致,造成计算偏差,应用困难

在阿里巴巴 OneData 体系中,OneID 指统一数据萃取,是一套解决数据孤岛问题的思想和方法。数据孤岛是企业发展到一定阶段后普遍遇到的问题。各个部门、业务、产品,各自定义和存储其数据,使得这些数据间难以关联,变成孤岛一般的存在。

OneID的做法是通过统一的实体识别和连接,打破数据孤岛,实现数据通融。简单来说,用户、设备等业务实体,在对应的业务数据中,会被映射为唯一识别(UID)上,其各个维度的数据通过这个UID进行关联。

各个部门、业务、产品对业务实体的UID的定义和实现不一样,使得数据间无法直接关联,成为了数据孤岛。基于手机号、身份证、邮箱、设备ID等信息,结合业务规则、机器学习、图算法等算法,进行 ID-Mapping,将各种 UID 都映射到统一ID上。通过这个统一ID,便可关联起各个数据孤岛的数据,实现数据通融,以确保业务分析、用户画像等数据应用的准确和全面。

OneModel 统一数据构建和管理

将指标定位细化为:

1. 原子指标
2. 时间周期
3. 修饰词(统计粒度、业务限定, etc)

通过这些定义,设计出各类派生指标 基于数据分层,设计出维度表、明细事实表、汇总事实表,其实我们看到OneModel 其实没有什么新的内容,其实就是我们数仓建模的那一套东西

OneService 统一数据服务

OneService 基于复用而不是复制数据的思想,指得是我们的统一的数据服务,因为我们一直再提倡复用,包括我们数仓的建设,但是我们的数据服务这一块却是空白,所以OneService核心是服务的复用,能力包括:

  • 利用主题逻辑表屏蔽复杂物理表的主题式数据服务
  • 一般查询+ OLAP 分析+在线服务的统一且多样化数据服务
  • 屏蔽多种异构数据源的跨源数据服务
OneID 统一数据萃取

基于统一的实体识别、连接和标签生产,实现数据通融,包括:

  • ID自动化识别与连接
  • 行为元素和行为规则
  • 标签生产

OneID基于超强ID识别技术链接数据,高效生产标签;业务驱动技术价值化,消除数据孤岛,提升数据质量,提升数据价值。

而ID的打通,必须有ID-ID之间的两两映射打通关系通过ID映射关系表,才能将多种ID之间的关联打通,完全孤立的两种ID是无法打通的

打通整个ID体系,看似简单,实则计算复杂,计算量非常大。假如某种对象有数亿个个体,每个个体又有数十种不同的ID标识,任意两种ID之间都有可能打通关系,想要完成这类对象的所有个体ID打通需要数亿次计算,一般的机器甚至大数据集群都无法完成。

大数据领域中的ID-Mapping技术就是用机器学习算法类来取代野蛮计算,解决对象数据打通的问题。基于输入的ID关系对,利用机器学习算法做稳定性和收敛性计算,输出关系稳定的ID关系对,并生成一个UID作为唯一识别该对象的标识码。

OneID实现过程中存在的问题

前面我们知道我们的ID Mapping 是通过图计算实现,核心就是连通图,其实实现OneID我们在打通ID 之后,我们就可以为一个个连通图生成一个ID, 因为一个连通图 就代表一个用户,这样我们生成的ID就是用户的OneID,这里的用户指的是自然人,而不是某一个平台上的用户。

OneID 的生成问题

首先我们需要一个ID 生成算法,因为我们需要为大量用户生成ID,我们的ID 要求是唯一的,所以在算法设计的时候就需要考虑到这一点,我们并不推荐使用UUID,原因是UUID了可能会出现重复,而且UUID 没有含义,所以我们不推荐使用UUID,我们这里使用的是MD5 算法,所以我们的MD5 算法的参数是我们的图的标示ID。

OneID 的更新问题

这里的更新问题主要就是我们的数据每天都在更新,也就是说我们的图关系在更新,也就是说我们要不要给这个自然人重新生成OneID ,因为他的图关系可能发生了变化。

其实这里我们不能为该自然人生成新的OneID ,否则我们数仓里的历史数据可能无法关联使用,所以我们的策略就是如果该自然人已经有OneID了,则不需要重新生成,其实这里我们就是判断该图中的所有的顶点是否存在OneID,我们后面在代码中体现着一点。

OneID 的选择问题

这个和上面的更新问题有点像,上面更新问题我们可以保证一个自然人的OneID不发生变化,但是选择问题会导致发生变化,但是这个问题是图计算中无法避免的,我们举个例子,假设我们有用户的两个ID(A_ID,C_ID),但是这两个ID 在当前是没有办法打通的,所以我们就会为这个两个ID 生成两个OneID,也就是(A_OneID,B_OneID),所以这个时候我们知道因为ID Mapping 不上,所以我们认为这两个ID 是两个人。

后面我们有了另外一个ID(B_ID),这个ID可以分别和其他的两个ID 打通,也就是B_ID<——>A_ID , B_ID<——>C_ID 这样我们就打通这个三个ID,这个时候我们知道

这个用户存在三个ID,并且这个时候已经存在了两个OneID,所以这个时候我们需要在这两个OneID中选择一个作为用户的OneID,简单粗暴点就可以选择最小的或者是最大的。

我们选择了之后,要将另外一个OneID对应的数据,对应到选择的OneID 下,否则没有被选择的OneID的历史数据就无法追溯了

OneID 代码实现

这个代码相比ID Mapping主要是多了OneID 的生成逻辑和更新逻辑 ,需要注意的是关于顶点集合的构造我们不是直接使用字符串的hashcode ,这是因为hashcode 很容易重复

object OneID  {val spark = SparkSession.builder().appName("OneID").getOrCreate()val sc = spark.sparkContextdef main(args: Array[String]): Unit = {val bizdate=args(0)val c = Calendar.getInstanceval format = new SimpleDateFormat("yyyyMMdd")c.setTime(format.parse(bizdate))c.add(Calendar.DATE, -1)val bizlastdate = format.format(c.getTime)println(s" 时间参数  ${bizdate}    ${bizlastdate}")// dwd_patient_identity_info_df 就是我们用户的各个ID ,也就是我们的数据源// 获取字段,这样我们就可以扩展新的ID 字段,但是不用更新代码val columns = spark.sql(s"""|select|   *|from|   lezk_dw.dwd_patient_identity_info_df|where|   ds='${bizdate}'|limit|   1|""".stripMargin).schema.fields.map(f => f.name).filterNot(e=>e.equals("ds")).toList// 获取数据val dataFrame = spark.sql(s"""|select|   ${columns.mkString(",")}|from|   lezk_dw.dwd_patient_identity_info_df|where|   ds='${bizdate}'|""".stripMargin)// 数据准备val data = dataFrame.rdd.map(row => {val list = new ListBuffer[String]()for (column <- columns) {val value = row.getAs[String](column)list.append(value)}list.toList})import spark.implicits._// 顶点集合val veritx= data.flatMap(list => {for (i <- 0 until columns.length if StringUtil.isNotBlank(list(i)) && (!"null".equals(list(i))))yield (new BigInteger(DigestUtils.md5Hex(list(i)),16).longValue, list(i))}).distinctval veritxDF=veritx.toDF("id_hashcode","id")veritxDF.createOrReplaceTempView("veritx")// 生成边的集合val edges = data.flatMap(list => {for (i <- 0 to list.length - 2 if StringUtil.isNotBlank(list(i)) && (!"null".equals(list(i))); j <- i + 1 to list.length - 1 if StringUtil.isNotBlank(list(j)) && (!"null".equals(list(j))))yield Edge(new BigInteger(DigestUtils.md5Hex(list(i)),16).longValue,new BigInteger(DigestUtils.md5Hex(list(j)),16).longValue, "")}).distinct// 开始使用点集合与边集合进行图计算训练val graph = Graph(veritx, edges)val connectedGraph=graph.connectedComponents()// 连通节点val  vertices = connectedGraph.vertices.toDF("id_hashcode","guid_hashcode")vertices.createOrReplaceTempView("to_graph")// 加载昨日的oneid 数据 (oneid,id,id_hashcode) val ye_oneid = spark.sql(s"""|select|   oneid,id,id_hashcode|from|   lezk_dw.dwd_patient_oneid_info_df|where|   ds='${bizlastdate}'|""".stripMargin)ye_oneid.createOrReplaceTempView("ye_oneid")// 关联获取 已经存在的 oneid,这里的min 函数就是我们说的oneid 的选择问题val exists_oneid=spark.sql("""|select|   a.guid_hashcode,min(b.oneid) as oneid|from|   to_graph a|inner join|   ye_oneid b|on|   a.id_hashcode=b.id_hashcode|group by|   a.guid_hashcode|""".stripMargin)exists_oneid.createOrReplaceTempView("exists_oneid")// 不存在则生成 存在则取已有的 这里nvl 就是oneid  的更新逻辑,存在则获取 不存在则生成val today_oneid=spark.sql(s"""|insert overwrite table dwd_patient_oneid_info_df partition(ds='${bizdate}')|select|   nvl(b.oneid,md5(cast(a.guid_hashcode as string))) as oneid,c.id,a.id_hashcode,d.id as guid,a.guid_hashcode|from|   to_graph a|left join|   exists_oneid b|on|   a.guid_hashcode=b.guid_hashcode|left join|   veritx c|on|   a.id_hashcode=c.id_hashcode|left join|   veritx d|on|   a.guid_hashcode=d.id_hashcode|""".stripMargin)sc.stop}}

这个代码中我们使用了SparkSQL,其实你如果更加擅长RDD的API,也可以使用RDD 优化,需要注意的是网上的很多代码中使用了广播变量,将vertices 变量广播了出去,其实这个时候存在一个风险那就是如果你的vertices 变量非常大,你广播的时候存在OOM 的风险,但是如果你使用了SparkSQL的话,Spark 就会根据实际的情况,帮你自动优化。

优化点 增量优化

我们看到我们每次都是全量的图,其实我们可以将我们的OneID 表加载进来,然后将我们的增量数据和已有的图数据进行合并,然后再去生成图

val veritx = ye_veritx.union(to_veritx)
val edges = ye_edges.union(to_edges)val graph = Graph(veritx, edges)

总结

  1. ID Mapping 是OneID 的提前,OneID 是ID Mapping 的结果,所以要想做OneID必须先做ID Mapping
  2. OneID 是为了打通整个数据体系的数据,所以OneID 需要以服务的方式对外提供服务,在数仓里面就是作为基础表使用,对外的话我们就需要提供接口对外提供服务

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/768210.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FPGA时钟资源详解——时钟Buffer的选择

目录 一、概述 二、时钟Buffer的选择 2.1 BUFG 2.2 BUFR 和 BUFIO 2.2.1 源同步接口的支持 2.2.2 扩展时钟域转换功能 2.2.3 BUFR 作为简单的时钟分频器 2.3 BUFH 2.3.1 BUFH 的关键特性 2.3.2 应用场景 三、总结 3.1 BUFG&#xff08;全局时钟缓冲器&…

OpenCV4.9.0开源计算机视觉库核心功能(核心模块)

转到&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV 介绍使用 下一篇&#xff1a;如何使用OpenCV扫描图像、查找表和时间测量 ​ OpenCV核心功能主要有以下各个&#xff1a;本文将开始介绍下列内容&#xff1a; Mat - 基…

SpringBoot配置JWT拦截器

目录 1.背景介绍 2.前提工作 3.具体代码 &#xff08;1&#xff09;相关依赖 &#xff08;2&#xff09;相关配置文件 &#xff08;3&#xff09;JwtUtils类 &#xff08;4&#xff09;准备好登录逻辑代码&#xff08;Dao、Service、Controller&#xff09; &#xff0…

解决方案Please use Oracle(R) Java(TM) 11, OpenJDK(TM) 11 to run Neo4j.

文章目录 一、现象二、解决方案 一、现象 当安装好JDK跟neo4j&#xff0c;用neo4j.bat console来启动neo4却报错&#xff1a; 部分报错信息&#xff1a; Starting Neo4j. WARNING! You are using an unsupported Java runtime. Please use Oracle Java™ 11, OpenJDK™ 11 t…

大白话扩散模型(无公式版)

背景 传统的图像生成模型有GAN&#xff0c;VAE等&#xff0c;但是存在模式坍缩&#xff0c;即生成图片缺乏多样性&#xff0c;这是因为模型本身结构导致的。而扩散模型拥有训练稳定&#xff0c;保持图像多样性等特点&#xff0c;逐渐成为现在AIGC领域的主流。 扩散模型 正如…

设计模式学习笔记 - 设计模式与范式 - 创建型:6.建造者模式:详解构造函数、set方法、建造者三种对象创建方式

概述 本章学习一个比较常用的创建型设计模式&#xff0c;Builder 模式&#xff0c;中文翻译为建造者模式或构建者模式&#xff0c;也有人叫它生成器模式。 建造者模式的原理和代码实现非常简单&#xff0c;掌握起来并不难&#xff0c;难点在于应用场景。比如&#xff0c;你有…

Google ScreenAI代表了一款先进的视觉语言模型,专为用户界面(UI)和视觉情境下的语言理解而设计

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

华为od真题2023-C卷-三叉搜索树

题目描述&#xff1a; 定义构造三叉搜索树规则如下: 每个节点都存有一个数&#xff0c;当插入一个新的数时&#xff0c;从根节点向下寻找&#xff0c;直到找到一个合适的空节点插入。查找的规则是: 1.如果数小于节点的数减去500&#xff0c;则将数插入节点的左子树2.如果数大于…

政安晨:【深度学习部署】—— TensorFlow Extended(TFX)介绍

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras实战演绎机器学习 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 前言 TensorFlow Extended&#xff08;TFX&a…

深入了解Redis的过期策略和内存淘汰机制

✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心哦&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; ✨✨ 帅哥美女们&#xff0c;我们共同加油&#xff01;一起进步&am…

语言模型的原理、实战与评估

语言模型的原理、实战与评估是一个宽泛的话题,下面是对这三个方面简要概述: 语言模型的原理 语言模型(Language Model, LM)是一种统计模型,用于估计一段文本序列的概率分布。它的核心任务是给定一系列词语,计算出这些词语组合成一个完整句子或段落的概率。典型的语言模型…

mysql基础2多表查询

多表查询 多表关系: 一对多 案例: 部门 与 员工的关系 关系: 一个部门对应多个员工&#xff0c;一个员工对应一个部门 实现: 在多的一方建立外键&#xff0c;指向一的一方的主键 多对多 案例: 学生 与 课程的关系 关系: 一个学生可以选修多门课程&#xff0c;一门课程也可以…

MySQL基础复习

目录 一、简单的命令 二、SQL语句分类 三、简单查询 四、条件查询 五、排序 一、简单的命令 net start 服务名称 net stop 服务名称 mysql -uroot -p123456 显示密码形式 mysql -uroot -p 隐藏密码形式 exit 退出 show databases; 查看MySQL中的数据库有哪些 use test…

RuleApp资源社区,知识付费社区,可对接typecho的小程序APP

强大的文章/社区/自媒体客户端&#xff0c;支持打包为安卓&#xff0c;苹果&#xff0c;小程序。包括文章模块&#xff0c;用户模块&#xff0c;支付模块&#xff0c;聊天模块&#xff0c;商城模块等基础功能&#xff0c;包含VIP会员&#xff0c;付费阅读等收费体系&#xff0c…

AttributeError: ‘_MSDataLoaderIter‘ object has no attribute ‘_put_indices‘

问题描述 复现代码过程中遇到错误&#xff1a;AttributeError: _MSDataLoaderIter object has no attribute _put_indices 解决方案 出错的原因是代码中使用了不存在的属性"_put_indices"。这个错误可能与你使用的版本不兼容有关。在pytorch1.x版本中&#xff0c;&q…

c语言函数大全(I开头)

c语言函数大全(I开头) There is no nutrition in the blog content. After reading it, you will not only suffer from malnutrition, but also impotence. The blog content is all parallel goods. Those who are worried about being cheated should leave quickly. 函数名…

【生产力】Mac 窗口布局工具 Magnet

Magnet 是一款为Mac操作系统设计的实用工具&#xff0c;旨在帮助用户更加方便地管理和组织他们的窗口布局。通过使用Magnet&#xff0c;用户可以轻松地将应用程序窗口拖放到屏幕的各个部分&#xff0c;从而实现窗口的自动排列和大小调整。这款工具特别适合需要同时处理多个应用…

Django Ajax

【一】Json 【1】介绍 JSON&#xff08;javascript object otaition&#xff09;是一种轻量级的数据交换格式JSON使用了Javascript的一部分语法来定义其数据格式&#xff0c;但Json是独立于语言的Json采用完全独立于语言的文本格式&#xff0c;使得Json成为理想的数据交互语言…

OD_2024_C卷_100分_72、求最多可以派出多少支团队【JAVA】【双指针】

题目描述 用数组代表每个人的能力&#xff0c;一个比赛活动要求参赛团队的最低能力值为N&#xff0c;每个团队可以由1人或者2人组成&#xff0c;且1个人只能参加1个团队&#xff0c;计算出最多可以派出多少只符合要求的团队。 输入描述 第一行代表总人数&#xff0c;范围1-5…

react native 键盘事件

在做修改密码功能是发现他的键盘第一次调起之后然后收起键盘焦点不会消失而且键盘也不会再调起来了 我门线引入需要的组件 import { StyleSheet, View, TextInput, Keyboard, TouchableWithoutFeedback, } from react-native; import React, {useEffect, useState, useRef} fr…