写点什么

海量存储的批量计算框架

作者:百度Geek说
  • 2024-12-31
    上海
  • 本文字数:6703 字

    阅读完需:约 22 分钟

导读

本文介绍了百度针对海量存储数据计算需求研发的 HTAP 表格存储系统及计算调度架构。项目背景源于原有存储系统难以满足日益增长的 OLAP 业务需求,因此构建了集 OLTP 与 OLAP 于一体的 HTAP 系统,通过存算分离、Serverless 设计等创新点提升 IO 访问能力和资源利用率。同时,自研的计算与调度系统实现了任务开发的 SQL 化和数据处理的 FaaS 化,简化了业务使用成本,提高了开发效率。整体方案在存储成本、IO 能力、IO 放大率等方面取得显著成果,为海量存储数据的计算提供了高效、灵活的解决方案。

01 项目背景及目标

1.1 项目背景

搜索内容存储团队主要负责各类数据,如网页、图片、网页关系等,的在线存储读写(OLTP)、离线高吞吐计算(OLAP)等工作。


原有架构底层存储系统普通采用百度自研表格存储(Table)来完成数据的读、写、存工作,此存储系统更偏向于 OLTP 业务场景。随着近几年大数据计算、AI 模型训练的演进,对存储系统 OLAP 业务场景的依赖越来越重,如数据关系分析、全网数据分析、AI 样本数据管理筛选。在 OLTP 存储场景的架构下,支持 OLAP 存储需求对资源成本、系统吞吐、业务时效带来了巨大挑战。为此我们在百度自研表格存储之外,结合业务实际 workflow 针对性优化,增加构建了一套符合业务需求的 HTAP 表格存储系统以及相应的计算框架,共同组成面向海量存储数据的大批量计算架构系统。

1.2 项目目标

  • 提供海量存储数据计算的超高 IO 访问能力。当前内容存储数据达几十 P+,访问频率按照每周一轮估算,平均 IO 能力需要达到 34G/s,峰值 IO 能力需要达到 200G/s。面对如此庞大的 IO 访问能力,需要从文件系统、存储引擎、分布式存储系统、访问模型等全方位进行深度优化来满足需求;

  • 提供海量存储数据计算的快速开发 &部署能力。在提供海量访问能力的同时,也需要为业务提供访问配套的基础设施,来满足业务开发 &部署计算任务的需求。

02 现有研发条件和工作基础

搜索内容架构存储团负责各类数据,如网页、图片、网页关系等,的在线存储读写(OLTP)、离线高吞吐计算(OLAP)等工作。面对当前海量存储数据的计算需求有清晰的技术和业务认知,第一视角明确清楚地知道系统瓶颈、技术难点、业务需求。


  • 系统瓶颈——当前存储系统能提供的 IO 能力与业务计算需求之间的矛盾。随着大数据、机器学习、大语言模型等新技术的兴起,业务对数据的计算访问需求越来越强烈,然而存储系统的 IO 能力却一直止步不前。为此,迫切需要一款面向数据计算的存储系统;

  • 技术难点——数据表格存储系统的数据访问模型与计算模型之间的矛盾。当前架构底层存储普遍采用百度自研表格存储(Table)来完成数据的读写存工作,此存储系统更偏向于 OLTP 业务场景。但随着近几年大数据计算、AI 模型训练的演进,对存储系统 OLAP 业务场景的依赖越来越重,如数据关系分析、全网数据分析、AI 样本数据管理筛选。在 OLTP 存储场景的架构下,支持 OLAP 存储需求对资源成本、系统吞吐、业务时效带来了巨大技术挑战;

  • 业务需求——方便高效快速的任务开发 &部署能力的需要。在大量搜索内容 OLAP workflow 中,从表格存储系统中提取筛选数据只占全部任务的一小部分,大量任务需要对数据进行加工处理得到需要的结果。常规的做法是多任务串联,这样做的缺陷是大量中间临时数据存储开销。为此我们为 HTAP 表格存储系统构建了一套计算与调度系统。

03 整体方案

3.1 概览

本项目拟研发面向海量存储数据的大批量计算架构,主要分为两大系统,HTAP 表格存储系统、计算 &调度架构。


3.1.1 HTAP 表格存储系统



△图 2.3


  • 架构采用业界 HTAP 主流设计思想,将 OLTP 和 OLAP workflow 拆分到两套存储系统中,如 F1 Lightning、ByteHTAP,在 SDK 层根据任务类型分发到不同的存储系统中;

  • OLTP 存储系统——Neptune,采用 Multi-Raft 分布式协议组建存储集群,采用本地磁盘(SSD/HDD 等) + 百度分布式文件系统 AFS 组成存储介质;

  • OLAP 存储系统——Saturn,Serverless 设计模式,无常驻 Server,即用即加载,贴合 OLAP workflow 的不确定性和间歇性;

  • OLTP 与 OLAP 存储系统间,采用数据文件硬链的方式进行数据同步,全版本替换,成本低、速度快,充分贴合 Saturn Serverless 设计模式。


如上架构设计图,可将 OLTP 与 OLAP workflow 拆分到两套独立的系统中,解决上述提到的存算耦合问题。


  • 解决存储空间放大问题。空间放大主要带来的问题是存储节点成本,Workflow 分离的架构将 OLAP 需要的数据文件采用 AFS 低成本存储,减少了对存储节点存储空间的压力。



△图 2.4


OLAP 存储系统的数据写入并没有使用常见的 log redo 或 raft learner 模式,最主要还是在保证 OLAP 存储系统的 Serverless 特性的同时,又能实时感知到 OLTP 系统的最新写入结果。


  • 解决存储节点资源冗余问题。拆分后,分布式存储节点将大量重型 OLAP workflow 转移到 OLAP 存储——Saturn 中,将极大减少存储节点的计算压力。同时,OLAP 存储的 Serverless 设计模式又可贴合 workflow 的不确定性和间歇性。



△图 2.5 Saturn Serverless 模型


计算节点可以部署在任意计算集群中,如 Map-Reduce、自研计算节点 Pioneer 等,在 SDK 中直接初始化存储引擎,从 AFS 中访问对应分片的数据文件。计算节点可充分利用云原生系统(PaaS)的弹性资源,解决资源常驻冗余问题。


3.1.2 一次开发,多端部署



  • 任务生成。自研 KQL 数据查询语言。在任务生成阶段将 KQL 语句解析优化成相关的调度任务,一个 Job 包含多个 Task。

  • 任务调度。

  • 任务调度的计算节点可以是 Map-Reduce,也可以是自研计算集群 Pioneer,负责不同计算场景。

  • 任务运行容器负责数据依赖部署和运行计算框架。

  • 计算框架采用插件化设计思想,依托 KQL 语言进行差异化描述。计算框架的最大特点是,可在数据处理节点执行用户自定义 FaaS 函数。

3.2 详细介绍

3.2.1 HTAP 表格存储系统


3.2.1.1 OLTP 存储系统——Neptune



Neptune 引擎主要支持四类操作:写、删、读、Scan。每一类操作都通过 RegionMapper 进行映射,对外隔离分区概念。


Neptune 存在两类分区:索引分区、数据分区。


  • 索引分区。索引分区用于减少因为数据分区导致 Key 所在数据分区不明确导致的随机访问 IO 放大问题,提升随机查性能。

  • 数据分区。Neptune 可配置多个数据分区,每个数据分区内包含多个 Locality-Group。分区间的数据理论上是互斥的。


Neptune 各类操作的流程:


  • 写操作:

  • 根据 RowWriter 中设置的 Region 信息找到需要写入的 Region 的 Handle,按照列语义将数据序列化成 RawData。

  • 同时根据 Region 信息生成当前 Key 的 Region 索引信息。

  • 将 RawData 与 RegionIndex 作为一条操作记录 Commit 到引擎中,整个操作为原子操作。

  • 删操作:

  • 由于存在 Region 的概念,删除某个 Key 是需要明确当前 Key 所在的分区。目前的做法是查询一遍分区索引获取分区信息,再准确删除对应分区的数据。这样带来一个问题,删除操作会增加一次分区查询操作,我们可以考虑将分区信息全部加载到内存提升性能。

  • 读操作:

  • 读操作类似删除操作,会首先查询分区索引表,如果在分区索引中查询不到则表明当前 Key 不存在,直接返回 NotFound。否则,根据分区索引查询对应的分区即可。

  • Scan 操作:

  • Scan 时业务可以指定对应的分区以及 CF 信息,RegionMapper 根据这些信息 Select 出合适的物理存储 Handle,然后对这些物理存储进行 Scan。


3.2.1.2 OLAP 存储系统——Saturn



Saturn 主要分三层:文件系统(File-System)、Table(表级别的抽象,非 TG 的 Table)、访问层(SDK),Meta-Server 为每一层提供全局 Meta 信息支持。


  • 文件系统。Saturn 既可以支持 AFS,也支持本地文件系统,同时后续可以支持其他类型的文件系统。文件系统的类型对于 Saturn 来说是插件化可插拔的。使用 AFS 作为文件系统相比于 Table 在成本层面有巨大优势。

  • Table。一个抽象的 Table 包含多个 Slice,理论上每个 Slice 间的数据是互斥的,这里引入数据模型的概念。当前支持两种数据模型:哈希序(hash order)、全局序(global order),两种模型与 Table 完全对等。

  • SDK。SDK 目前支持 Seek 和 Scan 功能,使用方式跟通用的列存储系统保持一致,SDK 直接与文件系统(AFS)连接,对外提供存储 Serverless 的访问能力。


同时,Table 数据的更新和构建包含两种模式:全量构建、增量合并


  • 全量构建。全量构建通过完整 Dump Table 数据的方式对表中的每个分片进行逐步替换,替换过程中采用多版本机制保证访问的稳定性。

  • 增量合并。增量合并通过控制 TG Table 做 Major Compaction 的时机,保证每次获取增量数据前不会发生 Major Compaction。增量数据通过 Snapshot 的形式对外提供所有的操作记录,这些记录保存在 Table SST 文件中,Saturn 把这些 SST 文件 Transform 成自身协议的 SST,再发起 Ingest 操作即可。


3.2.1.3 存储引擎优化——数据行分区


数据行分区思想在很多 OLAP 存储系统中很常见,如当前比较流行的一些数据湖架构,ClickHouse、IceBerg 等。在表格存储中,数据行分区的好处是可以极大减少在数据行筛选过程中 IO 放大率。以下是我们在存储引擎中支持数据行分区的设计思路:



△图 2.6


数据行分区的思想在 OLTP 和 OLAP 存储引擎中都有使用,OLTP 存储引擎以数据行分区构建的数据文件可直接被 OLAP 存储引擎加载,减少了 OLAP 存储的数据构建工作。


数据行分区在 Write、Read、Scan 场景下的处理流程分别为:


  • Write 操作。Write 时会根据请求中的特殊 Region 描述,如分区键,找到需要写入的 Region-Index 和 Region 上下文,前者保存 Key 的分区索引信息,后者中保存实际数据,操作记录由 WAL 中保存。

  • Read 操作。Read 操作相比通常直接访问数据,需要多进行一次分区索引访问,为减少多一次访问带来的性能折损,我们将分区索引信息全内存化。由于索引数据非常小,因此全内存化是可接受的。

  • Scan 操作。Scan 操作相比之下没有任何变更,但在 Scan 特殊分区场景下可大量减少 IO 放大。因为相比之前的行过滤模式,可直接跳过大量不需要的数据。


在业务存储支持时,合理设置数据行分区,可极大减少数据行筛选过程中的 IO 放大率。


3.2.1.4 存储引擎优化——增量数据筛选


在实际业务中,有很大一个场景是获取近期(如近几个小时、近一天)有值变化的数据,常规的做法是 Scan 全量数据,以时间区间作为过滤条件,筛选出符合条件的结果。但如此的筛选逻辑会带来严重的 IO 放大,因为满足条件的结果只占全量结果的一小部分。为此,我们在引擎层调整优化 Compaction 时机以及调整筛选流程,减少增量数据筛选过程中需要访问的数据文件集合,降低 IO 放大,业务提速。



△图 2.7 LSMT


3.2.1.5 存储引擎优化——动态列结构


在 OLAP 存储引擎中,还存在一类访问场景会带来 IO 放大问题,数据列筛选。在表格存储系统中,一个 Key 可以包含多个列族(Column Family),一个列族中可以包含任何多个数据字段,这些字段以行结构存储在同一物理存储(Locality Group)中,当筛选特定数据列时,需要进行整行读取,然后过滤出需要的字段,这也将带来 IO 放大问题。


同时,OLAP workflow 的访问不确定性导致存储层无法及时调整数据在物理存储中的结构。为此,我们引入动态列结构的概念,在逻辑层对业务透明,在物理层根据近期 OLAP workflow 特性及时调整物理结构。



△图 2.8


如上图,在逻辑存储中,分为两个 LG,根据 workflow 特性,把业务常用的访问字段在 Compaction 阶段存放在同一物理存储结构中,反之,这样可以减少字段筛选阶段的 IO 放大率。


动态列结构只在 OLAP 存储引擎中生效,我们在原有 OLAP 存储中引入 workflow 收集以及 compaction 任务,将从 OLTP 存储中同步的数据构建成更适合 OLAP 场景的存储结构。


3.2.2 计算与调度架构


在本节,我们将介绍在此 HTAP 表格存储系统基础上,如何设计实现任务计算和调度系统,简化业务使用成本,提升业务效率。


在大量搜索内容 OLAP workflow 中,从表格存储系统中提取筛选数据只占全部任务的一小部分,大量任务需要对数据进行加工处理得到需要的结果。常规的做法是多任务串联,这样做的缺陷是大量中间临时数据存储开销。


为此我们为 HTAP 表格存储系统构建了一套计算与调度系统,系统两大特点:任务开发 SQL 化、数据处理 FaaS 化。


3.2.2.1 SQL 化与 FaaS 化


我们充分贴合上述存储系统特性,自研了一套数据查询语言——KQL,KQL 类似于 SQL Server 语法。同时,又结合存储系统特性以及计算框架,支持一些特殊语言能力,最主要的是能支持原生 FaaS 函数定义,当然也支持外部 FaaS 函数包依赖。


如下是一段 KQL 语句例子以及说明:


function classify = { #定义一个Python FaaS函数def classify(cbytes, ids):    unique_ids=set(ids)    classify=int.from_bytes(cbytes, byteorder='little', signed=False)    while classify != 0:        tmp = classify & 0xFF        if tmp in unique_ids:            return True        classify = classify >> 8    return False}
declare ids = [2, 8];declare ts_end = function@gettimeofday_us(); # 调用Native Function获取时间declare ts_beg = @ts_end - 24 * 3600 * 1000000; # 四则运算
select * from my_table region in timeliness # 利用存储分区特性,从my_table中的timeliness分区获取数据where timestamp between @ts_beg and @ts_end # 利用存储增量区间特性,筛选增量数据 filter by function@classify(@cf0:types, @ids) # 在Filter阶段调用自定义FaaS函数 convert by json outlet by row;desc: # 对计算框架进行特殊描述 --multi_output=true;
复制代码


3.2.2.2 任务生成与调度



任务生成与调度主要分为三层,任务解析层、任务调度执行层、任务执行容器。


  • 任务解析层。负责将 KQL 表达式解析成实际的任务执行计划,并保存在任务存储容器中。

  • 任务调度执行层。负责将任务计划分发到任务执行容器,并轮训检测任务状态,执行探活、重试等操作。

  • 任务执行容器。提供两种任务执行容器,Pioneer、EMR。前者为自研任务执行容器,后者为公司 Map-Reduce 执行平台。

3.3 技术经济指标

通过上述的架构设计以及优化手段,我们在 IO 能力、访问成本、开发效率等方面取得显著成果。


04 主要创新点

4.1 自研 HTAP 表格存储系统

结合业务特性以及实际需求,构建符合业务场景的 HTAP 存储系统。架构采用业界 HTAP 主流设计思想,将 OLTP 和 OLAP workflow 拆分到两套存储系统中,如 F1 Lightning、ByteHTAP,在 SDK 层根据任务类型分发到不同的存储系统中。系统创新点如下:


  • 存算分离架构。解决 OLTP 存储系统的空间放大问题,将 OLAP Workflow 从 OLTP 存储中分离,分离的架构将 OLAP 需要的数据文件采用 AFS 低成本存储,减少了对存储节点存储空间的压力。

  • OLAP Serverless 设计。分布式存储节点将大量重型 OLAP workflow 转移到 OLAP 存储——Saturn 中,将极大减少存储节点的计算压力。同时,OLAP 存储的 Serverless 设计模式又可贴合 workflow 的不确定性和间歇性。计算节点可以部署在任意计算集群中,如 Map-Reduce、自研计算节点 Pioneer 等,在 SDK 中直接初始化存储引擎,从 AFS 中访问对应分片的数据文件。计算节点可充分利用云原生系统(PaaS)的弹性资源,解决资源常驻冗余问题。

  • 表格数据行分区。数据行分区思想在很多 OLAP 存储系统中很常见,如当前比较流行的一些数据湖架构,ClickHouse、IceBerg 等。在表格存储中,数据行分区的好处是可以极大减少在数据行筛选过程中 IO 放大率。

  • 增量数据筛选支持。在实际业务中,有很大一个场景是获取近期(如近几个小时、近一天)有值变化的数据,常规的做法是 Scan 全量数据,以时间区间作为过滤条件,筛选出符合条件的结果。但如此的筛选逻辑会带来严重的 IO 放大,因为满足条件的结果只占全量结果的一小部分。为此,我们在引擎层调整优化 Compaction 时机以及调整筛选流程,减少增量数据筛选过程中需要访问的数据文件集合,降低 IO 放大,业务提速。

  • 表格数据动态列结构。根据 workflow 特性,把业务常用的访问字段在 Compaction 阶段存放在同一物理存储结构中,反之,这样可以减少字段筛选阶段的 IO 放大率。动态列结构只在 OLAP 存储引擎中生效,我们在原有 OLAP 存储中引入 workflow 收集以及 compaction 任务,将从 OLTP 存储中同步的数据构建成更适合 OLAP 场景的存储结构。

4.2 自研任务生成与调度系统

在大量搜索内容 OLAP workflow 中,从表格存储系统中提取筛选数据只占全部任务的一小部分,大量任务需要对数据进行加工处理得到需要的结果。常规的做法是多任务串联,这样做的缺陷是大量中间临时数据存储开销。


为此我们为 HTAP 表格存储系统构建了一套计算与调度系统,系统两大特点:任务开发 SQL 化、数据处理 FaaS 化。


  • SQL 化。我们充分贴合上述存储系统特性,自研了一套数据查询语言——KQL,KQL 类似于 SQL Server 语法。

  • FaaS 化。在 SQL 化的基础上,同时结合存储系统特性以及计算框架,支持原生 FaaS 函数定义能力,当然也支持外部 FaaS 函数包依赖。


————END————


推荐阅读


网页多模态建模思考


百度垂搜一站式研发平台演进实践


初探图谱Embedding用于异常检测(一)


AIAPI - 转向AI原生检索


学校新来了一位AI作文老师:能看、会评、还教改写

用户头像

百度Geek说

关注

百度官方技术账号 2021-01-22 加入

关注我们,带你了解更多百度技术干货。

评论

发布
暂无评论
海量存储的批量计算框架_百度_百度Geek说_InfoQ写作社区