写点什么

百度搜索内容 HTAP 表格存储系统

作者:百度Geek说
  • 2023-11-30
    上海
  • 本文字数:4003 字

    阅读完需:约 13 分钟

百度搜索内容HTAP表格存储系统

作者 | Chaos


导读

本文主要介绍百度搜索内容存储团队应对海量互联网数据分析计算需求时,在构建 HTAP 表格存储系统方向上的一些技术思考。


全文 4683 字,预计阅读时间 12 分钟。

01 业务背景

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


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


以下我们将主要介绍在百度内容 HTAP 表格存储系统设计落地中的一些技术思考,文中的优劣欢迎各位积极交流探讨。

02 存储设计

2.0 需求分析

整套存储设计需要解决的核心问题是——如何在 OLTP 存储系统中支持 OLAP workflow?OLAP workflow 在 OLTP 存储系统上带来的两个最主要的问题是:严重的 IO 放大率、存算耦合。


  • 严重的 IO 放大率。 IO 放大率主要来自两方面,如下图,数据行筛选、数据列筛选。

  • 数据行筛选。在表格存储中,数据按照主键从小到大排列,OLAP workflow 根据条件筛选过滤出符合条件的数据行,会带来严重的 IO 放大。

  • 数据列筛选。表格存储是宽表结构,业务在一次查询中只会获取部分列,但数据是以行结构保存,需要获取整行再提取出需要的字段,依旧会带来严重的 IO 放大。



△图 2.1


  • 存算耦合。 存算耦合主要来自两方面,如下图,存储节点资源冗余、存储空间放大。

  • 存储节点资源冗余。在一个存储节点中,OLTP vs OLAP 占用的计算资源占比是 3:7,为满足 OLAP 需要,就需要对存储节点进行扩容,然而存储节点的扩容又不仅仅是计算资源。同时,OLAP 任务是间歇性的,就会造成忙时供给不足,闲时资源冗余等情况。

  • 存储空间放大。为支持每一个 OLAP 任务的数据访问,存储引擎需要为每一个 workflow 创建对应的 Snapshot,保证 workflow 完成前所依赖的所有数据文件均有效。当 OLAP workflow 耗时过长时,会导致 Compaction 后数据文件无法及时清理的情况,造成存储空间放大。



△图 2.2 Node

2.1 架构设计


△图 2.3


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


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


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


4.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)的弹性资源,解决资源常驻冗余问题。

2.2 存储引擎优化思路

结合上面的分析以及设计思路,已有效地解决了存算耦合问题。在本节中,我们将重点介绍解决 IO 放大率问题的一些优化思路。

2.2.1 数据行分区

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



△图 2.6


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


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


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


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


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


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

2.2.2 增量数据筛选

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



△图 2.7 LSMT

2.2.3 动态列结构

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


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



△图 2.8


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


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

03 计算与调度

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


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


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

3.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 任务生成与调度


1.任务生成。 在任务生成阶段将 KQL 语句解析优化成相关的调度任务,一个 Job 包含多个 Task。


2.任务调度。


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

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

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

04 总结

当前 HTAP 表格存储系统已在全网网页数据离线加速、AI 模型训练数据管理、图片存储以及各类在线离线业务场景落地,数据存储规模达>15P,业务提速>50%。


与此同时,随着大模型时代的到来,对存储系统带来了更多的挑战,我们也将继续深度优化,设计更高性能、高吞吐的 HTAP 表格存储系统。


——END——


推荐阅读


大模型时代,“人人可AI”的百度开发者平台长什么样?


数十万QPS,百度热点大事件搜索的稳定性保障实践


百度搜索万亿规模特征计算系统实践


通过Python脚本支持OC代码重构实践(三):数据项使用模块接入数据通路的适配


百度搜索智能化算力调控分配方法

发布于: 刚刚阅读数: 3
用户头像

百度Geek说

关注

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

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

评论

发布
暂无评论
百度搜索内容HTAP表格存储系统_大数据_百度Geek说_InfoQ写作社区