头图

作者:StarRocks PMC Chair 赵纯(本文为作者在 StarRocks Summit Asia 2022 上的分享)

一年前,StarRocks 源码开放,StarRocks 社区也正式成立。经过一年发展,社区已经获得了 3400 个 Star,7500 次的 PullRequest,200 名贡献者,7000 多名的参与者,当前已被 170 多家大型企业所采用。后面我所讲的所有内容都离不开整个 StarRocks 社区的支持与贡献。

为了能够给用户提供更快、更灵活、更实时的分析体验,StarRocks 过去一年在产品的功能、性能、稳定性上不断打磨。一年里,StarRocks 一共修改了 80 多万行代码,发布了近 50 个版本。其中我们支持了物化视图 2.0、资源隔离、极速数据湖分析等重要功能。

去年这个时候 StarRocks 发布了 Primary Key,进入了极速统一 2.0 时代,用户能够利用 StarRocks 同时进行实时数据和历史数据的分析。今年我们正式发布 StarRocks 数据湖分析,让用户能够在 StarRocks 上同时进行极速 OLAP 分析与极速数据湖分析,我们将它定义成极速统一 3.0。

#01

极速 OLAP

上图展示的是当前 StarRocks 相比一年前在几个标准测试集下的进步。从图中可以看到,经过一年的打磨,StarRocks 在单表 SSB、多表 SSB、TPC-H 三个标准测试集下,相比去年同期又提升了 50%-80%。接下来我会介绍 StarRocks 几个重磅的功能。

1、物化视图

物化视图包含了两个维度的内容,一个维度是物化,一个维度是视图。物化这个维度指的是物化视图要将数据进行物理化存储,这样后续应用就能够直接使用,起到查询加速的效果。视图是逻辑层次的概念,表达的是一个查询的结果集,视图可以直接被用来指定进行查询。用户使用视图更多的是想做一个逻辑的抽象,用来简化 SQL。

所以物化视图是两者的融合,一方面能够通过物理层的存储来加速查询,另一方面提供了逻辑层的抽象,用来简化用户的 SQL 表达。之前的 StarRocks 也支持物化视图,1.0 版本的物化视图存在着以下几个方面的缺陷:

  1. 表达能力有限,只能够支持单表聚合,不能够支持谓词过滤、复杂表达式,更不能支持多表关联,这限制了物化视图使用的场景。
  2. 用户不能够直接指定物化视图进行查询,这样就没有办法当成一个视图来使用,无法发挥出物化视图在逻辑抽象这个维度的能力。
  3. 物化视图 1.0 分区、分桶方式与基础表完全绑定,这样就限制了物化视图的应用场景。比如用户想要创建一个阅读的物化视图,但是基础表是按照“天”进行分区的,那么在物化视图 1.0 版本,用户是没有办法完成这样的需求的。
  4. 物化视图 1.0 只支持同步更新,在基础表导入时,物化视图同步进行导入。只有当物化视图和基础表都导入成功后,用户的数据才可见。这样有一个弊端,当物化视图数目增多时,导入的时效性就会受到一定的影响。所以,物化视图 1.0 版本更多像是一个索引,而缺少视图这方面的能力。

经过过去一年的设计与研发,StarRocks 发布了物化视图 2.0。物化视图 2.0 是一套全新的物化视图架构,与物化视图 1.0 版本完全不同。相比于物化视图 1.0,物化视图 2.0 具备以下能力:

  1. 物化视图 2.0 支持所有复杂的查询,包括谓词过滤、复杂表达式以及多表关联查询。
  2. 用户可以直接指定物化视图进行查询,完成查询分析,这样用户就可以在完成抽象逻辑的同时完成分析的加速。
  3. 物化视图 2.0 的分区、分桶方式可以与基础表不一致。基础表跟物化视图的分区对应关系可以是一对多、多对一或者是多对多的关系,这样用户就可以更加灵活地构建物化视图。
  4. 物化视图 2.0 支持异步刷新的机制,所以创建物化视图本身并不会影响数据的导入时效性。StarRocks 内部会根据基础表的变更,智能地判断出哪些物化视图的分区需要更新。StarRocks 会异步地完成物化视图的刷新。

上图展示的是用户在分析时如何使用物化视图。

图左展示的是,用户可以直接指定物化视图进行分析。用户在创建物化视图的时候使用较复杂的逻辑用于逻辑抽象,其他的用户可以直接针对抽象之后的视图进行查询分析。相比于视图,通过做物化视图能够获得更快的查询性能体验。

图右展示的是 StarRocks 能够将用户对原表的查询自动改写为对物化视图的查询。这里的物化视图起到的是一个透明加速的能力。

在传统的数仓建设中,用户不仅要设计数仓模型,更要关注整个数仓加工过程,并且在其中耗费了大量时间与精力。如果有了物化视图,用户就可以专注在数仓模型本身,而每一层的加工过程都可以通过物化视图来完成。我们的愿景就是通过物化视图的能力将用户从单调繁重的数据加工工作中解放出来,更加专注在数据分析本身。

2、资源隔离

StarRocks 讲的是极速统一。当用户用 StarRocks 来服务越来越多的业务时,就会面临一个问题:采用什么样的方式来支持不同的业务部署?是业务独立部署还是业务混合部署?

独立部署为每一个业务独立部署一个物理集群,这样的好处显而易见,就是业务之间相互不影响。但这样部署也会有以下缺陷:

  1. 多个集群之间会增加运维的压力,所有的运维操作都需要进行多次,比如升级操作。
  2. 从公司的角度看,独立部署的方式整体的资源利用率会偏低,因为闲置的资源并没有办法被其他的业务所复用。
  3. 由于物理的隔离,数据共享会变得复杂,用户想要数据共享,往往只能将数据拷贝多份。

混合部署,将所有的业务放到一个共享的集群中。在一个大集群中,运维的成本会降低,资源的利用率会升高,数据共享也会变得简单。但是最让用户头疼的一个问题就是在同样的一个集群中,业务之间会相互影响。比如某个业务不小心发了一个查询,将整个集群的资源全部吃光,那么在这个集群上,其他的业务都会被影响。

所以有没有第三种选择呢?尤其是在当前降本增效的大环境下,既能更高效地利用资源,又能够保证业务之间互不影响。

StarRocks 提供了这样的选择:集群内的资源隔离。用户可以为每个业务指定不同的资源组,资源隔离的机制会保证每个业务的资源组不被其他业务所影响。接下来我就为大家简单介绍一下 StarRocks 的资源隔离运行机制以及当前达到的能力。

上图展示的是 StarRocks 资源隔离运行的机制。StarRocks 内部会给资源组划分固定的资源,包括 CPU内存、IO 等等。有些资源是软隔离,比如 CPU、IO,有些资源是硬隔离,所谓的硬隔离超过了就要失败,比如内存。除了资源分配以外,StarRocks 也支持为每个资源组设定一定的限制,对于超过限制的请求就会予以拒绝。比如每个资源组都会有最大的请求并发数,当请求的并发超过限制时,新的请求就会被资源组拒绝掉。

那么资源隔离是如何生效的呢?如上图所示,StarRocks 接收到一个用户请求后,会根据请求的属性将这个请求划分到对应的资源组里。然后 StarRocks 内部就会利用资源组所分配到的资源来执行这个请求,这样一个资源组的资源就能够得到保证,不会使用其他资源组的资源,也不会被其他资源组所抢占。通过这样的机制,StarRocks 就能够保证各个业务在同一个集群内,并且相互之间不影响。 

上图展示的是 StarRocks 当前资源隔离的一个运行效果。测试分两个资源组:大资源组和小资源组,大资源组获得的资源是小资源组的两倍。

图左可以看出,两个资源组运行同样的请求的情况下,大资源组运行更快,并且从执行效率上看是符合所获得资源比例的。图右展示的是当查询运行在大资源组时,开启资源隔离与关闭资源隔离时执行效率的对比图。可以看到,当开启资源隔离后,大资源组里面执行的效率与理论计算效率较相符。通过上面这两个 case 可以看出 StarRocks 当前资源隔离的效果,我也期待资源隔离能够给更多用户带来价值。

3、Query Cache

当前数据分析越来越民主化,企业里进行数据分析的人员越来越多,对系统的压力也越来越大。在这样的场景下,如何提升查询执行的效率呢?过去对于每一个用户的请求,StarRocks 都是完整执行一遍,这并不是最经济最极速的方式。

比如下面这个查询要计算过去 7 天每天的 UV 值,但其实只有最近一天的数据在变更,其他 6 天的数据并没有更新。实际上过去 6 天的数据查询结果是能够被复用的。如果能够复用之前的查询结果,那查询就会执行得更快。所以很自然想到,我们可以针对这样的查询场景设计中间结果 cache 加速查询。

为了能够最大限度地利用查询中间结果,StarRocks 支持的是 tablet 级别的 cache,并不是最终结果的 cache;为了能够更快地加速查询,StarRocks 采用的是 sub-plane result cache;另外 StarRocks 的 cache 还支持 join、聚合等各种复杂算子。查询执行时,StarRocks 会尝试去获得对应 tablet 的中间结果。如果有中间结果可以复用,那么 StarRocks 会利用这部分中间结果。如果没有中间结果可以复用,那么 StarRocks 会针对这部分 tablet 使用原计划来执行计算中间结果,然后会将所有的中间结果用于下一阶段的计算,生成最后的查询计算结果。所以通过这样的 cache 机制,StarRocks 能够最大限度地利用中间结果加速查询。

上图展示的是当前 StarRocks Query Cache 的一个效果图。图左展示的是没有命中 cache 时的时间惩罚,从中可以看到,基本上可以忽略不计。图右展示的是命中 cache 后性能的加速比,可以看到如果命中 cache 查询,性能会有 2-15 倍的提升,这就是 QueryCache 当前的一些进展,期待后面能够给大家带来更惊艳的分析体验。

4、建表不需要指定 bucket

使用过 StarRocks 的同学都会面临一个问题,表的 bucket 到底要设置成多少?为什么设置合适的 bucket 会如此重要呢?如果 bucket 数目少了,StarRocks 的查询并行度与 bucket 数目绑定,过少的 bucket 数目会影响整个的查询性能。

如果 bucket 数目设置过多,那么在数据导入的时候新增的文件会比较小。比如我要导入 100MB 的数据,但是我有 200 个 bucket,那么每个 bucket 才 500KB,这样造成小文件过多,会增加数据管理的成本,也会影响后续的查询性能。所以 bucket 的数目不能过多,也不能过小。

所以用户就会问,那么我到底应该设置成多少呢?为了解决用户的这个困扰,让用户能够更简单地使用 StarRocks,我们做了以下两方面的工作:首先是解耦 tablet 与执行并行度之间的关系。我们通过支持 local shuffle 这样的能力,使得查询并行度与 tablet 数目之间无关。即使只有一个 tablet,上层仍然可以并行执行查询。之前 StarRocks 一个 tablet 上层只能有一个并行路来执行,但新版本的 StarRocks 可以不受 tablet 数目的限制。虽然只有一个 tablet,上层仍然可以并行的执行。

从我们的测试结果中也可以看出,如上图所示,创建一个 tablet 与创建多个 tablet 性能可以一致。这样用户在创建表的时候就不需要为查询性能而考虑应该设置多少个 buckets。除此之外,StarRocks 也支持了按照历史数据大小自适应的选择 bucket 的数目。这样通过上述两项工作,用户在创建表时就不需要花过多的精力来思考到底应该将 buckets number 设置成多少了。

5、导入优化

在导入方面,StarRocks 过去一年也在持续进步。去年我们正式发布了 Primary Key 模型,用于支持实时更新场景下的极速分析。但当时的 Primary Key 只能够进行全量内存加载,当系统内存不足时并不是十分友好。为了解决这个问题,我们支持了 persistent Primary Key。这样用户使用时并不需要将全部主键索引加载到内存中,仍然可以正常使用,从而大大降低了系统运行的内存压力。

从上图中也可以看到,在开启了 persistent PK 时,导入性能基本上没有什么影响,但系统占用的内存比例下降了 80%。

除了在 Primary Key 模型的优化之外,我们还做了很多导入优化。将导入全流程接入了我们 Pipeline 引擎,提供了 2PC 导入事务语义,支持了 Replicate Storage,能够极大提升多副本导入的速率,优化了 Apache Kafka 导入的调度策略。当前最大规模已经支持了 1000 亿/天的导入速度,实现了全面向量化解析 JSON/Parquet,提升两者的导入速度。

上表展示的是当前 StarRocks 的导入性能。可以看到在 342 核、3 台节点的集群规模下,我们导入 3 副本的数据:CSV、Parquet 能够达到 1GB/s 甚至更高的导入性能,JSON 可以达到 400MB/s 的导入性能,即使对于 1 万列的数据也可以达到 500MB/s 的导入性能。

由于篇幅的限制,不能在这里为大家介绍我们的所有优化。过去一年,我们做的优化还包括:CTE 复用、Global Runtime Filter 等等的优化。关于极速统一这件事情,StarRocks 从未停止前进的步伐,相信未来会给大家带来更加极速、更加统一的分析体验。

#02

极速数据湖分析

今年是 StarRocks 第一次向大家介绍数据湖分析,我来介绍下现状。

1、StarRocks 数据湖分析现状

上图展示的是 StarRocks 数据湖分析的整体架构。可以看到,在 Storage 层,数据都存储在 Apache Hive/Apache lceberg/Apache Hudi 这样的数据湖中。在计算层,StarRocks 的无状态节点 Compute Node 会组成多个物理集群,执行用户具体的查询请求。当前 StarRocks 已经可以对接 K8S。物理集群能够自动根据负载情况完成自动伸缩。在控制层,StarRocks FE 完成了数据湖元数据的对接,并接入用户所有的查询请求。在整个架构层面可以看到,当前 StarRocks 的数据湖分析已经具备了存算分离、弹性伸缩的能力。

提到数据湖分析,用户总是觉得数据湖分析的性能会不如 OLAP 快。我们把 StarRocks 数据湖分析叫做极速数据湖分析。那到底有多极速呢?我们认为为用户提供跟仓一样性能的数据湖分析,就是极速数据湖分析。

上图展示的是在 SSB 多表情况下,数据存储在 StarRocks 内与数据存储在数据湖内查询性能的对比。从图中可以看到,数据湖分析的性能已经完全可以媲美数据在仓里的分析性能。所以用户通过 StarRocks 进行数据湖分析,一方面能够享受存算分离、弹性伸缩,一方面还能够享受到与仓查询一样的极速体验。那么 StarRocks 究竟在极速数据湖中做了哪些工作呢?接下来我会为大家一一揭晓。

StarRocks 在数据湖的工作主要分为以下几个维度:第一,更容易的数据接入;第二,更快的分析性能;第三,更好的弹性;第四,更灵活的数据分析方式。数据湖分析数据都已经存在了各个数据湖中,那么我们需要一个简易的方式,能够将数据湖中的数据接入到 StarRocks中。StarRocks 现在提供了Web Catalog 的能力,用户只需要通过一条 SQL 命令就能够将外部数据湖整个湖的数据挂接到 StarRocks 中来,然后用户就可以在 StarRocks 中分析湖上所有的数据。

在新的 Catalog 框架下,StarRocks 已经支持了多种数据源,其中包括 Apache Hive、Apache Iceberg、Apache Hudi 等数据源挂载。Apache Iceberg 支持了 V1、V2 两种 format;Apache Hudi 支持了 MOR、COW 两种数据格式。上图展示的是 StarRocks 相比于 Trino 在 TPC-H 标准测试集下分别在 Apache Iceberg 以及 Apache Hudi 的性能对比。从图中可以看到,StarRocks 相比于 Trino,基本上有 3-5 倍的性能优势。

2、数据湖极速分析的障碍

  1. 数据湖 IO 延迟比较高。数据湖上的数据通常存储在对象存储或者 HDFS 中,其单次的 IO 请求延迟一般会在 20-30ms 之间,相比于本地 SSD 不到 1ms 的查询延迟要高出几十倍。另外不像本地系统一样,数据湖的 IO 访问一般通过 RPC 的方式,很难利用到 OS 的 page cache。
  2. 数据湖上的数据来源比较多,缺少对数据产生者的约束。所以有时数据湖上的数据并不是对数据分析十分有利,比如在有些场景下会有大量的小文件存在。
  3. 数据湖会经常被各种数据分析引擎所访问,但本身又缺少隔离机制,所以会造成相互影响,导致数据湖分析的性能不稳定。比如某些分析会受到一些批处理查询的影响,导致性能急剧下降。

3、极速数据湖分析工作

那么 StarRocks 为了让用户能够使用极速数据湖分析,做了哪些工作呢?

针对湖上单次 IO 请求延时比较高的情况,为了能够让分析执行地更迅速,StarRocks 支持了 Coalesce IO用于合并小的 IO 请求,通过减少 IO 次数,增加每次 IO 的请求量,这样就能够提升整个查询时延。

上图展示的是聚合 IO 的执行原理。在没有这个优化之前,对于每一个列的读取都是一次 IO 请求,在真实的场景中会存在很多列很小的情况。那么在这种情况下,聚合 IO 会将几个列的 IO 合并成一次 IO 请求,某些 Row Goup 会很小,那么 Coalesce IO 会也会将 IO 进行合并。一次 IO 请求包含了几个 Row Goup 的内容,从而降低 IO 的请求量。在文件比较小的情况下,聚合 IO 能够将整个 file 通过一个 IO 请求全部读取,这样可以最大程度减少 IO 请求。通过这个优化,在极端场景下可以指数级提升查询性能,在用户的真实场景中会有 2-3 倍的性能提升。 

Coalesce IO 是根据文件的物理属性进行 IO 优化,那么延迟物化是根据查询请求的特征来进行优化,其目的仍然是减少 IO 的请求次数。像上图中第三行,这样一条 SQL 指令会扫描表中所有的列,但是有一个选择度超低的过滤条件,在正常的执行逻辑过程中会将所有的列先扫描出来,然后完成谓词过滤。这样基本上是一个全标扫描的操作,会有大量的 IO 请求。

那么延迟物化是如何完成的呢?如上图所示,延迟物化会先将谓词列扫描出来,然后进行谓词计算。StarRocks 会按照谓词计算的结果将其他列读取出来。如果数据已经被谓词过滤,那么 StarRocks 就不会读取这一行的数据。这样在选择度极低的 SQL 语句中,延迟物化可以极大的降低 IO 请求量。在这个 case 中,IO 请求量下降了 5 倍,查询性能提升了 8 倍。

数据分析的数据都是有局部性的。虽然湖上存储了大量的数据,但经常分析的数据占少部分的。本地 SSD 相比于湖上的存储具有延迟低、没有干扰的特点。所以 StarRocks 实现了本地 Cache,利用本地存储来加速数据湖分析。

StarRocks 实现的本地存储是 File Block 级别的 Cache,不是 File 级别的 Cache,这样能够使 Cache 利用率更加高效。并且为了保证 Cache 命中率高,在查询调度时引入一致性哈希算法,尽可能保证数据的局部性,保证对同一份数据的查询尽可能落到同一个节点来处理,这样 Cache 的命中率更高,Cache 的资源利用率也更充分。通过 Local Cache 这个能力,如果本地 Cache 的容量足够,那么数据湖分析的性能完全可以和仓的性能所媲美。

数据湖上的分析往往具有比较强的随机性。如果使用固定资源来支持,通常没有办法最大化利用资源的。而数据湖分析数据往往都在湖中,那么就天然具备了存算分离的特点。基于此,StarRocks 的数据湖分析也实现了计算资源的弹性伸缩,是通过以下几步来完成的:第一,我们支持了完全无状态的节点 computer node 这样就可以能够做到快速在集群中增删节点。第二,将 StarRocks 与 K8S 集成,通过 K8S 完成资源管理与编排,就能够实现在资源紧张的时候增加节点,在资源充裕的时候释放节点,从而能够实现计算资源的弹性伸缩。另外 StarRocks 当前也支持在一个集群内创建不同的 compute node 组。用户可以指定使用不同的物理资源来执行具体的查询请求,这样能够将不同类型、不同优先级的业务在物理层面进行隔离。

数据湖上存储了大量没有处理过的数据,存在大量半结构化的数据,比如会有似 Struct、Map 等类型。为了能够让用户分析所有的数据,StarRocks 原生地支持了常见的半结构化数据类型,包括 JSON、Array、Struct、Map。用户可以使用 StarRocks 对这些类型的数据进行极速分析,并且 StarRocks 实现了Java UDF 框架支持用户自定义 UDF、UDAF、UDWF、UDTF。这样用户可以很容易进行能力扩展。StarRocks 也支持了 λ 表达式,使得用户分析更加灵活。

#03

总结与展望

未来 StarRocks 还将努力为用户带来更极速、更统一的分析体验,并且 StarRocks 会全面拥抱云,坚定不移地向云原生方向努力。期待在不久的将来,StarRocks 能够为用户带来云原生版本的极速、统一分析体验。

关于 StarRocks

StarRocks 创立两年多来,一直专注打造世界顶级的新一代极速全场景 MPP 数据库,帮助企业建立“极速统一”的数据分析新范式,助力企业全面数字化经营。

当前已经帮助腾讯、携程、顺丰、Airbnb 、滴滴、京东、众安保险等超过 170 家大型用户构建了全新的数据分析能力,生产环境中稳定运行的 StarRocks 服务器数目达数千台。 

2021 年 9 月,StarRocks 源代码开放,在 GitHub 上的星数已超过 3400 个。StarRocks 的全球社区飞速成长,至今已有超百位贡献者,社群用户突破 7000 人,吸引几十家国内外行业头部企业参与共建。


StarRocks
4 声望15 粉丝

Linux 基金会项目 StarRocks 是新一代极速全场景 MPP 数据库,遵循 Apache 2.0 开源协议。