大家好,很高兴和大家一起参加第四范式技术日,分享OpenMLDB在Akulaku数据驱动中的应用实践。我是阿库拉库的马宇翔。对于OpenMLDB,我们是早期的追随者,也是对它提供的解决方案有浓厚兴趣的企业党,所以今天非常希望把我们的经验分享给大家展开讨论。场景需求及架构设计Akulaku的数据架构如图所示。在特征计算层,有一些第三方和自研的底层工具;在模型计算层,做了一些开放架构的集成,形成了一个易于扩展,不依赖于特定工具的计算模型。框架。这两层负责支持智能应用,比如行为动作、地理位置、设备指纹等,还有银行的一些反洗钱和设备风控,还有基于用户的智能客服和智能投顾。经验。这些智能应用都是基于相同的数据驱动基础技术栈来提供服务,而我们在设计满足上述条件的解决方案时发现了OpenMLDB。场景需求作为Akulaku的数据部门,我们通常会面临来自上下游的需求。下游业务方会要求我们尽可能支持各种功能,要求实时使用。我们常见的数据应用端会需要同时使用离线计算、异步实时计算和硬实时计算来满足决策需求。这些关键事件的决策不能出错,同时还要保证决策的稳定性。针对上游需求。比如运维部门作为资源提供者,有成本需求,希望整个计算系统的资源越少越好。这里少,多就是少,在满足业务的前提下,也就是要做到全局最优。要求我们做细化,但是细化会带来复杂度的增加,进而会降低稳定性。上下游的需求是相互排斥的,这对我们来说是一个挑战。对于内部数据部门来说,由于大数据工具的频繁迭代,员工的学习成本非常高。比如Spark对批计算友好,Flink对流计算友好。但是,为每个计算模型单独学习一个工具,并在工具的基础上迭代学习,也可能需要适应改造,对现有系统进行实质性的改造,这将使得每个员工都很难从整个系统中获得沉淀。部门,这是非常痛苦的。.在易用性上,我们的用户希望整个平台的设施足够简单,方便普及。它必须随处可用,并以相对简单的方式使用。否则,开发人员、分析师、算法工程师等各类服务角色的诉求各不相同,难以一一满足。第二重要的是可靠性。如果系统部署困难,三天死机两次,问题无法自检,测试时间过长,对我们的影响很大。因此,我们必须一一避免或减少上述问题。架构设计设计需求在以上场景下,Akulaku的架构设计必须满足以下两个目标。首先,我们需要做一些同时适用于OLAP和OLTP的高效融合计算方案。需要同时实现AI和BI的数据执行。需要保证AI和BI尽可能使用相同的数据在整条生产线上运行。而不是分别运行两个中间结果,然后得出不同的结论,这样风险很大。其次,使用的工具需要与其他工具兼容,生态良好。如果没有良好的生态,我们就很难将它放在整个结构中。经过大量的二次开发和以上两个目标的筛选,我们明确了Akulaku数据架构中的工具需要支持五个条件:第一,流批一体化。它的批处理和实时处理应该是同一个代码执行的,执行的底层也应该是同一个逻辑。第二,高性能。因为线上的大并发和线下的高吞吐任务需要一个支撑。第三,场景无关。对于场景无关的特征,我们需要它有一个数据可以随处使用,然后通过一些筛选,或者加窗来改变它的条件。而不是说每换一个场景,我们就得重新做一次全量计算,或者导入导出全量数据。第四,语义支持。语义支持更多是因为我们的流计算有很多新的语义,也就是Flink的每一个版本迭代都会根据大家提出的具体使用需求迭代一些新的语义。所以对于这些语义,我们希望我们的工具也能得到一些支持,它可以做一些更复杂的实时计算场景。第五,工具高效。首先我们要搭建计算框架的组件,它本身可以沉淀我们一些在线的pipeline和数据逻辑,供离线分析。方便我们后面对它做一些迭代。设计和实现最终形状的特征和数据计算架构如上图所示。首先,我们的数据源可能来自HDFS、Kafka、其他服务语言的SDK,或者Nebula这种专门的图计算工具。基于这些不同的数据源,我们在中间做了流批整合。最后我们主要是选择OpenMLDB的不同模式来实现这组功能,然后使用中间件来屏蔽流批一体化的不同组件。对于一个逻辑不同的实现保证了后面的融合计算组件可以很好的降低复杂度。在Akulaku中,近50%使用最多的指标实时性要求不高,比如运营商或管理者需要的数据指标,或者一些实时性要求不高的特殊模型,可能使用性能或者性价比比较高的和可以使用更通用的Rocksdb模型。接下来,如果批处理对生产要求、精度、性能、计算速度要求高,我们会使用其背后基于SparkFE的OpenMLDB离线模式,其性能比Spark好很多倍。如果有一些硬实时的计算,会在OpenMLDB的在线模式下进行,大并发下可以保持几十毫秒的水平,基本达到200毫秒硬实时的门槛。其他的一些补充,比如Clickhouse或者数据湖组件,会在索引市场或者更多的数据市场提供一些支持,这里不再赘述。在融合计算方面,我们主要基于Ray来完成。Flink是我们之前的解决方案,但目前我们正在对Ray进行全面过渡。数据应用层,首先是因为OpenMLDB的离线和在线集成,所以我们可以很容易地自动化MLOPs的测试,从持续交付到持续部署,可以简化很多步骤,因为代码是一致的。借助OpenMLDB,我们可以轻松的做AutoML、其他指数市场和低代码分析,完成一些更精细化的BI应用。应用细节和用例为什么我们最终选择将OpenMLDB作为我们的核心?第一,天然支持流批合一。流批合一是OpenMLBD的一个核心,或者说是主要功能,也是我们最需要的功能。第二,高性能。在衡量OpenMLDB的性能时,如果从Kafka写入的数据能够达到最大10000并发,当然这是三节点集群,节点多的集群可能会有更好的结果,也就是说性能OpenMLDB的还有扩展的空间。离线部分,OpenMLDB的性能是Spark的数倍,基本可以满足一些常规使用。在实时计算部分,我们可以轻松做到接近200qps,也可以在70毫秒内保持99%的计算。所以可以说OpenMLDB是一个非常好的在线和离线计算工具,也是一个非常好的分析型数据库,可以同时满足在线和离线计算。第三,场景无关。这个特性可以持久化到内存中,我们可以选择使用持久化内存版本,保证在极端情况下我们的数据依然可以恢复。通过这种方案,我们可以把数据写一次,然后用SQL不断地控制算力,保证我们可以不断地复用数据。二是它还支持数据过期。数据过期功能是指可以自动删除一些我们设置过的,长时间不使用的数据,这样可以节省大量的空间,提高我们的存储效率。并且还支持Rocksdb的版本,进而达到降本增效的效果。第四,语义支持。它支持常见的流媒体场景需求,并且可以使用与批处理语法相同的运算符。同时也支持UDF或UDAF的一些特征工程功能扩展。这些扩展方法对我们来说还是很实用的,因为你可以把一些具体的逻辑包装成函数来使用。第五,工具高效。我们目前正在使用Airflow之类的一些工具来固化整个脚本,然后将这种固化搁置。OpenMLDB只需要配置一些类似SQL的脚本就可以完成。这种方法更便于实现MLOPs。同时OpenMLDB也在和很多第三方工具建立生态,保证我们可以更方便的对接其他工具。应用思维及建议应用思维下面的内容将介绍OpenMLDB的应用思维。第一个是关于标准SQL。我们必须要有符合标准SQL的工具吗?我们思考的结果是:其实并没有那么必要。因为标准的SQL语法更本质的目的是为了支持我们的逻辑一致性,但是我们还有其他的解决方案来实现逻辑一致性。比如调用一些不规范的方法或者还不支持的方法,我们必须调用一些自己实现的函数或者用软件工程的一些设计模式来解决这些分包,或者解决一些多层复用问题。这样,我们就可以换取比标准SQL工具更高的效率。这个效率其实是我们目前比较需要的。在我们自己的时代,一些复杂到几百行SQL打活挖矿的任务都可以通过这个方案来解决,它的扩展空间还是很大的。二是关于质量和性能的平衡。一般来说,我们希望同时提高质量和性能,但更多时候它们会产生一些冲突。例如,每当增加复杂性时,质量就会下降,但增加复杂性可以改善整个产品的性能。这些时候,我们会选择做一些错位对齐。例如OpenMLDB的三种实现模式,我们会选择使用特定的模式来实现那些尽可能合适的特性。比如Rocksdb这个版本,我们会做一个通用的指标计算工具。在线计算版,我们将其作为在线实时模型特征计算工具。在离线版本中,我们会用它来为一些非常大批量的数据做一些T+1的计算工具。也就是说,我其实可以把每一个方案和具体的数据或者场景尽可能的匹配到最优。我们还将这种方法应用到预计算、实时计算、软加载或窗口划分等一些方案中,以进一步优化其质量和性能之间的平衡。三是在业务和技术方面,我们也需要做一些取舍。就技术而言,我们希望我们的技术不会产生任何技术债,然后我们会不断向上迭代。对于业务来说,它需要的是你功能的完整实现和上线的时间。关于这一点,我们之前已经做了一些低代码的工具来完成这一点。如果是标准的低代码工具,那么可能会节省更多业务人员“拖拽”的时间,这并不是业务真正想要的。他们更想要的是缩短上网时间。在线时间的减少取决于你使用的工具是否可以直接从持续交付进展到持续部署。这就是OpenMLDB在这里发挥的作用。就是我这里“拖拽”完成的一套低代码工具背后生成的SQL,可以直接申请线上版进行部署。使用细节接下来,我只想介绍一些具体的使用细节。其实更多的是小技巧,可能对大家在使用这个工具的时候有所帮助。首先,在建表的过程中,我们可能会提供多种索引定义方式。主流的方法是在INDEX中使用Key关键字,另一种是在时间窗口中使用TS关键字,用于所有基于时间的流数据。要使用Key关键字,我们需要自己将事件序列化,然后定义一些可以帮助你很好拆分序列的字段作为关键字。如果定义的非常成功的话,将会给我们使用这个工具的效果带来很大的提升。第一是逻辑会简化,第二是性能会提升很多。OpenMLDB目前支持的时间字段是两种数据类型,这也是需要注意的。接下来在查询部分,我们在查询一条数据的时候,完全不需要传入一个非常大的业务SQL。可以说我们只使用我关心的字段和时间戳。对于其他不重要的,可以使用一些替代值,给它一个占位符。有了这个占位符,OpenMLDB就已经可以正常工作了。二是金融场景特别常见,当前行不是用来计算某个时间窗口内的数据。Akulaku使用的方案是我们排除当前字典中毫秒时间戳的第一个字段,然后通过这种方式解决排除当前行的操作。然后是里面的其他字段,因为是非时间戳,不是我们用到的字段,所以是不重要的无所谓的数据,可以随便做一些占位符。这些操作可以简化消除当前行问题的实现,不需要做一些很复杂的逻辑。建议与展望最后,向大家介绍一下我们最终使用的一些建议,以及对OpenMLDB产品未来迭代的展望。使用建议对于这个比较经典的使用建议,首先,如果我们的逻辑很复杂,会导致在线验证和离线验证。这两件事不是短时间内可以判断的。一致,或者最后的结果是否可以是一个数字。对于这种方法,我们推荐使用OpenMLDB来完成,因为它自然地消除了这个问题。其次,如果我们参与计算的数据能够按照时间或者某个指标进行完美的切片加窗,那么我们也推荐使用这个工具。因为它的性能会非常高,那么我们的性价比和效率都会提升到一个非常可观的水平。第三部分就是如果我们逻辑开发人员不是很关心大数据和高性能领域的一些问题,甚至包括SQL优化,其实也不太想去考虑。那么我们也推荐使用这个工具来开发这个逻辑。就我们而言,OpenMLDB本身的性能和底层优化都做得很好。对于特别影响性能的SQL语义的实现,比如多表连接,它并没有直接支持,所以不会让逻辑开发人员写一些性能很低的代码,可能会导致系统崩溃之类的。第二个是我们推荐很好地使用OpenMLDB。我们希望企业还是需要有比较清晰的数据治理能力。不然我第一步导入数据的时候OpenMLDB里面的数据可能比较乱。它更像是一种内部清理数据的工具。如果我们想利用好OpenMLDB的强项——计算,那么我们最好把需要用它计算的数据尽可能清楚的输入进去,然后直接执行后面相应的逻辑,而不是一直接收错误。迭代展望接下来是我们认为OpenMLDB未来会支持的一些功能,然后让我们的使用更加方便。首先,它目前似乎正在做一些事情来进一步支持异构资源并降低存储成本。在这个操作的后续推导中,我们认为会做一些更细化的使用配置。同一张表甚至可以支持某些字段的计算。比如某些需要用到内存版本的字段的计算,可以用Rocksdb来完成。这样就可以将资源的精细化管理做到比较极致。只要成本和产出的所谓ROI能够更高,OpenMLDB的应用场景其实会更广。其次,从其目前的数据IO和SDK支持来看,其背后可以支撑的工作还有很多。比如现在的离线数据导入,我们一般使用HDFS或者CSV。然后是一些比较新的数据或者线下的数据湖,或者一些线上的连接器,未来可以实现。二是关于SDK支持。我们目前使用的是JavaSDK和PythonSDK。与其他更成熟的数据工具相比,我们希望能有一个支持Python多线程的东西。或者对于Java来说,可能是它生成的文件形式可以更友好一些,也可以直接有一个很明显的switch功能,可以帮助我们更好的方便OpenMLDB的使用。第三,我们期待来自社区的更多文档贡献。比如OpenMLDB有很多宝藏功能,比如UDF函数的一些实现,或者如何实现底层数据在在线和离线两种不同模式下的一致性。设计能够给还没有入门或者刚入门的开发者一个更充分的介绍,那么我相信它的转化和使用也会增长的更快。第四,我们认为OpenMLDB可以有更友好的SRE支持设计,比如数据过期是一个很好的特性。但是如果是在生产环境中,出现一些问题就不好回头做进一步的迭代了。这个时候,如果我们能有一个选项做一个异步转储,或者后面增加一些定时删除,对SRE的排错或者后续的功能迭代会更加友好。当然也包括,比如对当前命令行日志的更细的分类,或者对整个数据库级别的一些管理权限的一些支持。这些是SRE可能关心的一些需求。关于整个OpenMLDB,这里是我们这边的一些建议和使用实践。同时,我也非常希望看到更多的公司来使用它,通过常见的“踩坑”和“填坑”,让OpenMLDB成为一个更好的工具。谢谢你们。
