伴鱼:借助 Flink 完成机器学习特征系统的升级

简介: Flink 用于机器学习特征工程,解决了特征上线难的问题;以及 SQL + Python UDF 如何用于生产实践。

本文作者陈易生,介绍了伴鱼平台机器学习特征系统的升级,在架构上,从 Spark 转为 Flink,解决了特征上线难的问题,以及 SQL + Python UDF 如何用于生产实践。 主要内容为:

  1. 前言
  2. 老版特征系统 V1
  3. 新版特征系统 V2
  4. 总结

一、前言

在伴鱼,我们在多个在线场景使用机器学习提高用户的使用体验,例如:在伴鱼绘本中,我们根据用户的帖子浏览记录,为用户推荐他们感兴趣的帖子;在转化后台里,我们根据用户的绘本购买记录,为用户推荐他们可能感兴趣的课程等。

特征是机器学习模型的输入。如何高效地将特征从数据源加工出来,让它能够被在线服务高效地访问,决定了我们能否在生产环境可靠地使用机器学习。为此,我们搭建了特征系统,系统性地解决这一问题。目前,伴鱼的机器学习特征系统运行了接近 100 个特征,支持了多个业务线的模型对在线获取特征的需求。

下面,我们将介绍特征系统在伴鱼的演进过程,以及其中的权衡考量。

二、旧版特征系统 V1

特征系统 V1 由三个核心组件构成:特征管道,特征仓库,和特征服务。整体架构如下图所示:

v1 architecture

特征管道包括流特征管道批特征管道,它们分别消费流数据源和批数据源,对数据经过预处理加工成特征 (这一步称为特征工程),并将特征写入特征仓库。

  • 批特征管道使用 Spark 实现,由 DolphinScheduler 进行调度,跑在 YARN 集群上;
  • 出于技术栈的一致考虑,流特征管道使用 Spark Structured Streaming 实现,和批特征管道一样跑在 YARN 集群上。

特征仓库选用合适的存储组件 (Redis) 和数据结构 (Hashes),为模型服务提供低延迟的特征访问能力。之所以选用 Redis 作为存储,是因为:

  • 伴鱼有丰富的 Redis 使用经验;
  • 包括 DoorDash Feature Store和 Feast在内的业界特征仓库解决方案都使用了 Redis。

特征服务屏蔽特征仓库的存储和数据结构,对外暴露 RPC 接口 GetFeatures(EntityName, FeatureNames),提供对特征的低延迟点查询。在实现上,这一接口基本对应于 Redis 的 HMGET EntityName FeatureName_1 ... FeatureName_N 操作。

这一版本的特征系统存在几个问题:

  • 算法工程师缺少控制,导致迭代效率低。这个问题与系统涉及的技术栈和公司的组织架构有关。在整个系统中,特征管道的迭代需求最高,一旦模型对特征有新的需求,就需要修改或者编写一个新的 Spark 任务。而 Spark 任务的编写需要有一定的 Java 或 Scala 知识,不属于算法工程师的常见技能,因此交由大数据团队全权负责。大数据团队同时负责多项数据需求,往往有很多排期任务。结果便是新特征的上线涉及频繁的跨部门沟通,迭代效率低;
  • 特征管道只完成了轻量的特征工程,降低在线推理的效率。由于特征管道由大数据工程师而非算法工程师编写,复杂的数据预处理涉及更高的沟通成本,因此这些特征的预处理程度都比较轻量,更多的预处理被留到模型服务甚至模型内部进行,增大了模型推理的时延。

为了解决这几个问题,特征系统 V2 提出几个设计目的:

  • 将控制权交还算法工程师,提高迭代效率;
  • 将更高权重的特征工程交给特征管道,提高在线推理的效率。

三、新版特征系统 V2

特征系统 V2 相比特征系统 V1 在架构上的唯一不同点在于,它将特征管道切分为三部分:特征生成管道,特征源,和特征注入管道。值得一提的是,管道在实现上均从 Spark 转为 Flink,和公司数据基础架构的发展保持一致。特征系统 V2 的整体架构如下图所示:

v2 architecture

1. 特征生成管道

特征生成管道读取原始数据源,加工为特征,并将特征写入指定特征源 (而非特征仓库)。

  • 如果管道以流数据源作为原始数据源,则它是流特征生成管道;
  • 如果管道以批数据源作为原始数据源,则它是批特征生成管道。

特征生成管道的逻辑由算法工程师全权负责编写。其中,批特征生成管道使用 HiveQL 编写,由 DolphinScheduler 调度。流特征生成管道使用 PyFlink 实现,详情见下图:

v2 codegen

算法工程师需要遵守下面步骤:

  1. 用 Flink SQL 声明 Flink 任务源 (source.sql) 和定义特征工程逻辑 (transform.sql);
  2. (可选) 用 Python 实现特征工程逻辑中可能包含的 UDF 实现 (udf_def.py);
  3. 使用自研的代码生成工具,生成可执行的 PyFlink 任务脚本 (run.py);
  4. 本地使用由平台准备好的 Docker 环境调试 PyFlink 脚本,确保能在本地正常运行;
  5. 把代码提交到一个统一管理特征管道的代码仓库,由 AI 平台团队进行代码审核。审核通过的脚本会被部署到伴鱼实时计算平台,完成特征生成管道的上线。

这一套流程确保了:

  • 算法工程师掌握上线特征的自主权;
  • 平台工程师把控特征生成管道的代码质量,并在必要时可以对它们实现重构,而无需算法工程师的介入。

2. 特征源

特征源存储从原始数据源加工形成的特征。值得强调的是,它同时还是连接算法工程师和 AI 平台工程师的桥梁。算法工程师只负责实现特征工程的逻辑,将原始数据加工为特征,写入特征源,剩下的事情就交给 AI 平台。平台工程师实现特征注入管道,将特征写入特征仓库,以特征服务的形式对外提供数据访问服务。

3. 特征注入管道

特征注入管道将特征从特征源读出,写入特征仓库。由于 Flink 社区缺少对 Redis sink 的原生支持,我们通过拓展 RichSinkFunction简单地实现了 StreamRedisSink 和 BatchRedisSink,很好地满足我们的需求。

其中,BatchRedisSink 通过 Flink Operator State 和 Redis Pipelining的简单结合,大量参考 Flink 文档中的 BufferingSink,实现了批量写入,大幅减少对 Redis Server 的请求量,增大吞吐,写入效率相比逐条插入提升了 7 倍 。BatchRedisSink 的简要实现如下。其中,flush 实现了批量写入 Redis 的核心逻辑,checkpointedState / bufferedElements / snapshotState / initializeState 实现了使用 Flink 有状态算子管理元素缓存的逻辑。

class BatchRedisSink(pipelineBatchSize: Int
) extends RichSinkFunction[(String, Timestamp, Map[String, String])]with CheckpointedFunction {@transientprivate var checkpointedState: ListState[(String, java.util.Map[String, String])] = _private val bufferedElements: ListBuffer[(String, java.util.Map[String, String])] =ListBuffer.empty[(String, java.util.Map[String, String])]private var jedisPool: JedisPool = _override def invoke(value: (String, Timestamp, Map[String, String]),context: SinkFunction.Context): Unit = {import scala.collection.JavaConverters._val (key, _, featureKVs) = valuebufferedElements += (key -> featureKVs.asJava)if (bufferedElements.size == pipelineBatchSize) {flush()}}private def flush(): Unit = {var jedis: Jedis = nulltry {jedis = jedisPool.getResourceval pipeline = jedis.pipelined()for ((key, hash) <- bufferedElements) {pipeline.hmset(key, hash)}pipeline.sync()} catch { ... } finally { ... }bufferedElements.clear()}override def snapshotState(context: FunctionSnapshotContext): Unit = {checkpointedState.clear()for (element <- bufferedElements) {checkpointedState.add(element)}}override def initializeState(context: FunctionInitializationContext): Unit = {val descriptor =new ListStateDescriptor[(String, java.util.Map[String, String])]("buffered-elements",TypeInformation.of(new TypeHint[(String, java.util.Map[String, String])]() {}))checkpointedState = context.getOperatorStateStore.getListState(descriptor)import scala.collection.JavaConverters._if (context.isRestored) {for (element <- checkpointedState.get().asScala) {bufferedElements += element}}}override def open(parameters: Configuration): Unit = {try {jedisPool = new JedisPool(...)} catch { ... }}override def close(): Unit = {flush()if (jedisPool != null) {jedisPool.close()}}
}

特征系统 V2 很好地满足了我们提出的设计目的。

  • 由于特征生成管道的编写只需用到 SQL 和 Python 这两种算法工程师十分熟悉的工具,因此他们全权负责特征生成管道的编写和上线,无需依赖大数据团队,大幅提高了迭代效率。在熟悉后,算法工程师通常只需花费半个小时以内,就可以完成流特征的编写、调试和上线。而这个过程原本需要花费数天,取决于大数据团队的排期;
  • 出于同样的原因,算法工程师可以在有需要的前提下,完成更重度的特征工程,从而减少模型服务和模型的负担,提高模型在线推理效率。

四、总结

特征系统 V1 解决了特征上线的问题,而特征系统 V2 在此基础上,解决了特征上线难的问题。在特征系统的演进过程中,我们总结出作为平台研发的几点经验:

  • 平台应该提供用户想用的工具。这与 Uber ML 平台团队在内部推广的经验相符。算法工程师在 Python 和 SQL 环境下工作效率最高,而不熟悉 Java 和 Scala。那么,想让算法工程师自主编写特征管道,平台应该支持算法工程师使用 Python 和 SQL 编写特征管道,而不是让算法工程师去学 Java 和 Scala,或是把工作转手给大数据团队去做;
  • 平台应该提供易用的本地调试工具。我们提供的 Docker 环境封装了 Kafka 和 Flink,让用户可以在本地快速调试 PyFlink 脚本,而无需等待管道部署到测试环境后再调试;
  • 平台应该在鼓励用户自主使用的同时,通过自动化检查或代码审核等方式牢牢把控质量。

原文链接
本文为阿里云原创内容,未经允许不得转载。 

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

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

相关文章

小型微型计算机系统退回修改,小型微型计算机系统

基本信息期刊名称小型微型计算机系统《中国计算机系统杂志》的英文名称出版周期每月发布了ISSN 1000-1220发布CN 21-1106 / TP邮政编码8-108组织者中国科学院沉阳计算技术研究所出版地: 辽宁省沉阳市期刊首页网址提交URL包含在中/荣誉CSCD核心期刊中国科学引文Pж(AJ)摘要杂志C…

Flink 1.14 新特性预览

简介&#xff1a; 一文了解 Flink 1.14 版本新特性及最新进展 本文由社区志愿者陈政羽整理&#xff0c;内容源自阿里巴巴技术专家宋辛童 (五藏) 在 8 月 7 日线上 Flink Meetup 分享的《Flink 1.14 新特性预览》。主要内容为&#xff1a; 简介流批一体Checkpoint 机制性能与效率…

2021 年云原生技术发展现状及未来趋势

简介&#xff1a; 作者于雨担任了 2021 年 GIAC 会议云原生专场的出品人兼讲师&#xff0c;组织了前后四个场子的演讲&#xff0c;在这个过程中作者同时作为听众从这些同行的演讲中学到了很多非常有用的知识。本文算是对 2021 GIAC 云原生专场的侧记&#xff0c;管中窥豹&#…

像搭“乐高”一样实现整合式网络安全体系

部署多种防护产品&#xff0c;却无法形成防御合力&#xff0c;是当前很多企业网络安全建设都面临的挑战。网络安全能力整合是企业的刚需&#xff0c;也是行业发展的大势所趋。虽然Gartner 提出的网络安全网格架构&#xff08;CSMA&#xff0c;Cybersecurity Mesh Architecture …

合规安全大考核:移动应用安全策略全盘点

简介&#xff1a; 移动应用涵盖用户大量个人数据&#xff0c;一旦发生泄漏可能对个人、社会造成重大影响&#xff0c;同时对移动应用产业长远的发展来说也是毁灭性打击。移动应用开发者&#xff0c;也应注意开发过程中的规范性、安全性&#xff0c;敬畏安全问题&#xff0c;防范…

禁用计算机f1-f12,win10禁用F1至F12热键转为功能键的技巧

win10禁用F1至F12热键转为功能键的技巧介绍。有网友询问&#xff1a;Win10系统笔记本电脑上的F1-F12键上都变成了开关系统功能开关的快捷键&#xff0c;而失去了F1-F12键本身的快捷键的功能。因为编写程序运行的许多软件都需要使用Fn快捷功能键运行&#xff0c;还有制作Word文档…

Quick BI电子表格: 新手亦可表格自由

简介&#xff1a; 随着企业业务快速增长&#xff0c;单纯的表或交叉表展现的数据模式相对固定&#xff0c;已不能满足企业中不同角色用户、不同业务场景数据可视化分析展现的诉求。在满足业务人员可视化需求层面&#xff0c;Quick BI不仅提供了丰富的图表组件&#xff0c;也提供…

CSDN 十大技术主题盘点-云原生篇

关于2021&#xff0c;我们能看到的技术变化有很多。当云原生向下而生&#xff0c;当分布式数据库席卷而至&#xff0c;当低代码平台扩展了开发的边界&#xff0c;当万物互联蔚然成风……我们看到了太多在2021年形成的变化&#xff0c;但也能看到这些趋势非但没有结束&#xff0…

基于MaxCompute+PAI的用户增长方案实践

简介&#xff1a; 如何通过PAIMaxCompute完成用户增长模型AARRR全链路&#xff0c;包含拉新、促活、留存、创收、分享。 本文作者 李博 阿里云智能 高级产品专家 在过去一年阿里云PAI机器学习团队做了很多偏业务的实践&#xff0c;其中有一条就是基于 MaxComputePAI的产品方案…

Atmosic发布搭载能量收集技术的超低功耗蓝牙5.3 片上系统(SoC)高级产品系列

物联网&#xff08;IoT&#xff09;能量收集无线技术的全球领导者Atmosic今日宣布推出ATM33系列蓝牙5.3高性能片上系统&#xff08;SoC&#xff09;产品&#xff0c;该产品系列将Atmosic已获专利的先进能量收集及超低功耗技术推进到更高的水平。 为减少各种物联网产品高昂的电池…

基于 MaxCompute 的实时数据处理实践

简介&#xff1a; MaxCompute 通过流式数据高性能写入和秒级别查询能力(查询加速)&#xff0c;提供EB级云原生数仓近实时分析能力&#xff1b;高效的实现对变化中的数据进行快速分析及决策辅助。当前Demo基于近实时交互式BI分析/决策辅助场景&#xff0c;实现指标卡近实时BI分析…

如何使用计算机来线性拟合,Excel2019使用教程:绘制线性回归图

Excel的功能很强大&#xff0c;可以做各种数据处理和分析。想要检测两组数据是否具有线性关系&#xff0c;就可以使用excel2019来做一元线性回归分析图表&#xff0c;进行数据分析&#xff0c;从而根据结果来测试两组数据的关系。在excel2019中制作一元线性回归分析图表的方法很…

技术干货| 阿里云基于Hudi构建Lakehouse实践探索「内附干货PPT下载渠道」

简介&#xff1a; 阿里云高级技术专家王烨(萌豆)在Apache Hudi 与 Apache Pulsar 联合 Meetup 杭州站上的演讲整理稿件&#xff0c;本议题介绍了阿里云如何使用 Hudi 和 OSS 对象存储构建 Lakehouse&#xff0c;为大家分享了什么是 Lakehouse&#xff0c;阿里云数据库 OLAP 团队…

将 k8s 制作成 3D 射击游戏,好玩到停不下来 | 文末福利

作者 | 小碗汤来源 | 我的小碗汤今天演示一个项目&#xff0c;利用Unity做场景、用C#做交互逻辑&#xff0c;将k8s制作成一个3D射击游戏。正好最近在学习Unity&#xff0c;所以利用这个项目开始上手挺合适的。源码、可执行文件可以自行下载&#xff0c;也可在文末获取&#xff…

Alibaba FFI -- 跨语言编程的探索

简介&#xff1a; 跨语言编程时现代程序语言中非常重要的一个方向&#xff0c;也被广泛应用于复杂的设计与实现中。 跨语言编程是现代程序语言中非常重要的一个方向&#xff0c;也被广泛应用于复杂系统的设计与实现中。本文是 GIAC 2021(全球互联网架构大会) 中关于 Alibaba …

世界通信简史

作者 | 小枣君来源 | 鲜枣课堂█ 萌芽期&#xff1a;现代通信的诞生公元前600年左右&#xff0c;古希腊哲学家泰勒斯闲着没事&#xff0c;拿家里的琥珀棒蹭一只小猫。 蹭着蹭着&#xff0c;他发现&#xff0c;琥珀棒把小猫的毛都吸起来了。 现在我们都知道&#xff0c;这是因为…

如何避免出现SQL注入漏洞

简介&#xff1a; 本文将针对开发过程中依旧经常出现的SQL编码缺陷&#xff0c;讲解其背后原理及形成原因。并以几个常见漏洞存在形式&#xff0c;提醒技术同学注意相关问题。最后会根据原理&#xff0c;提供解决或缓解方案。 作者 | 阿里云安全团队 来源 | 阿里技术公众号 ‍‍…

「CSDN 2021年度 IT 技术影响力之星评选」活动报名倒计时!

“CSDN 2021年度IT技术影响力之星评选”活动自2021年12月6日启动以来受到了行业各界的关注以及企业和个人的积极响应&#xff0c;截止目前&#xff0c;已收到上千份参评报名。本次评选活动的第一阶段——企业/个人参与提名将于2022年1月30日结束&#xff0c;以真实数据为基础&a…

技术人员的一点产品思维思考

简介&#xff1a; 作为一线的开发人员&#xff0c;大家是不是都经历过和产品吵得不可开焦&#xff0c;甚至最后谁也无法说服谁&#xff0c;最后只能由老板出面解决的经历。而大多数情况老板还真能以某种方法去解决&#xff0c;并且是一个双方都能接受的方案。然而这不全是因为老…

chrome插件上传csv_Chrome插件推荐

从 IE 到 Chrome &#xff0c;期间使用了很多浏览器&#xff0c;搜狗、360、2345、傲游等等&#xff0c;最后选择了 Chrome &#xff0c;一直到现在&#xff0c;在使用的过程中发现一些好用的插件&#xff08;扩展程序&#xff09;&#xff0c;在此推荐给大家。PS&#xff1a;使…