简介
权重通常是指某一因素或指标相对于某一事物的重要程度。在电商中我们可以根据用户行为进行数据埋点,进而对其进行权重配分,更专业的叫法就是 用户画像 。不同的角度有不同的叫法,但是权重主要还是为了帮助我们更好的了解使用者的使用轨迹。
模块
主要划分为下面三个模块
规则
根据数据进行权重配分,因为每个数据的配分都是不同的。比如:用户每天登录一次游戏,那么就加一分这样。然后对于分值大于某个值后可以春节发个积极奖等等。
聚合统计
根据埋点获取到的数据进行聚合,比如:将每天的数据聚合成每个月,然后再匹配当前的规则进行权重配分。
数据埋点
根据前端对接埋点接口,然后将数据落地,数据的来源基本来自埋点。具体如何设计埋点可以看看那这一篇文章。如何做好数据埋点?
例子
权重系统在之前工作当中有实施过,现在大概说一下当时的情况。
- 定时任务拉取各个微服务系统的埋点数据
- 定时任务对当天数据根据权重规则进行配分并按天将数据落地
- 定时任务根据业务对数据进行聚合处理
规则定义
1 2 3 4 5 6 7 8 9 10
| CREATE TABLE `rule_path` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `pid` int(10) unsigned DEFAULT '0' COMMENT '父级id', `name` varchar(36) DEFAULT '' COMMENT '名称', `is_use` tinyint(4) DEFAULT '1' COMMENT '1.使用 2.禁用', `created_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updated_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间', `deleted_at` datetime DEFAULT NULL COMMENT '删除时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB CHARSET=utf8mb4 COMMENT='规则路径表';
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| CREATE TABLE `rule_leaf` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `path_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '权重路径id', `handle_type` tinyint(4) DEFAULT '1' COMMENT '权重处理类型 1.单次 2.循环', `point` int(10) DEFAULT '0' COMMENT '配分', `total_point` int(10) DEFAULT '0' COMMENT '配分总和', `condition_point` int(10) DEFAULT NULL COMMENT '条件值', `limit_type` tinyint(4) DEFAULT '1' COMMENT '上限: 1.日 2.周 3.月 4.年', `limit` int(10) DEFAULT '0' COMMENT '上限值', `condition_being` varchar(36) DEFAULT NULL COMMENT '字段标识开始', `condition_end` varchar(36) DEFAULT NULL COMMENT '字段标识结束', `is_use` tinyint(4) DEFAULT '1' COMMENT '1.使用 2.禁用', `special` json DEFAULT NULL COMMENT '特殊字段,根据业务进行配置', `created_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updated_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间', `deleted_at` datetime DEFAULT NULL COMMENT '删除时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='规则叶子节点表';
|

配分计算
首先因为不同的规则存在不同的计算方式,所以我们可以定义一个 Context
上下文对象,使用 rule_leaf
表的主键 id
作为键值,相关的值使用计算的类。这样子我们就能够对不同的类型使用不同的计算方式了。
1 2 3 4 5 6 7 8 9 10 11 12
| class WeightContext { private $maps = [ 1 => VersionCalculate::class, 2 => LoopCalculate::class, ];
public excute($leafId, array $elements) { return (new $maps[$leafId]())->exec($elements); } }
|
1 2 3 4
| interface CalculateInterface { public function exec(array $elements); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class VersionCalculate implements CalculateInterface { public function exec(array $elements) { } }
class LoopCalculate implements CalculateInterface { public function exec(array $elements) { } }
|
因为这些配置规则计算都是非常多变的, 所以在编写配分计算的时候必须要考虑到可扩展性,最后我们使用采用 策略模式 进行编写。
数据聚合
聚合是基于当前埋点数据,将天的维度聚合为周,月,年。根据不同的业务需求,我们可以聚合不同的数据维度。
缺点
埋点数据没有统一处理,导致出错问题分散在各个服务负责人身上。
优点
配分计算部分采用 策略模式 ,使得算法可以自由切换并且扩展性良好。