1. id标识实现
简单方案:将这条数据中的uid/imei码/imsi码/mac/androidid/uuid这些标识字段优先级取一个标识,作为这条数据的用户唯一标识
可能存在问题:登录前和登录后取到的唯一码不一致
现实的问题:
在实际的业务中,用户可能使用各种各样的设备,有着各种各样的前端入口,甚至同一个用户拥有多个设备以及使用多种前端入口,就会出现日志中对同一人不同时间段所收集到的数据可能取到的标识个数,各类各不相同:
如:用户可能会使用的设备:
手机、平板电脑
安卓手机、IOS手机、winphone手机等
安卓也有各种不同的版本
IOS也必须各种不同的版本
由此带来的问题:用户设备的标识没办法轻易定制一个规则来作为唯一标识、不同媒体app的取法不一样,常见的id标识各类如下:
mac:手机网卡的物理地址,若干早期版本的ios,winphone,andriod可取到
IMEI:手机串号,安卓可以取到,若干早期IOS,winphone可以取到,运营商可以取到
IMSI:手机SIM卡序号,安卓可以,早期IOS,WINPHONE,运营商也可以取到
androidid:安卓id
openuuid(app自己生成的序号):卸载重装app后就会变更
idfa:广告跟踪码
deviceid:app日志采集埋点开发人员自己定义的一种逻辑id,可能取自android,imei,openuuid等),逻辑上的id
从而导致:
有一些数据 中,用户有登录帐号,而有些却没有
有一些数据中,有imei码,mac地址,而有些则没有mac地址和android
如果按之前的方案来生成数据的唯一标识 ,显然是错漏百出的。
要从这些杂乱的id中分辨出哪些id是属于同一个用户(设备),用普通的 where x=y这种简单的逻辑是很难实现的。
一。解决方案一:利用外部存储,如redis
将每个用户登录的日志中提取出用户名/imei/mac/手机号等,存储到一个redis的id库中,并为此日志中的id生成一个唯一的id号,当只要有相同(及可关联的信息)日志中部分信息与id库中存储的信息一致时,就把它识别为同一个人,以此不断收集相同相关联的信息,组合生成一个用户的完整资料。这样只要重复多次后就可以拿到一个用户的准确信息。定期对此redis数据进行整理合并。当然也可以通过帐号不同时来做一些简单的手工修复来进行整理。
具体实现:
1、从日志数据中抽取出各种标识id
2、将提取到的标识id再去redis标识库中查询是否存在与日志中抽取出的id有重合或关联的信息
3、如果不存在,则新建一个唯一的统一标识,并建立新的标识库
4、如果存在,则使用已存在的唯一标识,并把剩下不一样的标识加入到原标识库中,作为以后标识关联的依据
也有可能在某个阶段上,这些数据间完全没有任何关联联系,那么这个人的数据就可能被打成两个不同的标识,此时可以定期对redis中的id映射进行整理合并。
也有可能合并后两人不同的人又被打上相同的唯一标识。
解决方案二:spark图计算,尤其适合多端打通的时候
利用spark图计算,找出各种id标识之间的关联关系去标识同一个人。
核心思想:
将数据表达成“点”,点和点之间可以通过某种业务建立“边”。
再可以从点、边上找出各种数据的关系:比如连通性;最短路径规划
将上图进行提取,生成下图的算法:看哪些可以连通成一个子图,即生成一个唯一id,得到一张id映射表,再拿着这张表来对每条日志打上唯一标识
具体实现思路:
1、将当日数据中的所有用户标识字段、及标志字段之间的关联,重心在点集合、边集合
2、将上一日的ids->guid的映射关系,也生成相应的点集合、边集合
3、将上面两类点集合、边集合合并到一起生成一个图
4、通过上面生成的图利用“最大连通子图”算法,得到一个连通子图结果
5、从结果图中提取出哪些id是同一组,并据此生成一个唯一标识
6、将上面生成的唯一标识 去比对前日的ids->guid映射表(如果某个人已存在guid,直接沿用原来的guid)
源码:https://gitee.com/liminghui321/cooperation
参考原文:https://blog.youkuaiyun.com/qq_36269641/article/details/109577071