产品需求:
- 显示用户的行为记录上第几次访问: 比如:『张三第3次访问了这篇文章』
想法1:
- 实现:首先想到的是去数据库『明细』表中查询一下历史数量,然后本次入库+1
- 问题:很明显,性能差到爆
想法2:
- 实现: 在数据库中维护字典,描述为『最后的次数』
- 问题:性能好是好点了,但抗不住并发,抗不住高峰(不用高,低的并发也抗不住)
想法3:
- 实现: 将字典缓存在Redis中,使用inc自增,进行缓存
- 问题:redis字典数据的生命周期,时间越久,数据越大,总有一天能占满,或者更换redis时次数字典将会丢失
想法4:
- 实现:对Redis中次数字典进行生命周期管理,定时持久化到数据库,redis数据设置自动过期,行为数据一般会有会话周期的,集中在某个时间段访问,过后访问的概率比较低(没有继续缓存的必要),如果之后再来访问,会从数据库中加载到Redis中,继续会话
- 问题:这样的实现逻辑相对来说比较复杂,功能还不能复用
想法5:
- 实现:修改埋点系统,定义『次数』函数,第几次,次数类属性上报时,指定生成方式为函数式生成,并指定入参。服务器接收数据上报后,通过反射找到对应属性值的函数定义(比如是一串字符: “#times_function,user_id”),传入对应的参数并执行。返回当前的次数。函数内的实现逻辑就是上面『想法4以上』逻辑,之后的带有次数类属性的埋点需求就能够通用
—话外题:
从次数的持久化联想到用户属性的存储问题,Doris存储只能是整行替换,不利于单属性更新场景,整行替换在更新多个属性时会容易出现并发问题,既然如此,带有更新某属性逻辑的数据,可以持久化到mysql中,通过binlog to doris逻辑将数据同步过来,这样可以解决用户画像:『用户基本信息』的存储更新问题,将数据同步过来在Doris一个环境后就能完成(『用户基本信息』+『用户标签』+『用户行为』+『用户群组』+『用户关系』)的交叉分析