在数据处理和分析的领域,提升查询效率始终是一项关键挑战。对于 OLAP 来说,性能的关键需求在于能支持实时分析,应对复杂查询,提供快速响应,并具备良好的可扩展性。这些方面,对于满足高效、准确的数据分析需求至关重要。
火山引擎正式发布《云原生数据仓库ByteHouse性能白皮书》,白皮书通过使用 SSB 100G、TPC-H 100G、TPC-DS 100G 数据集进行性能测试,展示出 ByteHouse 在查询效率方面的显著成果,并详细介绍ByteHouse在实时数仓、复杂查询等八大应用场景的高性能应用表现。
作为一款OLAP引擎,伴随字节跳动各业务的发展,ByteHouse已经过数百个应用场景和数万用户锤炼,在2022年3月,部署规模已超过1万8000台,最大的集群规模在 2400 余个节点,管理总数据量超过700PB,并逐步在外部金融、泛互等场景应用和推广。为了更好支持字节内外部大规模数据和复杂场景应用,性能一直以来是ByteHouse重点打磨的产品基本功。
SSB、TPC-H 和 TPC-DS 是常用于测试分析型数据库/数据仓库的数据集。在白皮书中,通过使用以上三种数据集进行性能测试,并以性能著称的某开源OLAP为基准测试产品,ByteHouse在不同查询项上都有显著的性能提升。以TPC-H 数据集举例,在相同硬件和软件环境下, ByteHouse 查询效率高于本次基准测试产品几十倍。
ByteHouse是字节跳动数据平台自主研发的云原生数据仓库产品,在开源ClickHouse引擎之上做了技术架构重构,实现了云原生环境的部署和运维管理、存储计算分离、多租户管理等功能,已通过火山引擎对外提供服务。在可扩展性、稳定性、可运维性、性能以及资源利用率方面,ByteHouse都有巨大的提升。
ByteHouse以提供高性能、高资源利用率、高稳定性、低运维成本为目标,进行了优化设计和工程实现,产品特性和优势如下:
产品能力上,在引擎外提供更加丰富的企业级功能和可视化管理界面:
ByteHouse来源于ClickHouse,但又基于字节跳动内部实践场景经验,进行了一系列升级。在性能层面,主要复杂查询以及宽表查询两方面进行优化。
其中相比单表查询或者宽表查询而言,复杂查询主要包含较多的Agg join和嵌套子查询等特征。在复杂查询优化项中,相比于社区版ClickHouse,ByteHouse升级的能力包含自研优化器以及在引擎层新引入的exchange runtime Filiter模块以及为提升并行化能力而做的一些重构工作。
首先,自研优化器RBO,即基于规则的优化,包含列裁剪、分区裁剪、表达式简化、子查询解关联、谓词下推、冗余算子消除、Outer-Join 转 Inner-Join、算子下推存储、分布式算子拆分等常见的启发式优化能力。
在自研优化器CBO,即基于代价优化部分,ByteHouse主要基于Cascade搜索框架,从而可以边生成物理计划边寻求最优解。并针对join order枚举问题采用了Join graph partition的方式减少了重复计划的生成从而提升搜索性能;另外代价则为基于统计信息生成。
在Join Recorder方面,针对10表级别规模的join recorder问题,ByteHouse能够在秒级别全量枚举并生成最优解,另外,针对大于10表的则使用了启发式,ByteHouse还支持混合Outer Semi Anti Join的reorder功能。
在CTE层面,ByteHouse支持了Inline, shared及partial inline等不同粒度的代价计算,从而计算最优解。
除此之外,ByteHouse具备基于magic set placement能力,通过计算join过滤度代价来选择下推到agg,从而减少agg计算热点的能力。
在生成计划过程中,区别于业界主流的二阶段方式,即先生成最优单机计划再生成分布式计划的方式。ByteHouse优化器融合了两个阶段,先展开所有分布式计划,然后基于全局代价生成最优解,并减少shuffle。其中,ByteHouse也会通过表的元数据信息和属性推论,利用数据分布来减少agg和join的shuffle开销。
优化器生成的物理计划往往按照数据重分布会拆解成多个计划片段即plan segment,相比于社区版ClickHouse,除了优化器生成的物理计划不同之外,plan segment之间数据的传输也是依赖我们新引入的exchange模块能力。模块分为两层,数据传输层和算子层。
此外,ByteHouse还实现了更多exchange性能相关优化,如尽量减少重复的序列化及载批等逻辑。
相对于社区对于join能力,ByteHouse提供了runtime filter能力,这是在执行引擎中动态构建filter的能力,例如在 Hash Join 的 Probe 阶段前,提前过滤掉大部分不会参与 Join 的左表数据,从而减少数据传输和计算的开销,提升性能。这里的Runtime Filter是在 Hash Join 的 Build 阶段后,结合 Join Key 和 Hash表生成。此外,ByteHouse支持根据不同的场景生成最优的 RuntimeFilter,优化了 Runtime Filter 的生成和执行的流程。同时,也支持 Distributed 和 Local 的 RuntimeFilter,及自适应的 Shuffle-Aware 能力。
除了以上介绍的优化器、exchange和runtime filter能力外,ByteHouse也是一直朝着提升并行计算能力的方向持续在演进。
针对agg和join,社区版ClickHouse的解法通常不会考虑数据的分布特性,以及一些算子的聚合度特性,从而产生大量的无意义的blocking的中间结果的merge开销以及join跨节点的shuffle开销。
针对agg,ByteHouse实现了自适应的agg streaming能力,可以根据聚合度减少无意义的中间merge开销。
另外,结合优化器,和bucket表能力,ByteHouse用了数据分布特性,大量减少了agg和join的shuffle开销,从而提升了并行度。
针对社区ClickHouse典型宽表场景,ByteHouse做了全局字典、Zero copy以及Uncompress Cache优化。
首先,全局字典主要功能是通过全局字典编码的方式将变长的字符串转化为电长的数值。针对 AGG function 和 exchange 算子,不仅在单节点上单节点以,也可以在跨节点间直接进行这个编码值的计算,以此提升计算效率。
其次,Zero copy是应对内存墙的一种优化方式,通过减少数据传输中引发的深拷贝开销,尽量提升内存带宽在真正计算上的使用。
最后,针对单节点上多线程同时并发访问Uncompress cache引发常见的锁竞争的现象,ByteHouse做了针对性优化,保证了Cache带来的性能收益。
以下是ByteHouse在标准数据集的性能表现。本次发布会主要聚焦100G 的规模。针对每项测试,ByteHouse和某款开源的 OLAP 引擎进行了性能对比。
从 TPC-DS 100G 的结果可以观察到,经过测试发现在完成 TPC-DS 标准测试数据集的 99 个查询中,ByteHouse比开源产品OLAP 引擎总体时间超出 6 倍多,并且开源产品部分语句无法正常执行。在两者均完成查询的结果中,开源产品与 ByteHouse 查询时间相差 15.7 倍,其中Q53、Q63、Q82 等语句的查询效率相差 200 倍左右。
针对TPC-DS 100G 数据集,涉及到前面的收益相关优化项,包括资源的优化器、 exchange 算子、 runtime filter 以及全局字典等。详细的结果可以在ByteHouse性能白皮书中仔细阅览。
针对 TPCH 100 数据集,在经过 TPCH 的标准测试数据集的 22 个查询中,开源产品部分与给予无法正常执行,整体查询周期很长,在两者均完成查询的结果中,开源产品与 ByteHouse 的查询时间相差无数倍,其中Q3、Q5、 Q7 等语句的查询效率相差 100 倍以上。TPCH 相关的收益优化项包含优化器 exchange、 runtime filter以及前面提到的并行化重构和全局字典等。
公布的完整的SSB 测试结果,不仅是 13 条针对宽表的测试,还包括另外 13 条在星状模型场景下的进行多表关联的测试。
首先从 13 条宽表查询的结果来看, SSD 宽表测试的 13 个查询中, ByteHouse 查询性能全面超越开源产品,整体查询性能达到该产品的 3.6 倍多。对其中涉及的收益相关的优化项包括优化器 exchange 全区字典 Zero copy 以及 Uncompressed Cache 。
除了以上的宽表查询之外,针对标准的 SSB 多表关联的查询,从结果可以看出,在 13 个查询中,开源产品最后 3 个查询因为内存问题查询失败,整体查询性能与ByteHouse相差较大,其中涉及的优化项包含优化器exchange、 runtime filter、全局字典等。
在大数据和实时分析的时代,在很多业务场景,比如广告等,都对OLAP点查能力有强需求。高并发点查对于商业决策、市场分析、用户行为研究场景中的使用体验和查询精准度都起到重要作用。
如果OLAP系统的高并发点查能力不足,就会存在响应时间慢等情况,在技术层面则体现为索引计算繁重、点查读放大严重、执行链路冗长、锁竞争激烈等问题,ByteHouse通过采用短链路的执行方式、建立unique table 点查索引、提升读链路效率等方式进行优化
首先,我们为高并发的点查场景设计一套更简洁的短路执行计划。
当执行计划分析完后,如果query是一个点查场景,ByteHouse可以为其生成一个特定的优化的规则。
简化后只保留简单的几个规则,例如:
普通的query会生成执行计划,分为两个阶段:阶段一,segment 1下发到各个节点去执行,阶段二 segment 0 汇聚各个节点的数据,这种计划会带来大量的 plan 序列化反序列化,网络传输、数据汇总等一系列的开销;而在点查场景中,可能存在点查只会命中一条数据,那么这一条数据势必就会存在于某一个节点上,那么没有必要把计划发送到各个节点。为此,我们做了如下优化:
完成执行计划上的优化之后,在真正做查询的时候,ByteHouse引入了一个基于unique table 的点查索引。
该索引为一个内存的结构(KV结构),k是检查中所用到的谓词值,value是行号,直接访问点查索引就能得到对应的行号或者对应的mark。点查索引可以和行存复用,通过索引得到行号的集合后可以直接访问对应行的数据。
读链路中首先会进行分区的裁剪,和之前主键过滤一样,分区的裁剪里面有大量的表达式的计算,为此ByteHouse做了更轻量的分区的裁剪,并基于分区裁剪和 unique index 的过滤的结果得到 part 和 mark 的值。针对 limit 可以下推的场景,ByteHouse在 mark 的粒度上建了一个 Min-Max 的索引,然后按照 Min-Max 索引做排序就可以通过 limit 值来判断出真正需要读的 mark 是哪些。这样就可以只读少量的mark,不必要读所有筛选出来的 mark 再做过滤。
读链路里面存在两种格式,一种是列存的格式,一种是行存的格式。
测试场景为 unique 表,点查query为用 unique 表的 key 为谓词。下图中展示了每个优化阶段完成后对应的 QPS 变化,baseline 表示的是未进行任何优化时候的表现
不仅仅是技术层面的性能提升,ByteHouse在实时数仓、复杂查询、宽表查询、人群圈选、行为分析等八大场景中,也将高性能落地。其中,在人群圈选场景中,ByteHouse可以满足大规模数据的分析和查询需求,并具有一套用于解决集合的交并补计算的定制模型BitEngine,该模型能解决实时分析场景中的性能提升问题。相比于普通和Array或者用户表方式,BitEngine在查询速度上有10-50倍提升,解决了人群圈选中误差大、实时性不强以及存储成本高的痛点。
通过一系列技术优化手段,ByteHouse实现性能进一步提升,缩短查询执行时间、优化资源利用,能应对更复杂的查询场景,为用户提供更流畅的数据分析体验。不仅仅是探索性能突破,ByteHouse也在持续拓展产品一体化、易用性、生态兼容性,为业务带来更多的价值,推动各行各业数字化转型。