AI时代,你需要了解的AI 数据库架构设计和内存优化思路

2023-05-31 0 248

原副标题:AI黄金时代,你须要如是说的AI 资料库体系结构和缓存强化路子

译者 | 陈迪豪

撰稿 | 邓艳琴

随著人工智慧控制技术的产业发展和普及化,愈来愈多的企业和组织机构须要处置和预测大批的统计数据,当中就主要包括了 AI 统计数据。AI 资料库为处置这些统计数据提供了更高效率,更智能化的形式,能更快地支撑力人工智慧应用应用领域的产业发展。因此,目前 AI 资料库已经正式成为人工智慧应用领域的炙手可热控制技术之一。OpenMLDB 则是这里头的著名开放源码工程建设项目。

责任撰稿重新整理自 OpenMLDB PMC 陈迪豪在 QCon 亚洲地区软件结构设计讨论会(上海站)AI 虚拟化分高峰论坛上的刊登的演说录。

期望我们通过责任撰稿能如是说四个方面的文本:最前沿的 AI 资料库体系结构、资料库缓存强化思路和同时实现技术细节和 OpenMLDB 缓存强化在 AI 情景的课堂教学。

责任撰稿产品目录:

Al 资料库与缓存操控性强化 OpenMLDB 与 Spark 缓存计划 OpenMLDB 标准化代码强化同时实现

内存强化在 AI 情景的应用应用领域课堂教学

AI 资料库与缓存操控性强化

什么是 AI 资料库

随著 AlphaGo 到 chatGPT 等愈来愈多的 AI 应用应用领域的破冰,为了应付愈来愈多的 AI 的市场需求,AI 的基础建设工程建设项目也愈来愈多,囊括硬体晶片结构设计、机器学习架构,和特别针对 AI 产业化破冰的资料库,当中主要包括 OpenMLDB 和一些矢量资料库。

AI 资料库是特别针对机器学习和 AI 合作开发的资料库,已渐渐正式成为 MLOps 的重要模块,全力支持主要包括app和新浪网业务流程其中的 AI 应用应用领域的破冰。

OpenMLDB 如是说

OpenMLDB 是著眼于化解 AI 产业化破冰的一类资料库,与现代资料库大同小异。它既并非像 Redis 或 MySQL 那般的新浪网资料库,也并非 OLAP 或 OLTP 资料库。恰好相反,它是一类紧密结合了app和新浪网排序的资料库,可以满足用户机器学习产业化各种市场需求。OpenMLDB 的特点如下:

致力于化解 AI 产业化落地的统计数据治理难题 选用 SQL 和资料库合作开发体验降低合作开发门槛 天然保证线上线下排序一致性,同时实现毫秒级的排序延迟

OpenMLDB 的使用

AI 资料库的使用业务流程与现代的资料库几乎没有区别。首先,OpenMLDB 有 CLI,提供建库建表等接口,可以插入或加载统计数据,这些功能与常见新浪网资料库非常相似。

但是 OpenMLDB 有一个独特的app特征排序功能,可以对海量的特征和原始统计数据进行app计算,例如存储在 HDFS 或 Hive 数仓中的数百 TB 的统计数据,对这些统计数据可以提交分布式app排序任务。

AI时代,你需要了解的AI 数据库架构设计和内存优化思路

用于app特征排序的的 SQL 计划可以直接上线,一旦 SQL 上线,它就正式成为了一个新浪网的 IPC 服务,可以让客户端调用该服务传递原始统计数据输入,并返回经过特征排序后的结果。当结果返回后,任务可以将特征集成到 TensorFlow、PyTorch 等模型推理服务中,从而同时实现一个端到端的机器学习的破冰的应用应用领域。

OpenMLDB 体系结构

OpenMLDB 的体系结构主要包括app特征排序部分和新浪网实时引擎,这两部分通过一个标准化的一致性执行计划生成器同时实现一致性。

AI时代,你需要了解的AI 数据库架构设计和内存优化思路

这个一致性执行计划生成器囊括了一致性的引擎 ASTTree parser,该引擎解析 SQL 语法和词法,生成app和新浪网请求计划,完成逻辑计划生成、逻辑计划强化、物理计划生成、物理计划强化等操作。

AI时代,你需要了解的AI 数据库架构设计和内存优化思路

在这个标准化执行引擎中,我们使用了 OpenMLDB 提供的 SQL Parser 和 Validator 进行校验。同时,我们还使用了 planner 来生成逻辑计划和物理计划,并对其进行强化。由于我们使用的编程接口是 SQL,因此有很多强化空间,比如表达式下推、拼表、转重排等任务都可以在这个阶段完成。完成编程后,用户须要使用 Codegen,它可以为不同的硬体平台(例如 Mac、X86 的机器或 ARM 架构极其)生成不同的代码。最后,我们使用一个执行器来管理行的代码器,标准化 Schemas 管理、状态管理和迭代器等功能。

AI时代,你需要了解的AI 数据库架构设计和内存优化思路

OpenMLDB 缓存架构

OpenMLDB 的统计数据是以行代码的 。现代的资料库像是 MySQL 使用的统计数据代码也是行编码。行代码的好处是同一行随机查询的时候会非常快,在一行内的列都是使用的连续缓存。这个结构设计对 OpenMLDB 的新浪网查询操控性非常重要。Spark 虽然也是app排序,但 Spark 内部全力支持读取 Parquet,而 Parquet 属于列存储,Spark 读到 Parquet 后,它其中部也会转成一个行代码的格式,方便后续做统计数据的迭代和查询。 OpenMLDB app和新浪网使用相同的 Parser、Optimizer 和 Codegen 。这是为了确保用户写的每一个表达式和生成计划都达到app新浪网标准化,从而生成一个 C 语言的函数代码,这个代码再根据不同的硬体平台编译成机器码。app和新浪网标准化使用同一套强化后的硬体码执行,这可从根本上保证它的特征一致性。 OpenMLDB 用的控制技术为 LLVM JIT,对表达式生成平台相关的强化执行代码 。JIT 代表 Just In Time compiler,无需预编译,它是把表达式放到云端,使用 LLVM 后,直接在代码里对表达式做代码,然后生成跟平台有关的强化执行代码。 app集成 Spark, 基于 Java JNI 调用 C++ 代码接口 。由于app的统计数据是海量的,要求大吞吐,必须全力支持分布式地执行。我们的app集成了 Spark 和 Flink 的批处置。此外,OpenMLDB 是基于 Java 的 JNI 去调 C++ 的代码接口。

总结一下,从操控性角度考虑,OpenMLDB 统计数据是以行代码的方法来存储的。为了保证app新浪网的一致性,OpenMLDB 相当于用 C++ 写了一套标准化的 SQL 编译器,再使用 LLVM 做代码生成。对于app的集成,我们集成了 Spark 和 Flink 的批处置,因为 Spark 是基于 JVM 的引擎,它只能通过 JNI 的方法调用 C++ 的接口。

AI时代,你需要了解的AI 数据库架构设计和内存优化思路

思考一下

AI时代,你需要了解的AI 数据库架构设计和内存优化思路

这个问题后续会进行解答。

OpenMLDB 与 Spark 缓存计划

Spark 是大统计数据处置的事实标准,是所有大统计数据处置工具中不可或缺的一部分。作为一个分布式排序架构,从编程接口到排序操控性方面,Spark 一直处于领先地位。然而,自 Spark 1.6 版本开始,其同时实现也遇到了排序瓶颈。这些瓶颈不仅来自硬体,也来自于代码逻辑本身。

AI时代,你需要了解的AI 数据库架构设计和内存优化思路

为如是说决这些瓶颈,Spark 引入了 Tungsten 缓存强化计划,从最初使用简单的 Java 同时实现 row 格式,到同时实现分布式 RDD,再到最终使用 JVM 的 Unsafe 接口进行连续缓存管理。这项强化计划还主要包括向底层指定级别的矢量强化,从而进一步提升了 Spark 的操控性。

Spark Tungsten 缓存强化

Tungsten 缓存强化计划包含以下三点:

缓存管理 。Tungsten 缓存强化计划重新结构设计了 Spark 的 row 缓存管理,采用类似指针的计划来管理连续的缓存,以强化列访问和后面的 Codegen 排序。 缓存强化 。官方博客中提到,Java 的字符串同时实现会导致缓存浪费。比如,一个四个字母的字符串 abcd,理论上只须要申请四个字节,但实际占用缓存却可能达到 24 个字节。这是因为 Java 字符串同时实现中包含 12 个字节的 header,8 个字节的 hash 和 4 个字节的实际文本。Tungsten 的强化可以有效化解这个问题。 Tungsten 的强化 。 在强化前,Spark 的 row 同时实现是基于多个 column 对象的,每个 column 都是一个 Java 对象。 这导致 JVM 管理的小对象特别多,GC 压力特别大。 而 Tungsten 强化后,Spark 的 row 和 column 对象的生命周期其实是一样的,可以手动回收。 这个信息过去是无法告诉 GC 进行强化的,只能将对象引用设为 0 等待 JVM 回收 GC 压力也比较大。

Spark UnsafeRow 强化

Spark Tungsten 包含了 UnsafeRow 强化。

AI时代,你需要了解的AI 数据库架构设计和内存优化思路

它基于 JVM 提供的一类 Unsafe 的 API。客户可以向 JVM 申请一段连续的缓存,并自行管理该缓存。但是,由于该缓存不会自动释放,所以存在缓存泄漏的风险。

Spark UnsafeRow 强化是将所有行转换为 UnsafeRow 对象。该行对象还包含外部的 schema 属性,还有一个指针,指向一个包含单行所有列的连续缓存。Spark 通过指针和偏移来访问用户须要的统计数据,例如读取的字节数、字节类型等。

此强化使用了行代码的 UnsafeRow,与 OpenMLDB 相似,它可以保证所需的统计数据在连续缓存中,对于列的读操控性很高。强化后,Spark Tungsten 可以减少对小对象的管理和 GC 压力。例如,如果用户以前的一行有 100 列共 1 万行,它将具有 100 万个小对象,而现在不须要这么多小对象,缓存标准化由 Spark 来管理。

AI时代,你需要了解的AI 数据库架构设计和内存优化思路

上图总结的是 Spark 的行格式,拥有四列,每一列都是不同类型的统计数据,例如第一列是 int 类型,第二列是 string 类型,第三列是 double 类型,第四列也是 string 类型。在行的开头,有一个 nullbitset,是一个 64 位的长整型,可以表示从 -(2 的 32 次方)到 +(2 的 32 次方)。

然而,在 int 或 long 中无法表示 null。用户可以使用数字零表示有值,但是无法使用 int 表示 null。因此,在许多体系结构中,主要包括 OpenMLDB 和 Flink 中的行都要全力支持 null 值。换句话说,无论用户存储的是什么,如果用户想表示 null,都必须使用一个单独的位来表示。零表示有值,而 1 表示 null,这就是 nullbitset。因此,一般须要使用多少位来表示 null 取决于行中有多少列。

有一个稍微奇怪的地方是,行中的 int 在大多数操作系统同时实现中都是 32 位的,但在 Spark 中,它使用 64 位来表示。同样,由于字符串的长度可能是变长的,因此 Spark 中的字符串表示记录了大小和偏移量,用户可以在普通列类型的基础上,使用后面的变长区域来专门存储字符串文本。最后,用户可以根据偏移量和大小指针读取字符串文本。

然而,这里包含一些问题,例如,为什么 nullbitset 是 64 位?因为图表显示一共只有四列。理论上,四位就足够了。如果按最基本的单位,一个字节就可以了。但是,在 Spark 内部,为了读取访存方便,所有统计数据都按照 64 位来对齐。这意味着,无论是 int、double 还是 float,它们都使用 64 位,这会导致一些浪费。另外,例如,UnsafeRow 没有版本信息,换句话说,如果缓存结构发生变化,相应的代码也必须进行更改。还有一个问题,用户通过 row 指针无法知道行的大小是多少。用户只能像 Spark 一样,在外部有一个 Java 对象,专门维护这个 row 的长度。

总结如下:

AI时代,你需要了解的AI 数据库架构设计和内存优化思路

在编写 Spark 代码时,通常使用其ow。通过将 internalRow 转换为 UnsafeRow 对象,可以方便地按照偏移量读取想要的值。这一点与我们在 OpenMLDB 中进行的缓存强化和缓存对齐等操作密切相关。

然而,Spark UnsafeRow 也存在一些问题。首先,它的统计数据结构不够紧凑,虽然能提高缓存操控性,但也会造成一些缓存浪费。其次,UnsafeRow 没有版本信息,这可能会在代码升级后出现兼容性问题。最后,查询执行

Spark 对比 OpenMLDB Spark

Spark 是在版本 1.6 的时候就开始做的强化。2.0 的时候已经非常稳定。下图是 OpenMLDB 和 Spark 3.0 的操控性对比。纵坐标是运行时间,OpenMLDB 在这种单窗口下排序操控性可以提升一倍,并且在多窗口下操控性可以提升五倍,它的运行时间减少到原来的 1/6。

AI时代,你需要了解的AI 数据库架构设计和内存优化思路

此外,OpenMLDB 做了一些额外的倾斜强化,多线程以后,它的操控性提升可能更大。这个额外的倾斜强化也是 Spark 本身没有的部分。

可以看到,即使 Spark 做了这么多缓存强化,减少了 Java 的小对象,也通过了 UnsafeRow 的接口,但是它跟 OpenMLDB 纯 C 语言同时实现的代码在操控性上还是有较大差异。

OpenMLDB 标准化代码强化同时实现

本章节如是说 OpenMLDB 如何对接 Spark 操控性强化。

OpenMLDB 行缓存代码强化

和 Spark 一样,基于行存储,最大化新浪网行读取操控性 相比于 Spark,基于 C++ 指针同时实现,没有 GC overhead 相比于 Spark,增加 Version header,全力支持多版本格式 相比于 Spark, Nullbitset 以 byte (8 bits) 为单位按需分配 相比于 Spark,不同类型按需分配空间,缓存布局更加紧凑

这里展示 OpenMLDB 行的缓存计划:

AI时代,你需要了解的AI 数据库架构设计和内存优化思路

前面显示的是 6 个 byte 的 Header。当中因为它不会有超过 64 个版本,所以每个版本只须要一个 byte 来表示。这里用 32 位来表示一个 Size。BitMap set 是以 byte 为单位,最小是一个 byte。每个 field 里头的长短是可以变的。比如,一个 field 是 int,它只占 32 个 bit,Long 占 64 个 bit。后面同样也有个变长的一个存储字符串的区域。这个存储字符串的区域,OpenMLDB 也做了一个强化。它的每一个字符串,只要存下 offset 就可以了。所以它的 Size 其实是后面一个 offset 减去前面一个 offset,等于它实际的长度。而这就代表它把字符串的 Size 给强化掉了。此外,它不一定须要用 32 位去表示 size 的长度。而是可以根据实际 row 的大小去算这个 offset 的值,不一定是一个 32 位的 int。

Spark 与 OpenMLDB 行缓存对比

下图是 OpenMLDB 与 Spark 的行缓存的对比。几个特点主要包括:

缓存更紧凑,全力支持多版本和包含整个行 size,所需存储的空间也更小。 OpenMLDB Row,它跟 Spark 相比,多了一个 row size 和 header。但是它在外部不用单独存 size,而且 nullbitset 更小。所有的类型都是可以根据它实际的占用空间来表示。string offset 指针的位置用一个 byte 来表示,长度是 1。最终算出来的整个 row size 是 255 byte。这导致缓存强化大幅度的减少了接近 45%。尤其是统计数据量越大,每一行所占的空间越少。这跟所列的类型有关。列数越多,可以节省的缓存空间也越多。

思考解答

回到前面的问题,计划是用 Spark 把统计数据读出来。Spark 的第一个 op 是从 Parquet 转成 UnsafeRow 的排序。它把 Spark 的统计数据转成一个 Spark CodeGen 代码全力支持的格式。但 C++ 代码怎么去读取转化后的格式呢?

答案是在app引擎的架构上去全力支持 Spark 的统计数据格式 。在app引擎实际执行的时候去调用 Spark API,但是这里头的问题是两个系统的缓存格式本身并不兼容。而 OpenMLDB 提供了 C 的 API 是基于内部 row 的格式, Spark 提供的这个 RDD[Row] 和 RDD[internalRow],返回的都是 Scala 对象,基于 UnsafeRow 的格式。

OpenMLDB app引擎与 Spark 整合

兼容的计划有四个:

GitHub 上代码里头默认的计划叫 encoder 和 decoder。 修改 Spark 的源码。但是这会导致后期不好维护,因为改动 Spark 底层的代码太多。 修改 OpenMLDB 的代码,去兼容 Spark UnsafeRow 的格式。(采取计划)

OpenMLDB UnsafeRowOpt 强化

最后重新整理全力支持操控性强化的计划:

通过 execution engine,拿到 RDD[internalRow],转成 UnsafeRow。然后把这个 UnsafeRow 的指针传给 C 接口。如有须要,可以直接从 UnsafeRow 里头拿到列的值,把它转成 ByteArray 指针传递给 C 函数,就可以用 C 的方法去访问。最后从测试结果来看操控性提升也是非常可观的。 OpenMLDB 测试了十个情景,有些情景的列数特别的多,有些列数比较少。在这可以看出加上 UnsafeRow 强化以后,这个运行的时间从 500 多分钟降到 100 多分钟,大部分操控性提升都非常明显。 后面 OpenMLDB 也做了一些火焰图操控性预测。如果 OpenMLDB 不做强化,它的行排序占比是百分之三点多,占总额排序时间是 3.4。加上操控性强化后,行排序占比降到 1.43,整体任务的排序时间减少了。而且没有代码,开销也小很多。所以加上 UnsafeRow 强化以后,OpenMLDB 的整体操控性会比 Spark 开放源码版本快很多。

缓存强化在 AI 情景的应用应用领域课堂教学

以推荐系统为例,用户可以基于机器学习做建模,并且保证app新浪网一致性。

译者简介

陈迪豪,目前担任 OpenMLDB PMC 和第四范式平台架构师,曾担任小米云深度学习平台架构师和优思德云排序公司存储和容器团队负责人。活跃于分布式系统、机器学习相关的开放源码社区,也是 HBase、OpenStack、TensorFlow、TVM 等开放源码工程建设项目贡献者。QCon 北京 2022 明星讲师。

活动推荐:

5 月 26 日 -5 月 27 日,QCon 亚洲地区软件结构设计讨论会即将破冰广州,从下一代软件架构、研发效能提升、DevOps vs 平台工程建设、AIGC、统计数据驱动业务、工业互联网、出海的思考、金融分布式核心系统、大前端架构等角度与你探讨,欢迎你来现场打卡交流~

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务