【沉淀之华】从0到1实现用户推荐 - 实时特征系统构建,包含特征计算,特征存储,特征查询,特征补偿超详细思路分享

文章目录

    • 背景介绍
      • 设计初衷
      • 基本概念
    • 技术架构
      • "四高"
      • 特征存储
      • 特征计算
      • 特征查询
      • 特征补偿
    • 技术难点Q&A
    • 彩蛋

背景介绍

设计初衷

作为用户推荐系统的支撑系统之一:用户实时特征系统有着举足轻重的重要,甚至说它是一起推荐行为触发的必要条件。而实时特征系统价值除了为实时推荐获取用户特征提供基础能力,对离线数据训练模型也起到关键支撑。

在这里插入图片描述
离线训练流程
在这里插入图片描述

由于我主要负责实时系统, 离线训练细节逻辑由专门算法同学负责,通过经验分享和沟通也得到了算法同学认可如上图所示

看起来实时特征的生产和离线训练生产特征 逻辑大体相同,但是实时特征对数据一致性,及时性以及对接口的响应RT是要求极高的, 我们业务中就要在峰值5000+QPS的背景下 要求P995 在500ms 以内返回,那么如何做到这一点,请听我娓娓道来…
在这里插入图片描述

基本概念

考虑有些同学可能还未接触过,这里把一些本文涉及到核心概念做了总结,让大家有个整体感受

关键词描述备注
用户画像用户画像的本质是通过对用户的行为分析和统计,挖掘用户的需求、兴趣和习惯购买行为,支付方式,浏览习惯
客群特定的、拥有共同特性(可能是年龄、收入、性别、购买行为等)的消费者群体例如:喜欢购买骑行卡的用户骑车在xx岁的用户
特征通常是描述用户特定行为或属性,也可以是城市、车辆某些行为如:购卡用户、多少日内骑行用户免押金城市、订单量大于xx的城市等
标签进一步具体刻画特征,或者说在业务实践中的常用术语技术层面对特征具象化
物料用户的原始特征,如身份、年龄、职业等技术层面理解就是未进入到特征系统的业务数据
Point-in time时间点准确预测可直接影响离线训练模型结果,也就是常说的特征穿越问题
用户活跃度活跃期、沉默期、沉睡期
召回根据原始特征快速分析用户的泛化兴趣,即粗略的共同爱好进行参与排序计算实时推荐第一步

在这里插入图片描述

其他概念都比较好理解,特征穿越可能会有点疑惑,本文重点不在这,但是文末有进一步解释

技术架构

“四高”

在这么一个在推荐业务及其重要的环节,怎么保证实时特征生产和查询的及时性,准确性,以及服务的高可用性、高并发、高性能,同时为了兼容后续业务迭代如何让特征生产具备高扩展性,几经打磨如下技术体系:
在这里插入图片描述
下面我们分析每一个业务模块

特征存储

如果说实时特征系统是用户推荐的关键一环,那么特征存储选择决定了"三高"的上限,这里我们采用ES 集群 + Redis 主从架构,

为什么选择ES?
众所周知,本身ES集群本身基于Raft协议在数据一致性可以得到很好的保障,加上本身基于lucence引擎在搜索领域早已崭露头角,高性能查询当之无愧,此外ES集群采用1主2从,多副本分片机制加之运维人员合理配置,承载高并发、高可用性也是可以轻松做到。

至于Redis,考虑的即便是实时特征也有进一步对特征时效性的区分即高时效性和一般时效性,例如对某些用户特征要求1秒级返回,有的可以允许几分钟时延,因此Redis主要是做这部分时效性一般特征的抗压组件再合适不过。


特征计算

和离线采集一样,实时特征采集也是需要经过ETL标准流程,通过承接不同业务事件,做一般时效性特征采集,转化到最终匹配到统一特征模型配置中,而针对于时效性很高的特征,分两步,有的直接通过业务接口同步更新,对于链路较长的业务特征采集,则是通过直接加载业务数据源方式构建
在这里插入图片描述
然而,随着用户行为累积,特征的表现形式也多种多样,如何灵活特征的衍生和快速配置方式让特征生效

在设计之初就考虑到了这一典故,我对特征进行元数据管理,对特征来源,特征计算逻辑也进行单独管理,事实上背后最关键的技术也是来自ES本身支持场景基本单一【这是选择ES另一个考虑】,其中内置很多计算函数:如sum,max,min,avg等,基于此可以灵活衍生多个不同维度复杂算子同时我们还有专门的管理后台对特征进行状态上下线,以及通用计算逻辑界面化配置[可以参考下],这样可以极大减少开发周期,几乎无需写代码即可实现新特征注册上线及使用。

在这里插入图片描述
在这里插入图片描述

特征计算配置得益于我们在初始化阶段就构造了20多个算子, 可以支持一般性特征扩展。


特征查询

查询其实在特征计算也提到过,对推荐系统来说,查询RT越低,在用户侧推荐效果就越好。因此我们对特征进行时效性划分, 当需要时效性一般的数据,直接走缓存,如果缓存未命中则直接从ES全量集合中获取,对于时效性较高的走ES查询,而对于时效性极高的特征,则是优先从业务数据源直接查询

可能会有疑问:这么高的并发业务库能承载的了这样的查询吗?
A:首先特征系统在接入业务数据源的时候,业务方基本都做了读写分离,加上一主多从的机制可以充分分担查询压力,同时对于这种时效极高的数据特征case是比较少的,基本只存在特定页面过来。为了防止突发流量,我们也做了相应的限流和熔断机制
在这里插入图片描述


特征补偿

特征补偿,主要发生在监听业务事件消费逻辑上,也就是非实时性较高的特征场,而且生产环境很难完全规避中间件抖动带来的影响,所以对于这部分特征我们采用异步任务,对消费异常过程的特征进行打点,然后在业务低峰期进行对应特征事件数据补偿:比如在监听用户购卡、结单消息出现问题时,通过user_id和异常消费时间线是一定可以从业务数据找到对应特征元数据并补充到ES中。


技术难点Q&A

1. 数据一致性保障?
这里存在三处不一致需要解决

  • 不可重复读:当查询请求介于更新相同特征之间时容易引发不可重复读的问题,那么常见的思路就是需要考虑加版本号控制,ES也提供了这样的机制
  • 增量更新:对于实时特征来说,基本都是基于用户当天的行为特征, 比如是否注册用户,复活用户等应该保障一天只更新1次,而不是出现特征覆盖的情况造成推荐系统紊乱
  • 数据加工一致:作为特征生产的集中站,我们从业务那里无论是异步还是同步加载特征源信息,都应该在解析,转换以及使用都应该和业务保持一致,比如数据脱敏,例如我们从用户系统获取用户信息,我们也需要保持同样的加密和解密算法逻辑,还有类似对状态,枚举的定义甚至文字说明也要保持一致,避免数据误差。

2. 数据幂等

这个最容易忽略,业务方在产生这些数据特征, 尤其是状态相关的一般也是随着业务规模才逐渐加上了幂等逻辑,而对于特征消费场景来说,幂等也是应考虑的重点,以避免对特征数据源产生较高写操作,是系统压力集中站,必须要谨慎设计

3. 如何尽最大努力保障业务数据源的稳定性
前面提到,我们会有兜底逻辑查询业务数据源,尤其是实效性极高的特征,虽然早期并发不高,但是如果业务扩展,高并发查询进来势必会对系统带来查询瓶颈,那么改如何优化?

  1. 做到同一个用户只查询1次, 这取决特征元数据抽取和特征配置表的设计思路,如下图所示
    在这里插入图片描述
    这就是看技术经理怎么设计了,一般来说从理解上看特征与数据源关系是多对多:一个数据源可以生成多个特征,一个特征可能需要来自多个数据源特征共同组成,因此如果只从技术考虑那么这个实现复杂度是N*M,因此为了降低复杂度在设计的时候我们采用了数据库第二范式冗余字段,进行优化对一个数据源一次性抽取所有特征, 即便并不关心是否一定需要最终使用,也避免多次占用网络带宽造成的性能损耗。

4. 复杂特征计算通用性
简单特征只需要经过1次预处理就可以完成写入,但是对于复杂的特征分为2类:

  • 特征消费时可以确定的逻辑:即便如此,也需要组合多个特征输入甚至还要对某些特征加工, 然后作为最终特征构建的输入,这里我们统一借助特征算子配置,以预定义函数算子 + Stream表达式方式去编排拼接得到最终的复杂特征,这个过程可以通过管理页面进行控制,而无需手动编码,可以快速响应产品需求变化
  • 对于特征生产无法确定的逻辑,比如甚至需要依靠实时推荐系统查询提供输入才能最终确定逻辑:对于这部分特征只能硬编码去根据推荐输入参数实时处理并得到期望的特征值。

还有更多的细节问题,有过一定开发经验童鞋通过网络也能顺腾摸瓜思考得以解决,千篇一律,这里就不一一举例了


彩蛋

什么是特征穿越【Point In Time】?

我也是盲人摸象,慢慢熟悉之后整个流程才了解,这个情况倒不会发生咋实时系统,而是多在离线训练发生,但是起点仍然在实时特征中心

简单来说,通过营销推荐策略推给用户导致的购买行为,本应该在T1时刻关联的对应的特征,但是因为系统时效性或者逻辑漏洞造成关联的T0 时刻特征,这就会对模型训练造成极大干扰,导致最终生产的模型不佳,举例如下:

在这里插入图片描述

采用ChatGPT举例生成,以此说明
如上图所示, 用户在9点时刻行为,只能使用9点之前用户的特征【过去购买、点击的商品】,如果使用了9点之后的信息来构建就会产生特征穿越,因为包含了未来的信息导致模型训练和预测结果存在显著差异,从而反应模型表现很差

写在最后, 深耕不易,如需转载和复制,请备注出处!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/5723.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c#word文档:3.向Word文档中插入表格/4.读取Word文档中表格

--向Word文档中插入表格-- (1)在OfficeOperator项目的WordOperator类中定义向Word文档插入换页的函数NewPage (2)在WordOperator类中定义向Word文档插入表格的函数InsertTable using Microsoft.Office.Interop.Word;// 引入Mic…

探索APP内测分发的全过程(APP开发)

什么是APP内测分发探索APP内测分发的全过程? APP内测分发是在应用程序开发过程中探索APP内测分发的全过程,开发者将应用程序的测试版或预发布版分发给特定用户进行测试、反馈和评估的一种方式。这是一个非常重要的环节,可以有效地提高应用的…

详解SDRAM基本原理以及FPGA实现读写控制

文章目录 一、SDRAM简介二、SDRAM存取结构以及原理2.1 BANK以及存储单元结构2.2 功能框图2.3 SDRAM速度等级以及容量计算 三、SDRAM操作命令3.1 禁止命令: 4b1xxx3.2 空操作命令:4b01113.3 激活命令:4b00113.4 读命令:4b01013.5 写…

mac如何打开exe文件?如何mac运行exe文件 如何在Mac上打开/修复/恢复DMG文件

在macOS系统中,无法直接运行Windows系统中的.exe文件,因为macOS和Windows使用的是不同的操作系统。然而,有时我们仍然需要运行.exe文件,比如某些软件只有Windows版本,或者我们需要在macOS系统中运行Windows程序。 虽然…

如何安全的使用密码登录账号(在不知道密码的情况下)

首先,需要用到的这个工具: 度娘网盘 提取码:qwu2 蓝奏云 提取码:2r1z 1、打开工具,进入账号密码模块,如图 2、看到鼠标移动到密码那一栏有提示,按住Ctrl或者Alt点击或者双击就能复制内容&…

正版Office-Word使用时却提示无网络连接请检查你的网络设置 然后重试

这是购买电脑时自带的已经安装好的word。看纸箱外壳有office标记,但是好像没有印系列号。 某天要使用。提示:无网络连接请检查你的网络设置。 经过网上高手的提示: 说要勾选勾选ssl3.0、TLS1.0、1.1、1.2。 我的截图 我电脑进去就缺1.2. …

PCIe总线-MPS MRRS RCB参数介绍(四)

1.概述 PCIe总线的存储器写请求、存储器读完成等TLP中含有数据负载,即Data Payload。Data Payload的长度和MPS(Max Payload Size)、MRRS(Max Read Request Size)和RCB(Read Completion Boundary&#xff0…

C++ 抽象机制

抽象机制 1. 虚函数 使用关键字virtual 声明的函数,意思是可能随后在其派生类中重新定义。 纯虚函数 在声明的末尾使用0 的函数,说明是纯虚函数。 抽象类 含有纯虚函数多的类称为抽象类(abstract class). 多态类型 如果一个类负责为其他一些类提供接…

unity入门——按钮点击了却无法调用函数

查阅了一番都没有解决问题,最后发现问题是由button的Onclick()事件绑定了代码脚本而不是游戏对象导致的。 如果Onclick()事件绑定的是代码脚本,则下拉框里没有函数,但是点击MonoScript后能手动填入函数名(本以为这样就能实现调用…

State.initState() must be a void method without an `async` keyword错误解析

文章目录 报错问题报错的代码 错误原因解决方法解析 另外的方法 报错问题 State.initState() must be a void method without an async keyword如下图: 报错的代码 报错的代码如下: overridevoid initState() async{super.initState();await getConf…

openssl3.2 - exp - 使用默认的函数宏,在release版中也会引入__FILE__

文章目录 openssl3.2 - exp - 使用默认的函数宏,在release版中也会引入__FILE__概述笔记验证是否__FILE__在release版下也能用?将openssl编译成release版的,看看CRYPTO_free()是否只需要一个参数就行?将工程中的openssl相关的库换…

重定义大语言模型的记忆能力:对抗性压缩如何挑战现有测量法

DeepVisionary 每日深度学习前沿科技推送&顶会论文分享,与你一起了解前沿深度学习信息! Rethinking LLM Memorization through the Lens of Adversarial Compression 引言:探索大型语言模型的记忆能力 在当今信息时代,大型…

Window(Qt/Vs)软件添加版本信息

Window(Qt/Vs)软件添加版本信息 文章目录 Window(Qt/Vs)软件添加版本信息VS添加版本信息添加资源文件添加版本定义头自动更新版本添加批处理脚本设置生成事件 Qt添加版本信息添加资源文件文件信息修改自动更新版本 CMake添加版本信…

#ESP32S3R8N8建立工程(VSCODE)点亮LED

1.参考文档 【立创ESP32S3R8N8】IDF入门手册 - 飞书云文档 (feishu.cn)https://lceda001.feishu.cn/wiki/GOIlwwfbIi1SC3k8594cDeFVn8g 2.建立工程 3.运行效果 4.更改配置 5.插播 之前配置的环境是有问题的,就算有自动检测也要仔细检查,必须严格按照以…

VMware安装ubuntun虚拟机使用桥接模式无法上网问题解决

问题:最近准备使用VMware虚拟机搭建k8s集群服务,因为需要在同一个网段下,我使用桥接的方式,我发现主机在使用有线连接时虚拟机网络连接正常,但是使用无线网就显示连接不上网络。 解决方法 一、查看网络连接&#xff…

aardio封装库) 微软开源的js引擎(ChakraCore)

前言 做爬虫肯定少不了JavaScript引擎的使用,比如在Python中现在一般用pyexecjs2来执行JavaScript代码,另外还有一些其他执行JavaScript的库: https://github.com/eight04/node_vm2: rpc调用nodejs,需要安装nodehttps://github.…

Spring Data JPA数据批量插入、批量更新真的用对了吗

Spring Data JPA系列 1、SpringBoot集成JPA及基本使用 2、Spring Data JPA Criteria查询、部分字段查询 3、Spring Data JPA数据批量插入、批量更新真的用对了吗 前言 在前两篇文章已经介绍过,在使用Spring Data JPA时,DAO层的Respository通过继承J…

BigKey的危害

1.2.1、BigKey的危害 网络阻塞 对BigKey执行读请求时,少量的QPS就可能导致带宽使用率被占满,导致Redis实例,乃至所在物理机变慢 数据倾斜 BigKey所在的Redis实例内存使用率远超其他实例,无法使数据分片的内存资源达到均衡 Redis阻…

Python中动画显示与gif生成

1. 动画生成 主要使用的是 matplotlib.animation ,具体示例如下: import matplotlib.pyplot as plt import matplotlib.animation as animation import numpy as np fig, ax plt.subplots() t np.linspace(0, 3, 40) g -9.81 v0 12 z g * t**2 / …

新建stm32工程模板步骤

1.先使用keil新建一个project的基本代码 2.stm32启动文件添加 将stm32的启动文件,在原工程当中新建一个Start文件夹把相关的启动文件放到文件夹当中 然后还需要找到下面三个文件 stm32f10x.h是stm32的外设寄存器的声明和定义,后面那两个文件用于配置系…