PAI-Rec是一款基于Go的在线推荐服务引擎的框架,您可以基于此框架快速搭建在线推荐服务,也可以定制化进行二次开发。本文为您介绍如何在DataScience集群上使用PAI-Rec搭建一个简单的在线推荐服务,实现U2I召回和特征加载。
背景信息
PAI-Rec框架内容如下:
集成Go http Server,提供路由注册功能,方便开发Restful API。
包含推荐引擎的Pipeline流程,里面预定义了多种召回、过滤、排序策略,内置访问阿里云EAS服务。
包含多种数据源的加载,支持Hologres、MySQL、Redis、Tablestore(OTS)和Kafka等。
基于灵活的配置描述推荐流程。
集成轻量级A/B Test实验平台。
支持简单易用的扩展点,方便自定义操作。
更多框架信息,请参见PAI-Rec文档。
前提条件
操作流程
步骤一:数据准备
因为要实现U2I召回和特征加载,所以需要准备相应的召回表和特征表。
单击preparedata_mysql.sql,下载示例文件。
该文件会帮您创建db_pairecdemo数据库及以下数据表:
召回表:t_recall,包含字段user_id,表示用户ID,字段item_ids表示对应要召回的物品ID。
user特征表:t_userfeature,包含字段user_id和若干特征字段。
item特征表:t_itemfeature,包含字段item_id和若干特征字段。
重要示例中的库、表和字段信息会在之后的推荐引擎配置中用到。其中召回表的结构定义是约定好的,不能随意更改配置。更多配置详情请参见配置总览。
执行以下命令,获取MySQL服务的IP地址和端口。
kubectl -n bitnami get svc mysql
使用MySQL客户端连接服务,执行preparedata_mysql.sql文件。
说明数据库root账号的默认密码为emr-datascience。
步骤二:加载配置
PAI-Rec推荐引擎的具体Pipeline流程由配置定义,目前配置支持启动时加载config配置文件和通过配置中心热加载两种方式,本示例为通过配置中心热加载的方式。
配置中心也一同部署在DataScience上。
执行以下命令,获取端口。
kubectl -n pairec get svc pairec-experiment -o jsonpath='{.spec.ports[0].nodePort}'
访问http://<header1节点的IP地址>:<端口>链接,登录配置中心。
默认用户名和密码均为admin。
说明<端口>为步骤1获取到的。
新增配置。
在左侧导航栏,选择 。
在推荐引擎配置页面,单击新增。
在新增配置对话框中,填写配置名称和配置内容,选择运行环境。
参数
描述
配置名称
填写为pairec_config。
DataScience上部署的PAI-Rec推荐引擎,默认使用日常环境下名称为pairec_config的配置。因此这里的配置名称设为pairec_config,运行环境设为日常环境。
运行环境
选择日常环境。
配置内容分为以下几部分:
数据源配置
{ // ... "MysqlConfs": { // mysql 配置 "pairec-mysql": { // 自定义名称 "DSN": "root:emr-datascience@tcp(mysql.bitnami)/db_pairecdemo?parseTime=true&loc=Asia%2FShanghai" } }, // ... }
如果默认配置中没有MysqlConfs,新增即可。名称您可以自定义,会在之后用到。数据库设为之前数据准备中创建的db_pairecdemo。
召回配置
{ // ... "RecallConfs": [ { "Name": "user2item_recall", "RecallType": "UserCustomRecall", "ItemType": "video", "RecallCount": 500, "DaoConf": { "AdapterType": "mysql", "MysqlName": "pairec-mysql", "MysqlTable": "t_recall" } } ], // ... "SceneConfs": { "default_scene": { "default": { "RecallNames": [ "user2item_recall" ] } } }, // ... }
需要在场景配置中启用配置好的user2item_recall。其中,涉及的参数如下表所示。
参数
描述
RecallType
填写为UserCustomRecall ,表示使用U2I的召回方式。
RecallCount
填写为500,表示最多召回500个item。
AdapterType
填写为mysql,表示使用MySQL数据源。
MysqlName
填写为pairec-mysql,表示使用上文中配置的数据源- pairec-mysql。
MysqlTable
填写为t_recall,表示召回表名称为t_recall。
特征配置
{ // ... "FeatureConfs": { "default_scene": { "AsynLoadFeature": true, "FeatureLoadConfs": [ { "FeatureDaoConf": { "AdapterType": "mysql", "MysqlName": "pairec-mysql", "FeatureKey": "user:uid", "UserFeatureKeyName": "user_id", "MysqlTable": "t_userfeature", "UserSelectFields": "c1,c14,c15,c16,c17,c18,c19,c20,c21", "FeatureStore": "user" }, "Features": [ ] }, { "FeatureDaoConf": { "AdapterType": "mysql", "MysqlName": "pairec-mysql", "ItemFeatureKeyName": "item_id", "FeatureKey": "item:id", "MysqlTable": "t_itemfeature", "ItemSelectFields": "item_id,app_category,app_domain,app_id,banner_pos,device_conn_type,device_id,device_ip,device_model,device_type,hour,site_category,site_domain,site_id", "FeatureStore": "item" }, "Features": [ ] } ] } } // ... }
其中,涉及的参数如下表所示。
参数
描述
AdapterType
填写为mysql,表示使用MySQL数据源。
MysqlName
填写为pairec-mysql,表示使用上文中配置的数据源。
MysqlTable
填写为t_recall,表示召回表名称为 t_recall。
UserFeatureKeyName
用于指定特征表查询条件中的字段名。
ItemFeatureKeyName
FeatureKey
用于指定从哪里获取特征表查询条件中的字段值。
UserSelectFields
用于指定查询哪些特征。
ItemSelectFields
FeatureStore
用于指定将查询得到的特征存到哪里。
完成配置后,单击确定。
保存配置后,单击配置操作列的发布。
发布配置,引擎会自动加载设置好的配置。
步骤三:推荐测试
PAI-Rec引擎推荐接口为/api/rec/feed,访问此接口即可进行推荐测试(需要获取引擎服务地址)。
参数 | 描述 | 类型 | 是否必选 | 示例 |
uid | 用户ID。 | String | 是 | 10**** |
size | 获取item数量。 | Integer | 是 | 10 |
scene_id | 场景ID。 | String | 是 | feed |
category | 类目。 | String | 否 | 无 |
features | 上下文特征。 | JSON Map | 否 | {"age":20,"sex":"male"} |
debug | 打印更多的日志。 | BOOL | 否 | true |
您可以通过以下命令获取引擎端口,然后http://<header1节点的IP地址>:<端口>即为服务地址。
kubectl -n pairec get svc pairec-engine -o jsonpath='{.spec.ports[0].nodePort}'
假设服务地址为http://127.0.0.1:32204,则可以使用curl工具进行访问和测试。
curl http://127.0.0.1:32204/api/rec/feed -d '{"uid":"10****", "size":2, "debug":true}'
因为召回和特征都配置在default_scene,即默认场景下,所以此处无需指定scene_id。
当返回如下信息时,表示流程执行成功。如果推荐结果有问题或有其他需求,可以通过日志分析排查推荐流程,详情信息请参见日志分析。
{
"code": 200,
"msg": "success",
"request_id": "16dda535-9d7f-4bbb-aaa9-dc7199f9f6e8",
"size": 2,
"items": [
{
"item_id": "200001",
"score": 0,
"retrieve_id": "user2item_recall"
},
{
"item_id": "200002",
"score": 0,
"retrieve_id": "user2item_recall"
}
]
}
日志分析
如果推荐结果有问题或有其他需求,可以通过日志分析排查推荐流程。
执行以下命令,获取部署的PAI-Rec引擎的pod名称。
kubectl get po -n pairec
返回信息如下所示。
# NAME READY STATUS RESTARTS AGE # pairec-engine-9669c98fd-w9828 1/1 Running 0 2d4h
执行以下命令,打印pod日志。
kubectl logs pairec-engine-9669c98fd-w9828 -n pairec
一次推荐流程的日志示例如下所示。
I1230 08:36:04.103712 6 log.go:13] [INFO] requestId=16dda535-9d7f-4bbb-aaa9-dc7199f9f6e8 event=begin uri=/api/rec/feed address=10.244.0.0:39088 body={"uid":"10****", "size":2, "debug":true} I1230 08:36:04.103814 6 logger.go:18] [ERROR] scene:default_scene, not found the scene info I1230 08:36:04.103828 6 log.go:13] [INFO] requestId=16dda535-9d7f-4bbb-aaa9-dc7199f9f6e8,uid=100001,scene_name=default_scene,exp_id= I1230 08:36:04.106789 6 log.go:13] [INFO] requestId=16dda535-9d7f-4bbb-aaa9-dc7199f9f6e8 module=UserCustomRecall name=user2item_recall count=3 cost=2 I1230 08:36:04.106805 6 log.go:13] [INFO] requestId=16dda535-9d7f-4bbb-aaa9-dc7199f9f6e8 module=recall cost=2 I1230 08:36:04.106815 6 log.go:13] [INFO] requestId=16dda535-9d7f-4bbb-aaa9-dc7199f9f6e8 module=Filter cost=0 I1230 08:36:04.109738 6 log.go:13] [INFO] requestId=16dda535-9d7f-4bbb-aaa9-dc7199f9f6e8 module=LoadFeatures cost=2 &{100001 map[c1:1005 c14:2035 c15:30 c16:25 c17:234 c18:2 c19:4 c20:1002 c21:3 uid:10****] {{0 0} 0 0 0 0}} I1230 08:36:04.109810 6 log.go:13] [INFO] requestId=16dda535-9d7f-4bbb-aaa9-dc7199f9f6e8 module=rank cost=0 &{200001 0 user2item_recall video [] {{0 0} 0 0 0 0} map[app_category:07d7df22 app_domain:7801e8d9 app_id:ecad2386 banner_pos:0 device_conn_type:0 device_id:a99f214a device_ip:9d046c7f device_model:9a45a8e8 device_type:1 hour:21 recall_name:user2item_recall recall_score:0 site_category:3e814130 site_domain:7687a86e site_id:5b08c53b user2item_recall:0] map[]} &{200002 0 user2item_recall video [] {{0 0} 0 0 0 0} map[app_category:07d7df22 app_domain:7801e8d9 app_id:ecad2386 banner_pos:0 device_conn_type:66 device_id:a99f214a device_ip:9d046c7f device_model:9a45a8e8 device_type:23 hour:21 recall_name:user2item_recall recall_score:0 site_category:3e814130 site_domain:7687a86e site_id:5b08c53b user2item_recall:0] map[]} I1230 08:36:04.109973 6 log.go:13] [INFO] requestId=16dda535-9d7f-4bbb-aaa9-dc7199f9f6e8 event=end uri=/api/rec/feed cost=6
展示了Pipeline各个模块的执行情况。其中,count代表结果数量, cost代表花费时间。加载的特征也会打印出来。