草庐IT

腾讯灯塔融合引擎的设计与实践

冯国敬 2023-03-28 原文

一、背景介绍

腾讯灯塔是一款端到端的全链路数据产品套件,旨在帮助产品、研发、运营和数据科学团队 30 分钟内做出更可信及时的决策,促进用户增长和留存。

2020 年后数据量仍然呈爆炸性增长的趋势,且业务变化更加迅速、分析需求更加复杂,传统的模式无法投入更多的时间来规划数据模型。我们面临一个海量、实时和自定义的三角难题。不同引擎都在致力于去解决这个问题。谷歌等博客中曾提到,也是我们很认可的一个观点是以卓越的性能可直接访问明细数据(ODS/DWD)成为下一代计算引擎的必然趋势。

下图展示了灯塔融合分析引擎的整体技术架构:

左侧对接应用系统,包括灯塔自己提供的分析模型、可视化方案和一些 API 请求;右侧为融合分析引擎,包括查询引擎层、计算层、物化存储层、存储层分析策略中心和产品化中心。

  • 服务层,包括查询、接收以及治理,比如任务级别的缓存拦截等服务相关功能。
  • 计算层,不同于其他公司的自研方案,我们是在开源能力之上做增强和整合,来满足不同场景的需求。
  • 物化存储层,其中包含了我们构建现代物化视图的解决方案,实现了基于 Alluxio 的块级别缓存池,以及针对 BI 场景基于 Clickhouse 的抽取加速方案。
  • 存储层,对接了多种存储引擎,包括托管给灯塔的存储层和非托管的存储层,即业务方自己的数据。 
  • 分析策略中心,位于上述四层之上。主要负责业务方查询的工作负载中的治理和理解执行的整体链路。从一个任务开始执行,到执行计划的各个阶段的计算的资源消耗、存储的消耗、效率等表征作统一存储,并基于这些明细的数据抽出来一些衍生的指标,以推动任务优化,比如物化模型的构建和 SQL 自动优化,旨在端到端地解决这些问题。
  • 产品化中心,除了灯塔产品套件整体作为产品对外输出以外,融合分析引擎也可以单独作为产品对外输出。

二、挑战与融合分析引擎的解法

回到前文提到的挑战,即以卓越的性能直接访问明细数据,我们会从融合、内核优化和加速三个方面发力。

1、融合

同类产品的思路多为一体化,而本文的思路是取长补短,博采众长,融合开源社区的能力实现 1+1>2 的效果。

① 多源融合前端 

前端聚焦于提供集中化的 SQL 解析、优化和执行计划生成。它更多的承担的是对各个底层的理解以做出更优逻辑执行计划的角色。

前端是基于 Calcite 的两段式。第一段为常规操作,一个 SQL 要经过 Parse、Validate、Optimizer、Planner,通过自建的统一元数据管理中心来提供了运行时的Catalog和统计信息以辅助生成更优的执行计划;第二段为不同引擎的融合,提供统一的对外接口且进行一些定制化的增强。

② 融合后端

前端主要解决的是 SQL 解析和执行计划的生成优化,融合后端真正解决计算层面融合。

RDBMS面临算力、内存不足,无法提高计算并行度;Clickhouse 数据源面临复杂查询效率低等问题。

针对上述问题分别有以下解决方案:

  • 通用 MPP 引擎(Presto\Impala)加上高性能 connector。
  • 增强版 JDBC Connection,基于Mysql表模型对 Split Providers 进行自适应的优化,将单个 Table Scan 转换为多个 Table Scan 以提升计算效率。
  • 针对 Clickhouse 数据源会将分布式表运算改为基于本地表运算。
  • 对 Projection、Aggregation、Predicate 操作进行下推。

③  WLM(Workload Management)

前端和后端解决的是多个引擎如何融合和配合的问题,除此之外是端到端的分析策略中心的实现。裸用开源引擎存在以下问题:

  • 引擎 Profile 指标无持久化,单点分析粒度太细,无法对租户整体进行洞察;
  • 对运维人员要求高,需要足够的工作负载的洞察与优化的能力。
本设计的解决方案是通过自研的WLM(Workload Management),自动化收集不同引擎的 Query Profile 并结合历史查询给出基于专家经验给出优化建议,在策略中心基于优化建议自动设置 Query Options、Hints 等优化配置。

通过一系列的规则探查到这个 SQL 会存在大量的 Shuffle,会导致占用了大量的内存和网络资源。该装置会注入一些 Query Options 和 Hints,比如把它的 broadcast 换成 shuffle join,对于一些 CPU 优化器完成不了的事情基于我们的策略做一个自动优化,等 SQL 再进来就会有比较好的规划。

2、内核优化

在商业场景下经常会遇到很消耗资源量的大查询,如何能够在运行时识别和隔离大查询成为一个挑战。 

查询在运行前是无法断定其查询对资源的影响的,比如两表 JION 后笛卡尔积的导致其输出有上万亿记录数的规模。于是本引擎在收集监控运行时的指标参数,结合负载中心的优化建议,自动设置优化参数,以使得查询更高效的运行;对于无法优化且识别对资源使用有严重影响的查询,会进行拦截,及时止损。

① Impala

Impala 面临的一个挑战是如何充分利用计算引擎的索引加速。

  • 引擎 IO 调度内核优化,比如局部性的同文件多 DataRange 排序;通过调整权重以实现大查询 IO 惩罚,因为有些场景更多想保小查询,将大查询放到慢车道。
  • 存储特性价值发挥-索引(Pageindex、Zorder、Hillbert)。要高效查询原始数据,就需要利用好原始数据中的索引,比如 Parquet 中的数据页 Page Index,可以结合原始存储数据中的索引信息,在运行时进行数据过滤。如果要达到很高的效率,往往不是算法本身,而是底层的数据分布。比如一个谓词的列都是随机分布,那么一个值分布在每个数据页,就无法进行跳过,我们会通过负载中心查看历史查询去优化 Zorder 或者 Hillbert 索引。

② Presto

云架构 Presto 在大规模集群下如何保持高效的 Scalabaility Coordinator 单点问题是一个公认的挑战,这部分优化并非我们独创,而是业界的一个 feature。

第一种方案是 Coordinator HA 方案,但其并没有从根源解决问题,一旦 Active 节点失活,过不久 stand by 节点也会挂掉。

第二种方案是多 Cluster 联邦方案,部署多个集群,通过 Presto Gateway 路由不同的集群。但是路由策略管理是一个很大的难点,如果路由策略不当会带来严重的资源碎片化。

第三种方案是 Disaggregated Coordinator 方案,引入了 ResouceManager 聚合分布式资源状态,每个 RM 内存中维护一份状态数据,RM 之间通过心跳达成状态数据的最终一致。Coordinator 可以正常的 Parse、Validate、Plan,准入时 RM 统一获取资源视图,判断是执行还是等待等状态。

③ Kudu

这是一个不常见的问题,在一个运行很久的大集群,有一台机器要裁撤,由于大集群长时间运行元信息负债严重,导致 Tablet Server 无法优雅下线(需要重启 master),耗时可能高达几小时。

在一次实际生产 Case 中,几十万 Tablet,占用内存 50G 以上,Master 启动和Leader 切换都非慢。经排查,集群一直在加载元数据,并发现以前删除的表和数据集群还在维护。通过源码级别的增强,Master 内存消耗降低 10 倍。


3、加速

考虑到集群的算力和引擎本身的瓶颈上限,除了融合和内核优化,我们还需要做各种各样的加速手段。

除了引擎优化,Databrick 商业版的 OLAP 引擎添加了缓存层和索引层;Snowflake 支持了物化视图的能力;Google 的 BigQuery 提供了多级缓存,以进一步的加速。缓存、计算优化、索引与数据分布、物化、云化是业界的主攻方向,本次分享主要介绍三种手段。

① 缓存

实际场景中经常会遇到重复的查询,我们需要解决如何通过多级缓存机制避免“硬查”集群,加速“SQL 内”的数据扫描性能。该引擎的缓存设计借鉴了 Databrick 的内核缓存、Snowflake 的数仓缓存的缓存设计理念,研发了预计算与多级缓存的技术。

  • 预计算(固定图卡):通过“增量缓存”只刷最新天数据,避免大量数据扫描
  • 统一缓存(重复查询判+非固定图卡缓存):深耕 Calcite 源码,基于 SQL 常量折叠(变更检测)、SQL改写、SQL规则判断。
  • 内核缓存(大 SQL 内存缓存):通过远程告诉缓存+SQL磁盘溢写缓存(Alluxio),加速大查询,减轻 HDFS IO 压力。
  • Alluxio(HDFS 热数据缓存->SSD):通过对历史 SQL 性能数据分析,缓存热表(如大左表)。

② BI Engine

由于 BI 场景不用其他的查询分析场景,BI 场景下的看板对出数的时延要求很高,所以需要 BI 场景进行了特殊的优化。借鉴以 BigQuery 为例,它是有一块单独的内存池,它会根据历史查询判断出热数据并以列式的缓存下来。该引擎除了使用到上述的默认策略,还会添加一个 Clickhouse 的缓存层,基于历史记录判断那些数据是可加速并透明的将可加速的表移动到 Clickhouse 中作为缓存数据。这一整套策略可以让亿级数据运行至毫秒级。

③ 现代的物化视图

如何更高效利用好物化视图面临着三个问题:如何达到用最少成本达到最高性能;如何低成本维护好物化视图;查询时,在不改变查询语句的前提下如何将查询路由到不同的物化视图? 现代物化视图就是在致力于解决上述三个问题。

  • 如何达到用最少成本达到最高性能? 一般方案是做一些领域专家模型。但是对于这样一个平台化的产品是无法做到这一点的, 因为业务方才是最了解业务的。所以该产品可以依赖端到端的负载中心去历史查询记录来找到最大的公共子查询来自动的实现物化视图。同时,还会做一些其他的优化,比如添加相应的索引或者 Zorder\hillbert 排序。
  • 如何低成本维护好物化视图? 增量刷新物化视图,并通过负载中心来分析历史查询物化视图是否起到加速的效果,删除加速效果较差的物化视图。
  • 查询时,在不改变查询语句的前提下如何将查询路由到不同的物化视图?  通过基于 Calcite 的自动改写功能,用户不需要修改原有的 SQL 语句,SQL 会透明地路由到不同的物化视图。

三、实践总结

灯塔融合分析引擎,在 SQL、计算和存储三个技术领域,做了很多的技术创新和沉淀。下图列出了重要的优化点。

四、未来演进方向

我们未来将继续致力于从融合、内核优化和加速三个方向,解决“以卓越性能直接访问数据”的问题。

今天的分享就到这里,谢谢大家。

有关腾讯灯塔融合引擎的设计与实践的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  3. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  4. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  5. ruby-on-rails - Rails 中的推荐引擎 - 2

    我想为我的Rails网络应用程序提供推荐功能。特别是,我想向新注册的用户推荐他可能想要关注的其他用户。Rails中是否有用于此目的的引擎/gem?如果没有,我应该从哪里开始构建它?谢谢。 最佳答案 有Coletivogemhttps://github.com/diogenes/coletivo我试了一下。在MySQL上运行。Neo4jhttp://neo4j.org真的很容易实现一个“跟随谁”。事实上,大多数展示其能力的样本都涉及“跟随谁”。快速提示-只有在JRuby上运行时,Neo4j.rb才会很酷。如果不是-使用Neograph

  6. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  7. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  8. UE4 源码阅读:从引擎启动到Receive Begin Play - 2

    一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame

  9. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  10. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

随机推荐