1. 为什么要构建一个地理位置维表(字典)
在埋点日志中,有用户的地理位置信息,但是原始数据形式是GPS坐标,而GPS坐标在后续(地理位置维度分析)的分析中不好使用。gps坐标的匹配,不应该做这种精确匹配,应该做范围匹配,直接去匹配两个哪怕距离很近的gps坐标,很可能匹配不上,所以需要一个地理位置维表
2. 地理位置维表的设计模型(构建思想)是什么?
使用一种算法,将GPS坐标转换成一个字符串,并且当两个GPS坐标靠的越近,字符串的的吻合度会更大,这样就能通过GPS得到的字符串的吻合情况判断出该GPS的地理位置。
3. geohash地理位置字典构建的流程你能描述一下吗?
首先通过mysql中一系列的sql语句,得到包含经纬度信息,以及对应的省市区信息的表,然后在这个基础上,使用spark读取这个表中的数据,并调用geohash算法,将经纬度转换成转成字符串,然后将结果保存到指定文件中去,由于此处是用spark处理的,所以一般是保存到parquet文件中。
4. geohah编码的算法思想能够描述一下?
不断地将地球的经度、纬度范围,进行二分,输出1/0比特,形成一串二进制码(二分的次数越多,输出的bit串越长)。
然后将这一串二进制码,按照5bit一组合查base32码表,
输出最终结果!
5. idmapping是什么含义?为什么要做idmapping?
idmapping其实就是对每条行为日志数据按照其内部的一些标识(比如uid/imei码/imsi码/mac/androidid/uuid),确定该条数据的所属用户。
- 现实的无奈
在现实的日志数据中,由于,用户可能使用各种各样的设备,有着各种各样的前端入口,甚至同一个用户拥有多个设备以及使用多种前端入口,就会导致,日志数据中对同一个人,不同时间段所收集到的日志数据中,可能取到的标识个数、种类各不相同;
比如:
用户可能使用各种各样的设备:
1)手机、平板电脑
2)安卓手机、ios手机、winphone手机
3)安卓系统有各种版本 ( 5.0 6.0 7.0 8.0 9.0 )
4)ios系统也有各种版本(3.x 4.x 5.x 6.x 7.x .... 12.x )
产生问题:
用户设备的标识,没办法轻易定制一个规则来取某个作为唯一标识:
mac:手机网卡物理地址, 若干早期版本的ios,winphone,android可取到
imei(入网许可证序号):安卓系统可取到,若干早期版本的ios,winphone可取到,运营商可取到
imsi(手机SIM卡序号):安卓系统可取到,若干早期版本的ios,winphone可取到,运营商可取到
androidid :安卓系统id
openuuid(app自己生成的序号) :卸载重装app就会变更
idfa(广告跟踪码)
deviceid(app日志采集埋点开发人员自己定义一种逻辑id,可能取自android,imei,openudid等):逻辑上的id
- 从而导致:
有一些数据中,用户有登录账号,而有些没有;
有一些数据中,有imei码,mac地址;而有些则有mac地址和android;
前一日的数据中,有uid,android,而后一日数据中有android,mac地址
在这些情况中,如果按照之前的方案来生成数据的唯一标识,显然错漏百出!
如下图:
要从这些纷繁复杂的各类id中,分辨出哪些id属于同一个受众(设备),用普通的“where x=y”这种简单条件逻辑很难实现。
6. 利用redis来实现idmapping的思想、流程?
(1)思想:
将用户的各种id标识在redis作为key存储,而对应的value为用户的统一标识,这样只要查看redis中的key就能得出用户的信息
(2)流程:
在redis创建idmapping表,其中标识id为key,对应用户的统一标识为value===>从日志数据中抽取一条数据的所有标识id===>判断提取出来的标识id是否存在一个为idmapping表的key===>若不存在,则将这些标识id作为key,value为该批标识id中按字典排序最小的标识id,并存到idmapping表中,若存在,则取出key对应的值,并将其余的标识id都作为key,value为刚取出的值,存入idmapping表。
7. 利用图计算来实现idmapping的思想、流程?
(1)思想
采用图计算手段,找到各种id标识之间的关联关系,从而识别出哪些id标识属于同一个人
(2)流程
- 将当日数据中的所有用户标识字段,及标志字段之间的关联,生成点集合、边集合
-
将上一日的ids->guid的映射关系,也生成点集合、边集合
- 将上面两类点集合、边集合合并到一起生成一个图
-
再对上述的图执行“最大连通子图”算法,得到一个连通子图结果
-
在从结果图中取到哪些id属于同一组,并生成一个唯一标识
-
将上面步骤生成的唯一标识去比对前日的ids->guid映射表(如果一个人已经存在guid,则沿用原来的guid)
8. 目前的方案中都存在哪些问题?可能会造成什么样的影响?
方案一:借助redis实现idmapping
(1)这种形式的idmapping会将同一个人的日志行为识别成多个人的,但是回溯,将以前某天是同一个guid的多人合并,修改key-value时,计算量会很大,一般是不去做的
(2)这种形式会造成将单个用户识别成多个用户,影响后续的数据分析
方案二:使用图计算实现idmapping
(1)该方式可以通过将当日的id映射字典与前一日的id映射字典进行结合的方式,解决一个用户被当作多个用户的行为。但其又带来了另外一个问题,比如T-1天一个用户被识别成多个人(即存在多个用户统一标识:guid),并且在T天发现其为1个人,这时T天的guid就只能选择前一天多个guid的之一了,这样以来guid的延续性就不能保证了
(2)当进行数据分析时,比如对前几天的数据进行统计分析时,其还是会将diT-1天的数据识别成多个人,就会造成数据分析的不准确,
9. 项目中前一日的id映射字典和当日的id映射字典如何结合?
(1)将上一日的idmap映射字典,解析成点、边集合
(2)构造当日图计算中的点集合以及边集合
(3)分别将装有上一日的点集合的rdd与当日的点集合的rdd,上一日的边集合的rdd与当日的边集合的rdd进行union