开源机器学习数据库 OpenMLDB:线上线下一致的生产级特征平台
本文整理自 OpenMLDB PMC 卢冕 在 OpenMLDB Meetup No.6 中的分享——《开源机器学习数据库 OpenMLDB:线上线下一致的生产级特征平台》。
非常感谢大家来参加此次 OpenMLDB 第六次 Meetup。我叫卢冕,是 OpenMLDB 的研发负责人,也是第四范式的系统架构师。
今天由我来给大家整体介绍 OpenMLDB 的定位和特性,回顾最近一个月来 release 的内容和 OpenMLDB 研发进展。
我的分享主要分为三部分。
- 第一部分介绍当前人工智能工程化落地所面临的数据和特征挑战
- 第二部分讲解我们目前如何通过 OpenMLDB 这个线上线下一致的生产级特征平台来解决这些挑战
- 第三部分带领大家回顾 OpenMLDB 的发展历程,以及 OpenMLDB 下一版本的 Roadmap。
Tips:目前我们正在规划 OpenMLDB v0.7.0,已有一个初步的 roadmap(还在调整修改中)。如果大家对 OpenMLDB 有期待和需求或是对于参与开发某一个 feature 非常感兴趣,我们欢迎大家和我们进行详细地交流,也会把来自开源社区的需求放在讨论排期比较高优的位置。
交流通道:https://github.com/4paradigm/OpenMLDB/issues/2547
人工智能工程化落地所面临的数据和特征挑战
数据挑战
在如今人工智能落地的过程当中,其实我们把大部分时间都花费在数据治理上。
今天市面上已经有非常多的数据治理工具,如 MySQL、HDFS 等。但从 AI 落地的角度考虑,这些工具未能完全解决我们 AI 落地中的一些工程化问题。接下来就来具体介绍 AI 工程化落地面临的挑战,以及 OpenMLDB 的解决思路。
毫秒级实时特征计算需求广阔
在此之前,先说明一个非常重要的背景知识:OpenMLDB 所面向的应用场景是机器学习的决策类场景,而且是时效性要求非常强的决策场景,因此它需要具备毫秒级的数据和特征处理能力。
可能大家都知道我们的目前接触到的 AI 应用可以分为两类。
- 一类是感知类,例如 CV、人脸识别、NLP,它们都是属于感知类的应用。
- 另一类是 OpenMLDB 所关注的决策类的 AI 应用,主要面向于商业场景,像是防控、风控、反欺诈、个性化推荐等等。决策类的 AI 应用一般针对结构化的数据。
那为什么我们需要实时的机器学习去做决策呢?
其实,所谓实时机器学习决策,可以从两个维度上去理解。
- 一个维度是我们需要实时的数据。当我们需要对当前行为的发生做出判断,必须通过十秒甚至更短时的实时数据才能获得更准确的判断。
- 另一个维度是我们需要实时的计算,只有在非常短的时间内把计算结果反映出来,才能做到业务要求下的快速响应。
针对此类需要实时数据和实时计算的场景,我们现实生活中已经有了非常丰富的需求场景。AI 无人车、量化交易、银行的风控和事中反欺诈等都需要基于实时数据的快速实时计算。
在今天的市面上,我们也能看到很多机器学习的通用大数据处理框架,如 Spark、Flink,甚至是 Python,但是这些框架都不能达到毫秒级的实时计算响应速度。以 OpenMLDB 企业客户为例,在他们的银行反欺诈场景中,需要系统的响应时间控制在 20毫秒以内。若响应时间过长,反欺诈机制可能失效,导致大量损失。所以市场还是非常需要有一款具备毫秒级实时数据和特征处理能力的工具,为机器学习场景决策提供更强有力的支持。
OpenMLDB 最具优势的应用场景正是实时的机器学习决策。
机器学习应用开发上线全流程
接下来让我们进入到另一个重要的背景知识——机器学习应用从离线开发到上线全流程是怎样的。
整个需求会分为离线和线上两个部分。
在离线开发环节,数据科学家会不断探索开发特征脚本和模型,使它们能够达到最终的精度要求。
在线上服务环节,要将服务上线,真正做到线上的实时预测以及实时特征计算。OpenMLDB 关注的是其中的特征部分,而不涉及后续的模型。
在这里,我们可以通过下面的事中反欺诈交易的案例帮助大家了解实时特征计算场景。
假设图中有一位用户做了刷卡的行为动作。我们可以得到刷卡金额、刷卡时间、卡号这些消费记录,也是最原始的数据。我们的反欺诈系统会通过一张历史交易表,查询到做了消费行为的卡号,进而得到一系列的历史数据。
因为我们是做事中反欺诈的,所以当前的数据也能为判断提供依据,它也会虚拟地暴露到表格当中和交易记录等历史数据共同形成所有的原始交易信息,提供给特征抽取。
在右侧图表中还可以观察到一个非常重要的特征,就是信息的时间戳。所有原始信息都是基于时序排列的。这里经常需要做的特征计算模式,就是基于窗口的聚合模式。
在例子里,我们可以划定两个窗口,一个是十秒的窗口,即从当前交易的时间点向前十秒的时间点划一个时间窗口;另一个是三小时的窗口。基于这两个时间窗口,我们可以做一些特征抽取,比方说过去十秒或三小时的刷卡次数、最大刷卡金额、最小刷卡金额以及平均每次刷卡金额。那么通过计算我们得到了一些有效的特征信息,这些特征信息会提供给后面的模型推理环节使用。
这个就是 OpenMLDB 面向的实时特征计算场景中的典型案利。通过这个案例,我们可以看到两个非常值得关注的工程化需求。
- 第一点,线上线下的一致性。简单来说就是线上服务的效果需与数据科学家离线开发的效果一致。
- 第二点,低延迟、高并发、高可用的工程化需求。
接下来我会展开讲解这两点需求。
特征计算开发上线全生命周期
上图可以展示出特征计算开发,从开发到上线的生命周期。
首先会由数据科学家进入项目体系,他会根据经验使用 Python、SparkSQL 做离线特征计算。当离线特征计算的输出结果可以满足业务需求时,数据科学家生产满足业务精度的特征脚本和模型的任务就完成了。
但因为离线的特征脚本和模型不能满足低延迟、高并发、高可用的线上工程化需求。此时会有工程化团队介入。他们会使用一些高性能、高可用的工具,像 Database、C++ 把离线特征计算脚本转换成成实时特征计算的程序应用,满足生产需求后真正做上线服务。
那这个流程当中呢,其实我们有看到两组开发人员以及两套工具链。最重要的是中间还有一个环节,叫做计算逻辑一致性校验。这个环节需要保证的数据科学家和工程化团队开发脚本的计算逻辑、数据定义是一模一样的。
听上去这是一个直接且简单的需求,但在真正的工程化落地实践中,一致性校验往往要投入大量的时间精力。我们不仅需要这个工程化团队完成性能优化,还要不断地沟通对齐、去两边对齐、迭代测试,保证计算逻辑的一致性。根据我们以往的业务经验,这个环节很可能会成为整个项目周期的瓶颈,耗费几个月甚至一年以上的时间,计算其投入成本,是非常高昂的。
线上线下不一致原因
而线上线下不一致的原因也是多样的,它可能受到工具能力不一致的影响,也可能是需求沟通认知差导致的。美国一家线上银行的工程师就曾写博客述说过这种需求认知的差异,他在文章里提到自己对账户余额的定义与其他同事默认的账户余额定义以及处理方式不一致,导致了线上线下的不一致。
特征平台工程化解决方案
为了解决该痛点,头部企业会花费上千小时自研构建数据与特征平台,来解决诸如线上线下一致性、数据穿越、特征回填、高并发低延迟等工程挑战;其他中小企业则需要采购高昂的 SaaS 工具和数据治理服务。OpenMLDB 选择为大家提供开源的、低成本、高效率、企业级的解决方案。
OpenMLDB:线上线下一致的生产级特征平台
OpenMLDB 诞生背景
OpenMLDB 是去年6月开源的,但是其中的技术累积已经超过了四五年的时间。在第四范式的商业产品中,OpenMLDB 的前身是嵌入在 MLOps 产品中的特征平台,过去我们叫它 RTIDB 或 FEDB,已经跟随第四范式的商业化产品在100多个场景得到应用落地。
OpenMLDB 如何解决之前提到的两个问题呢?让我们往下看。
在 OpenMLDB 架构中有两套处理引擎。
-
一套用于离线开发,处理离线数据。它是我们基于 Spark 做了源代码级别优化后的产物,专门提供给数据科学家做离线探索,面向批处理模式。
-
另一套面向工程化,是针对生产级线上服务研发的实时 SQL 引擎,是由我们研发团队完全从零到一、自主搭建的。它是针对时序数据,也针对特征工程优化的一个分布式时序数据库。
除了两套引擎外,架构中还有一个非常重要的一致性执行计划生成器。它保证了线上线下两套引擎生产的执行计划在计算逻辑上完全一致。
配套这样一套架构,OpenMLDB 对外暴露的唯一编程语言是 SQL。用户只需要把 SQL 写好就能通过一致性执行计划生成器去生成线上和线下的执行计划,同时天然保证这两套执行计划对数据定义、计算逻辑定义是完全一致的。
这个架构能帮助我们达到“开发即上线”的终极目标。
数据科学家完成离线特征开发后,只需一行 deploy 命令,就能直接把计算逻辑从离线批处理的引擎切换到线上实时引擎。再去把这个实时数据接入,就能完成离线开发到上线的流程。这样做不再需要工程化团队的介入,也不需要两个团队两套设备的对齐沟通,不再需要反复的一致性校验,所以能大大降低 AI 工程化落地的成本。
OpenMLDB 参与的开发上线全流程
具体流程如上图。
- step 1:在离线开发模式,数据科学家导入离线数据用于特征探索开发(注意:OpenMLDB 离线引擎支持硬拷贝和软拷贝。在软拷贝模式下只需要给出 HDFS 路径,不做实际的数据拷贝)
- step 2:使用 OpenMLDB 提供的基于 Spark 改进的离线引擎在 HDFS 文件上做离线特征抽取,在这个阶段内数据科学家还会和模型训练交互,不断对特征抽取脚本进行调优。
- step 3:调试特征脚本至满意状态就可以把 SQL 上线,同时这也意味着计算逻辑上线。
- step 4:此时,切换 OpenMLDB 到在线模式。准备冷启动需要的数据,比如特征抽取逻辑需要过去三个月的时间窗口数据,那我们需要把从上线时间点开始倒退三个月前的所有数据导入。
- step 5:准备实时数据接入,随着现实时间的推移,最近三个月的窗口数据是不断变动的,数据窗口在不断前移,所以需要把实时数据接入。这里可以通过 OpenMLDB 提供的 SDK 去写入,也可以通过我们这个提供的 connectors,像 Kafka Connector,Pulsar Connector,RocketMQ Connector 等把实时数据直接入。
- step 6:接下来就可以进入实时特征计算,用户发送实时请求,OpenMLDB 会基于最新的窗口数据,进行特征计算,并返回结果。
在线上引擎中,OpenMLDB 有一个真正数据存储引擎,同时我们支持 TTL(一个数据过期的概念)。如果我们需要三个月的数据,那么当数据库中的存储大于三个月会自动淘汰过期的数据。
基于计算逻辑加数据呢,我们的实时特征服务就已经准备好了。OpenMLDB 此时可以服务线上的实时请求,并把实时特征送出去提供给后面的模型推理。
OpenMLDB 核心问题与核心特性
总结上述内容,OpenMLDB 解决了线上线下特征计算不一致的核心问题,提供了毫秒级实时特征计算的核心特性。
OpenMLDB 应用场景和使用方式
因为我们发现在社区当中存在很多不同的使用方式,所以在这里为大家列举展示一下 OpenMLDB 的使用方式。
我们最推荐的使用方式当然是刚才演示的从离线开发到实时上线的完整流程?这样能保证线上线下一致性。不过取决于场景需求,社区里也有许多不同的使用方式,可以给大家提供参考。
比如某些用户已有离线特征脚本了,但之前使用的在线引擎达不到性能需求,所以只用了 OpenMLDB 的在线引擎。
同理,也存在一些用户不需要去做线上的实时预估只需要跑批,就可以单独使用 OpenMLDB 的离线部分。
今天我们看到在开源社区中这三种方式都有出现。
再为大家简单介绍一下产品特性吧。
OpenMLDB 产品特性一:线上线下一致性执行引擎
第一个是线上线下一致性执行引擎可以天然保证线上线下的一致性,这点我们不重复介绍了。
OpenMLDB 产品特性二:高性能在线特征计算引擎
第二个重要特性是我们这个高性能在线特征计算引擎。图中展示了我们实时引擎的主要模块,这里想传达的主要信息是 OpenMLDB 是一个分布式、高性能、可扩展、高可用的架构。在设计中我们用 Zookeeper 管理原数据,用 Nameserver 保证 Tablet 的管理和故障的转移。而 Tablets 是我们整个数据库存储和执行的最小单位,其中包含了储存引擎和执行引擎。
OpenMLDB 的存储引擎是默认使用基于内存的存储模式,以此保证线上服务的高性能。当然我们也有设置 Binlog 机制和备份机制,保护数据,帮助持久化。基于内存的存储模式带来高性能的同时也会带来比较高的成本,所以我们也为对性能要求不敏感的用户提供了成本更低的磁盘存储模式。
在实时特征计算引擎中,我们最核心的优化是双层跳表结构和预聚合技术。其中最显著的优化是 OpenMLDB 内部使用了双层跳表结构。双层跳表结构可以帮助我们快速地找到相应数据给,保证线上计算的高性能。另外一个核心优化技术是预聚合技术。简单来说是针对数据量巨大的窗口,我们会提前计算部分结果,便于在实时计算时降低延迟。
左侧条形图是 OpenMLDB 与两个内存型商业数据库的性能对比图,可以看到在时序特征持续抽取的 workload 下 OpenMLDB 还是有比较明显的优势。
左侧折线图是我们使用预聚合技术后的性能提升表现,当窗口的数据量级达到几百万时,预聚合技术可以使延迟从秒级降至十毫秒以内。
性能测试报告:https://openmldb.feishu.cn/wiki/wikcnZRB9VRkqgD1vDFu1F9AaTh
OpenMLDB 产品特性三:面向特征计算的优化的离线计算引擎
第三个特性和离线引擎有关。首先,我们在 Spark 的基础上做了语法的扩展。其次,OpenMLDB 把一些执行计划也做了优化修改。然后最终我们达成的这个目的也是为了让这个Spark能够更方便的去做特征计算,而且能达到一个更高的一个效率。
OpenMLDB 产品特性四:针对特征工程的SQL扩展
第四个特性是 OpenMLDB 针对特征工程做了 SQL 的扩展——Last Join 和 Window Union。
Last Join语法能够在左表匹配到右表多条记录时只取其中一条,一般是会取最新的一条。这种情况通常是右表为某物体不断更新的信息状态,我们只需要最新的状态过来做拼表,做最后的特征计算,这种场景其实在机器学习中非常常见。
如果 Last Join 是一个简单的拼表,那 Window Union 其实就是一个相对复杂的拼表。Window Union 的设计针对另一种机器学习常见场景。在我们的现实应用中数据一般会出现在多表里面。Window Union 不是简单的取一条数据过来拼表,而是通过左表信息找到右表的对应记录然后再用。如果我们使用标准的 SQL 去实现上述要求也能够写出来,但会写的相当复杂,执行效率也对应下降。
OpenMLDB 产品特性五:企业级特性支持
第五个特性是 OpenMLDB 提供企业级的特性支持,包括高可用、扩缩容、平滑升级、企业级监控以及双机房保障。现在我们也在开发多租户还有云原生等企业级特性。
OpenMLDB 产品特性六:以SQL为核心的开发管理体验
最后的特性让我们用一个 OpenMLDB CLI 界面展示。如果使用过 MySQL,你肯定会对 CLI 有印象。OpenMLDB 作为一个数据库产品,也提供了一个类似的 CLI,用户可以在这里非常方便地完成整套流程,实现离线开发。
OpenMLDB 上下游生态
作为一个开源软件,开源生态建设也必不可少。OpenMLDB 也在上下游生态方面做了不少努力。
- 上游的数据生态部分,因为在生产环境的使用情况,我们更专注在线数据的生态合作。对接 Kafka、Pulsar、RocketMQ,我们都有开发相应的 Connector。在离线部分,OpenMLDB 目前主要读取 HDFS 上的数据,我们也在计划对接 Hive、Cassandra,争取能做到把这两个工具中的离线数据直接导入。
- 下游的模型部分,OpenMLDB 还是 松耦合 的实现方式。因为我们输出的格式比较标准,下游模型可以直接读取使用。
- 在生产这一模块,OpenMLDB 也和 Airflow、DolphinScheduler、Bzyer 做了紧耦合,能够直接在上述工具中调用 OpenMLDB 的算子。
- 在监控这一模块,OpenMLDB 也和 Prometheus 做了对接。
OpenMLDB 应用案例
在特征介绍后,让我们用一个客户案例帮大家更具体地了解 OpenMLDB 的应用。
Akulaku 是 OpenMLDB 第一个深度使用企业用户,是一家出海东南亚的线上金融公司。在 Akulaku 的应用中 OpenMLDB 的使用场景也大部分是和金融有关。
在图上的架构中,线上部分的设计中 OpenMLDB 被放置在模型计算层,在离线部分 OpenMLDB 位于特征计算层,通过这样的架构保障了线上线下特征计算的一致性并且完成了线上服务。
Akulaku 的应用场景和需解决的痛点与 OpenMLDB 非常匹配。Akulaku 的线上部署需要达到低延迟并发并且高时效性的要求,需要尽可能新鲜数据来反映实时的变更。线下分析也需要满足高吞吐的需求,同时要保证线上线下的逻辑完全一致。
使用 OpenMLDB 后,在一天内需要处理大概 10亿 条订单数据的 Akulaku,能够将窗口计算延迟大大降低,达到 4毫秒 的级别。
History & Roadmap
OpenMLDB 发展历程
接下来的时间我们会简单介绍 OpenMLDB 目前的发展状态和未来的规划。
开源至今,OpenMLDB 已经经历了一年多时间的迭代,从 0.1.0 升级到了 0.6.0,第七个版本预计会在今年11月或者12月和大家见面。
在成长的过程中,我们收到了非常多来自社区小伙伴的反馈,也吸引了一批用户的使用。Akulaku、京东科技、华为、37手游的同学都有深入参与到 OpenMLDB 的成长中,非常感谢合作伙伴带给我们社区的建议及反馈。
OpenMLDB 近期优化
过去一个月中,OpenMLDB 主要发布了一个大版本、两个小版本。其实我们做了两件非常重要的事情。
第一是是我们引入了一个数据库状态智能诊断工具以及一个自动化的 log 收集工具。在社区的讨论交流中我们发现 OpenMLDB 的状态诊断以及 log 解析存在不足,经常会耗费大量人力去排查集群状态。所以我们在 0.6.0 版本里引入了智能诊断工具。希望在存在问题是能为社区用户提供初始信息、调整建议,甚至是直接解决。
第二是完成了 OpenMLDB 和 Airflow 的整合。大家可以在非常流行的编排工具 Airflow 中直接调用我们的 OpenMLDB 算子。
另外,我们也做了 SQL 的语法增强。提供了更多事后决策的功能,支持 EXCLUDE CURRENT_ROW。
在 0.6.1 版本中,我们主要是做了一些修复,进一步提升了离线引擎的性能和稳定性,增加了 Oneflow 的整合案例。
在上周发布的 0.6.2 版本中,OpenMLDB 能够支持离线引擎的独立运行,对这个日志输入格式做了优化,减少一些意义不大的无效信息出现。
OpenMLDB v0.7 Roadmap
现状我们已经在规划 0.7.0 版本的过程中了,目前大致拟定了三个方向。
第一,增强 OpenMLDB 的 SQL 能力,特别是增强预聚合能力。因为我们看到部分用户的特征抽取语法逻辑非常复杂,所以虽然我们提供了 UDF 支持,但是接下来依然会在 SQL 的原生能力上去做增强。
第二个重要方向是,我们会 提升 OpenMLDB 的稳定性。比如我们可能会通过一些手段完成内存资源的隔离。以前造成 OpenMLDB 不稳定的最大的问题是内存消耗过度,而用户没有感知。一旦过度消耗,就可能会被 OS 给杀掉。所以在下一个版本中,我们会计划引入内存资源隔离的手段来避免服务的完全中断。
第三,在 易用性上做更多优化。之前会有社区用户抱怨运维命令过于复杂。针对这些声音,我们会对运维命令做一些简化优化。OpenMLDB 0.7.0 版本也会尝试在阿里云市场提供一个开箱即用的服务。欢迎大家持续关注。
OpenMLDB 欢迎你的加入
今天的介绍到这里就结束了。最后也非常欢迎大家加入 OpenMLDB 社区,可以扫描二维码入群了解更多相关内容或和我们做深入交流。
相关链接
OpenMLDB github 主页: https://github.com/4paradigm/OpenMLDB
OpenMLDB 微信交流群