导读:当前,大语言模型的应用正在全球范围内引发新一轮的技术革命与商业浪潮。腾讯音乐作为中国领先在线音乐娱乐平台,利用庞大用户群与多元场景的优势,持续探索大模型赛道的多元应用。本文将详细介绍腾讯音乐如何基于 Apache Doris 构建查询高效、实时统一分析的 OLAP 引擎,使 OLAP 作为底层基建加强模型连接转化效率、结果输出准确率,最终将大模型 + OLAP 引擎结合为用户提供个性化、实时化、灵活化的智能数据服务平台。
腾讯音乐娱乐集团(以下简称“腾讯音乐”)是中国在线音乐娱乐服务开拓者,有着广泛的用户基础,总月活用户数超过 8 亿,通过“一站式”的音乐娱乐平台,用户可以在多场景间无缝切换并享受多元的音乐服务。我们希望通过技术和数据赋能,为用户带来更好的体验,为音乐人和合作伙伴在音乐制作、发行、销售等方面提供支持。
基于公司丰富的音乐内容资产,需要将歌曲库、艺人资讯、专辑信息、厂牌信息等大量数据进行统一存储形成音乐内容数据仓库,并通过产品工具为业务人员提供数据分析服务。在内容数仓搭建的过程中,我们的工作始终围绕降本增效为主要目的进行优化与迭代,希望在数据服务方面不断提升产品工具的开发与分析效率,同时在数仓架构方面能够有效减少架构成本与资源开销。
在传统数据服务中,我们为业务分析师提供了多种数据服务,包括 SQL 查询、固定看板、定制化的分析工具以及人工跑数。然而,在实际应用过程中仍然存在一定痛点:
- SQL 查询平台 : 业务分析师根据需求进行 SQL 语句编写,对平台数据进行查询分析,每位业务人员都需要掌握 SQL,导致学习成本高、上手难度大。
- 固定看板(Dashboard) : 技术人员基于常规业务开发制作数据看板,虽然能够简化业务分析师查询的过程,但是看板制作成本高且灵活度低,当面对复杂的用户问题时,看板无法及时调整以满足需求变更。
- 定制分析工具: 基于特定的业务需求,技术人员需要定制化开发产品分析工具,整体开发成本过高,且单一的开发工具不具备通用性,随着工具数量增加,操作介面变得散乱,从而降低业务效率。
- 人工跑数: 当以上三个场景都无法满足业务需求时,业务分析师需要向技术人员提需求进行人工跑数,沟通成本过高、整体解决效率低下。
随着行业发展趋势,LLMs 大语言模型(LLMs - Large Language Models,以下统一简称为大模型)出现有效地解决了这些问题。当平台融入大模型后,平台用户输入的问题会进入大模型进行语义解析,自动转化为 SQL 语句触发 OLAP 引擎开启数据分析与查询。通过平台智能问答交互的方式,业务分析师不再需要依靠人工编写 SQL 提供查询分析结果,技术人员也不需要再制作过于固定或者过于定制化的产品工具。大模型 + OLAP 引擎结合的全新数据服务模式,不仅为平台用户提供了个性化、灵活表达、秒级回复的服务体验,还大幅降低了企业内部技术与业务学习成本,加速数据分析效率,实现多端入口统一、界面统一的平台构建。
本文将详细介绍腾讯音乐如何基于 Apache Doris 构建查询高效、实时写入且统一的 OLAP 分析引擎,使 OLAP 作为底层基建加强大模型与之连接转化的效率、结果输出的准确率,最终提供更智能化的问答交互服务,也希望通过这篇文章为有相关业务需求的公司提供不同视角和思路。
大模型 + OLAP :开启数据服务平台新模式
在大模型 + OLAP 架构方案中,目前经典方案如下图所示,大模型充当中间层将用户输入的自然语言转化为 SQL 执行语句,OLAP 作为底层存储和数据处理的引擎,负责接受和执行从大模型发送过来的 SQL 语句,对数据进行预聚合、多维分析等操作,满足大规模数据集的查询分析需求。
然而,这种架构在实际落地过程中也面临一定挑战,例如语义理解的准确性、查询效率的优化、私域知识的理解等方面,具体如下:
- 复杂数据口径不统一: 大模型对于技术方面的词汇,如字段、行列、表等无法理解,相反对于业务方面的词汇,如公司收入情况、日活跃用户数量等能够提供有效翻译与转换。因此挑战之一是需要思考如何引导用户进入指标范围内提问,挑战之二是当用户存在对多种指标、多类指标查询时,需要考虑如何保持指标维度口径的统一、如何有效生成对应的指标计算公式。
- 模型处理效率较低: 现阶段大模型虽然支持交互能力,但推理速度较慢,需要花费十秒级以上响应,用户每增加一个问题输入,就需要花费更多等待时间,使服务质量降低。同时大模型整体按照 Token 收费,使用量增加时也会导致平台成本升高。
- 私域知识无法识别: 虽然大模型已经开展许多公开数据集的语言转换训练,但面对企业内部的大量专业术语仍无法很好地理解转化。以音乐内容数据库为例,大模型时常缺少对于某些冷门歌曲的认知,在问答过程中无法正确给出交互反馈,因此我们需要增强大模型对于私域知识的理解。
- 定制场景无法满足: 大模型主要依据自身数据集进行回答,会出现“知识幻觉”(输出缺乏依据的内容)问题,我们需要允许第三方插件的接入使大模型得以联网,让用户借助内部插件完成更定制化、更多样的任务。因此如何接入、匹配并触发组件功能是我们的重点优化目标。
面对经典方案中的落地难点,我们的总体解决思路是将以上四大挑战逐一拆解,通过组件叠加分阶段完善大模型 + OLAP 架构构建,最终实现全新的交互问答服务模式,接下来我们将介绍各阶段挑战对应的解决方案。
01 增加语义层:处理复杂数据问题
为了解决复杂数据处理问题,我们在大模型与 OLAP 中间增加 Semantic Layer(以下简称语义层)。
一方面语义层作为连接技术与业务之间的转换桥梁,能够将数据字段翻译为业务用户的术语,使业务知识作为额外的抽象层。通过语义层,业务分析师不需要在定义指标后存储于 OLAP 数仓中,能够直接在语义层中指定过滤条件,将所需指标筛选后生成 SQL 语句并在 OLAP 中进行字段查询。这意味着,业务分析师能够把多源数据按照需求定义成语义信息并形成语义标准,有效解决了多种指标、多类维度计算口径不统一的挑战。
另一方面语义层能够针对业务计算逻辑,进行语义加工、描述、关联和运算。语义层在过滤数据后,能够屏蔽由表关联所产生的复杂指标计算公式,将多表 Join 场景进行拆解、转化,形成较为简单的单表查询,以提升语义转化的准确性。
02 设定人工经验:处理模型效率问题
针对模型效率问题,我们的解决思路是对指标计算、明细查询、人群圈选等查询场景进行复杂度判定,将简单查询场景直接跳过大模型解析的步骤,进入底层 OLAP 进行处理分析,使大模型更加专注处理复杂查询场景。
为此,如上图所示我们在模型中添加人工经验判断。当业务分析师输入 “查询各大音乐平台收入”问题时,模型依据判定规则发现该场景只需要提供某个指标或几个维度即可完成,这时不需要将问题进入大模型解析,直接使用 OLAP 进行查询分析,能够有效缩短响应时间,提升结果反馈效率。此外,跳过大模型解析的步骤也能够节省 API 调用经费,解决平台使用成本升高的问题。
03 增加内容映射:处理私域知识问题
针对私域知识的问题,我们在大模型上游增加 Schema Mapper 、在外部建立业务知识库,将平台用户的问题与知识库进行连接,通过 Schema Mapper 判定是否存在部份文字能够与知识库内容匹配。如果匹配成功,大模型将进一步解析转化、OLAP 分析处理。Schema Mapper 与业务知识库的引入,有效解决了大模型对私域知识理解不足的问题,提升语言处理的效果。
目前,我们正在不断对 Schema Mapper 匹配准确性进行测试与优化,将知识库中的内容进行分类处理、字段评级等操作,同时将输入文本进行不同范围的内容映射(如全文本映射与模糊映射),通过映射结果来加强模型语义解析的能力。
04 插件接入:处理定制场景问题
定制化场景主要指代业务范围之外的查询需求,需要将音乐内容数据与法律、政治、金融、监管等方面信息结合提供问答服务。通过增加插件,使平台用户能够访问实时更新且无法包含在训练数据或业务知识库中的信息,以实现定制化交互。
由于插件类型不同,模型接入方式也会有所不同,常见的接入方式主要分为两种:
- Embedding 本地文本接入: 该方式首先对本地文档进行向量化处理,通过语义向量搜索,找到本地文档中相关或者相似的词语进行匹配,之后将文档内容注入大模型解析窗口中生成答案。这种方式非常适合业务分析师希望将音乐内容数据库与最新政策等一类较为私有的文件结合完成查询需求。
- ChatGPT 第三方插件接入: 每款插件具备对应的 Prompt 与调用函数。业务人员在安装某款插件之后,在与模型对话中可以通过 Prompt 词触发函数开启调用。目前第三方插件类型丰富,涉及行业广泛,能够有效增加多元场景的处理与响应能力。
超音数平台框架构思
根据上述大模型 + OLAP 的四大解决方案进行了方案整合,以此进行框架设计并将其命名为超音数平台。大模型主要作用于自然语言与 SQL 分析语句的连接与转化,OLAP 引擎则作为数据存储与查询分析的核心基建。
超音数平台对于业务流程如图所示,模型运转具体过程如下:
- 用户输入问题通过 Schema Mapper 检索,判定字段是否匹配与业务知识库。
- 如若匹配则跳过大模型解析步骤,直接利用知识库中的指标计算公式触发 OLAP 进行查询分析;如若不匹配则进入大模型,开启下一步判定。
- 大模型首先通过人工经验判定问题复杂度,简单查询将指定 OLAP 引擎直接分析,复杂查询则开启语义解析形成 DSL 语句。
- DSL 语句通过语义层进一步过滤、拆解关联查询场景,生成简易单表 SQL 语句以触发 OLAP 数据处理与查询加速。
- 针对需要与外部信息结合的查询场景,大模型会判断是否调用第三方插件来辅助完成查询。
以“某首歌曲能否在综艺节目播出”为例,在经过检索匹配、语义解析后,大模型选择利用 OLAP 数据查询与第三方版权行业插件结合的方式进行回答,最终呈现结果由数仓中的歌曲信息与插件判定结果构成。
如今,业务分析师只需要在超音数平台中定义指标含义、维度类型即可直接开展自然语言的问答交互服务。同时还可以在平台中内置插件、丰富指标市场来拓展语义解析能力,完全覆盖了业务在常规与定制化场景下的查询需求。平台基于大模型 + OLAP 的模式加速业务分析效率,减少技术开发成本,向智能化、个性化、实时化的全新业务服务模式更近一步。
在这里希望可以与大家分享该开源项目,让更多人体验和学习大模型构建,也欢迎感兴趣的读者们共同参与大模型开发与建设。
超音数平台框架演进
在平台构建的过程中,OLAP 引擎作为整体架构的基建对 SQL 语句处理、数据存储分析、上游应用层的查询响应等有着至关重要的作用,我们希望通过架构升级以加强大模型到 OLAP 引擎的转化效率与结果输出准确性。
接下来我们将对比介绍 OLAP 早期架构与新一代架构在数据写入与查询两方面的差异,分享在架构演进过程中大模型 + OLAP 模型优化历程,最终助力超音数平台的构建,开启新一代的数据服务模式。
01 数据架构 1.0
我们初期的业务架构如上图所示,分为处理层、分析层、应用层三部份,用户文本在进入大模型之后解析为 SQL 语句使 OLAP 开始执行任务,具体的工作原理如下:
- 处理层:在 ODS- DWD- DWS 三层中将数据整合为不同主题的标签和指标体系之后,通过对 DWS 调度与采集所需字段,在 DWM 层将维度与指标数据加工成大宽表。
- 分析层:通过大宽表进入分析层,将数据导入 Clickhouse 与 Elasticsearch,其中 Clickhosue 主要负责维度与指标两类数据的查询加速,作为分析引擎为后续提供报表开发服务;Elasticsearch 主要负责维度数据处理,作为搜索/圈选引擎。
- 应用层:业务人员基于场景选取所需要的标签与指标,在应用层中创建数据集作为逻辑视图,同时可以二次定义衍生的标签与指标。
在实际业务使用中,早期架构的数据处理方式存在大宽表带来的数据延迟与存储浪费、多套组件导致架构冗余带来指标维度重复定义、学习与运维成本高等问题,具体如下:
- 数据延迟: 处理层不支持部分列表更新,DWS 层数据写入产生延迟后会造成大宽表的延迟,进而导致数据时效性下降。
- 运维成本高: 在处理层大宽表中维度数据量平均占一张大宽表的 50%,且在大部份情况下变化缓慢,这意味着每一张宽表的开发会将维度数据叠加,造成存储资源的浪费、维护成本增加;在分析层中存在多引擎使用的问题,查询 SQL 语句需要同时适配 Clickhouse 与 Elasticsearch 两个组件,增加人力成本,且两套组件也会加大运维难度,运维成本进一步升高。
- 架构冗余: 在应用层进行指标与维度定义时,导致相同数据会进行多次定义使各种指标、维度定义口径不一致,造成权限不可控,例如上图所示的 T1 (标签)与 M1 (维度)在应用层中,被不同数据集多次定义。
02 数据架构 2.0
基于以上问题,我们开始对架构进行改造升级,并在众多 OLAP 引擎中选择了 Apache Doris 来替换原有组件,主要因为 Apache Doris 具备以下核心优势:
- 实时导入: Apache Doris 能够支持海量业务数据的高吞吐实时写入,时效性可以做到秒级完成导入。
- 引擎统一: 支持 Multi-Catalog 功能,能够通过 Elasticsearch Catalog 外表查询,实现查询出口统一,查询层架构实现链路极简,维护成本也大幅降低。
- 查询分析性能: Apache Doris 是 MPP 架构,支持大表分布式 Join,其倒排索引、物化视图、行列混存等功能使查询分析性能更加高效极速。
在数据架构 2.0 版本中,数据架构保留处理层部份,主要升级分析层架构,并进行了语义层叠加:
- 分析层:引入 Apache Doris 替换 Clickhouse 组件,利用 Doris 的 Elasticsearch Catalog 功能对 Elasticsearch 外表进行查询,实现查询出口统一;
- 语义层:应用层不再需要创建数据集视图,直接通过语义层获取指标与标签内容执行查询任务,有效解决标签与指标口径问题。
03 数据架构 3.0
由于宽表开发过程中,维度数据一般变化较小、字符存储空间较大,且分析查询一般只需要查询最新的维度数据。在这种情况下,如果不断叠加维度数据制作宽表,会造成存储空间浪费的问题,同时查询响应速度也受到影响。
为了进一步提升架构性能,数据架构 3.0 主要将处理层中大宽表进行拆分,同时将分析层统一使用 Apache Doris 作为查询分析引擎:
- 处理层:按照业务分类在 DWM 中将大宽表拆分成缓慢维度表与指标表,使两类表在本地 Hive 中进行关联,通过 Hive 导入 Apache Doris 分析层中加速任务;
- 分析层:将关联数据表直接导入 Apache Doris 中,结合语义层暴露指标与维度以实现语义统一,用户只需要通过过滤条件就能够直接查询数据,得到所需要的结果。
04 数据架构 4.0
我们延续了 3.0 架构中分析层统一的优势,对处理层、分析层、语义层架构进一步优化,使查询性能显著提升:
- 分析层 + 处理层:数仓 DWD 层数据采用 Rollup 功能使事实表与维度表实时关联并创建多个视图进入 DWS 中。通过这种方式,分析层与处理层中的各类指标数据无需再重复定义,能够基于 Apache Doris 全部写入新建的 Rollup 视图中并利用
GROUP BY
将维度传入视图进行查询加速,直接对外暴露所需数据。 - 语义层:利用 Apache Doris 物化视图对指标与维度自定义口径,通过语义物化层进行查询加速,并将指标与维度通过
SUM
加工开发衍生标签与维度数据。 - 应用层:利用 Apache Doris 2.0 版本的倒排索引功能,对现有的索引结构进行丰富,满足了对知识库进行模糊查询、等值查询和范围查询等场景中的能力,进一步加速指标、维度查询响应速度。
数仓架构基于 Apache Doris 迭代升级,最终实现导入实时、引擎统一、查询高效的现代化湖仓 OLAP 引擎,简化架构链路的同时,有效解决大宽表中指标重复定义所带来的问题。在架构演进的过程,我们也积累许多关于 Apache Doris 性能优化经验,希望通过分享给读者们带来一些参考。
Apache Doris 性能优化实践
01 Colocate Join 宽表优化
在上文架构改造中我们提及,由于宽表开发会不断叠加字符数据,消耗存储空间,降低查询性能,因此我们充分利用了 Colocate Join 功能对宽表拆分、本地关联查询加速进行优化,具体过程如下:
- 指标大宽表:采用 Apache Doris 的 Aggregate Key 模型,使用增量的方式将数据覆盖写入;
- 缓慢维度表:主要通过
start_date
和end_date
的设置进行表建设,同时利用end_date
进行分区,当我们需要查询最新的维度数据时只需要将end_date
设置为‘9999-12-31’
即可。此外我们引用 Doris 2.0 版本中的写时合并,利用 Unique Key 模型进行维度数据聚合,使查询性能在该场景中得到很大的提升。 - 对外访问视图:在指标与维度表建设完成之后,利用
CREAT VIEW
提供统一对外访问视图,同时添加end_date
条件,使视图保持最新数据的展示。通过这样的方式不仅能够大幅度降低查询的复杂性,还能够充分利用 Doris 特性实现查询加速。
02 Rollup 解决指标膨胀问题
宽表拆分为指标表与维度表后,我们发现每一次视图产生都需要定义多个指标,出现指标膨胀的情况。以“歌曲播放量结算”为例,当仅定义单一指标时,我们需要将各个平台 + 各类内容进行排列组合,使语义层定义很多指标数据,造成指标数量过多。此外这些指标都需要通过离线生产任务进行加工,并通过 Hive 导入至 Apache Doris 中,造成链路较长、加工维护比较困难。
平台指标:覆盖四大音乐平台,包括酷我、QQ 音乐、酷狗、K 歌内容指标:包含歌曲、歌手、专辑以及厂牌等数据
为了有效解决指标膨胀问题,我们引入了 Doris Rollup 功能。如图所示,在 Doris Base 表数据基础之上,可以根据指定维度来创建任意多个 Rollup 视图并自动进行 GROUP BY
,实现各个平台与各类内容指标定义不重复、查询性能提升的目标。
03 物化视图实现查询加速
除了减少指标数量外,我们还希望能够衍生指标并且做到查询加速。在 Apache Doris 2.0 版本中我们采用了物化视图功能进行衍生指标的开发。目前,我们主要在单一维度表中单独地去查询自定义标签与维度,在定义复杂口径后自动的通过语义层物化任务。
如上图所示我们将指标 M1 、M2、M3 与维度 T1、T2、T3 分别进行定义,并通过 SUM 加工衍生标签,在加工完成之后创建物化视图加速查询。此外,在 Doris 后续 2.1 版本中还会支持多表创建物化视图,我们也非常期待使用该功能。
Apache Doris 导入性能调优实践
目前,腾讯音乐具有 90+ 数据来源表、 3000 + 维度和指标、导入数据量达到千亿级别,我们希望数仓能够支持大规模数据快速导入,且导入过程中保证数据写入的准确性。
导入链路如图所示,主要分为离线与实时两个部分,离线链路中指标表与变更维度表通过 Spark 进行批量导入,两类表利用 Flink 聚合形成宽表后写入;实时链路主要利用 Kafak 消息队列进行流式写入。最终,离线与实时两条链路利用 Flink 实时写入 Apache Doris 数仓中。
由于 Flink 聚合为攒批写入,如果出现写入任务失败,会导致数据丢失;同时,在聚合任务过多、字段过多的情况下存在 Compaction 不及时的情况,导致实时能力不可控;此外在加工宽表的过程中,也会造成重复写入的问题,无法保证数据写入准确性。
在 Apache Doris 2.0 版本发布后,我们引入了其全新功能 Flink Doris Connector 与 Doris Compaction,有效解决了 Flink 聚合引起的问题。
01 Flink Doris Connector 实现快写入
Flink Doris Connector 主要是依赖 Checkpoint 机制进行流式写入,同时该功能默认开启两阶段提交,保证写入过程中 Exactly Once 语义。值得注意的是,我们在引入最新版的 Flink Doris Connector 功能后,实现了从关系型数据库到 Apache Doris 的一键整库同步,承载了我们实际业务中千亿级别的实时并行写入,满足数据快写入与不丢不重的需求。
02 Doris Compaction 保证写入稳定性
为了解决 Flink 聚合引起的偶发性 Compaction 不及时问题,我们引入最新版的 Vertical Compaction 与 Segment Compaction 功能。
- Vertical Compaction 功能优势: 在单次合并过程中,我们不需要再将所有的列读出,只需要加载部份列数据即可,这能极大减少合并过程中的内存占用问题,提高压缩的执行速度,实现在大宽表场景下的部份数据合并。
- Segment Compaction 功能优势: 在单批次大数据量的导入场景下可以有效减少 Flink 写入过程中产生的 Segment 数量,且能够使合并和导入两个过程并行,避免增加导入时间。
如上图所示在引入 Doris Compation 功能后,在写入量增加 50 % 的情况下,Compaction Score 从平均 650 分降低至 80 分,技术人员不再需要担心夜间出现告警的情况,保证了整体链路的稳定性。
总结收益与展望
在引入 Apache Doris 后,数据架构围绕降本增效的目标,不仅在写查方面的性能得到大幅度提升,并且有效减少架构成本与资源开销,具体的收益如下:
- 极速查询分析: 通过 Apache Doris 的 Rollup、物化视图、倒排索引功能,由原来的分钟级查询时间达到现如今秒级毫秒级;
- 导入性能提升: 导入优化完成后,原本 3000+ 维度、指标数据的导入时间需要超过一天,现如今能够在 8 小时内完成导入,导入时间缩短至原来的 1/3,实现快速导入需求;更重要的是,Apache Doris 在保证数据快写入的同时,使数据能够不丢不重、准确写入;
- 链路极简与统一: Apache Doris 将查询与分析出口引擎统一,去除 Elasticsearch 集群使架构链路极简;
- 存储成本降低: 通过大宽表拆分的方式,使存储成本降低 30%,开发成本降低 40% 。
在未来,我们将进一步拓展使用 Apache Doris 湖仓一体功能,对 Hive、MySQL、数据湖等多源异构数据库进行网关统一,实现真正意义上的实时统一分析引擎。同时,尝试 CCR 跨集群数据同步功能,通过用户多集群的数据库表自动同步以提升在线服务数据的可用性。未来,我们也将在测试环节中验证读写负载分离以及多机房备份的性能效果。
目前,Apache Doris 社区已经公布了后续版本中将推出的存算分离全新架构,能够利用低成本的共享存储系统简化上层计算节点的复杂度,使架构带来巨大的成本经济优势。我们也希望能够进一步探索,基于 Apache Doris 本地高速缓存 + 共享存储系统的混合模式,在保障性能的同时降低系统存储开销。
最后,非常感谢 SelectDB 技术团队的积极响应与专业解答,希望通过这篇文章分享大语言模型在互联网业务中的应用,也欢迎更多人参与 Apache Doris 社区与超音数平台的开源框架构建。最后,我们也会持续参与社区活动,将相关成果贡献回馈社区,希望 Apache Doris 飞速发展,越来越好!