Firebolt号称在速度上碾压其他云原生数仓,但是网上关于其资料不是很多,而且由于它不是走开源路线,没有办法直接了解它的实现。于是翻译了其官方文档的技术白皮书,方便大家学习。
摘要
企业上云主要有两个原因:(1)利用最新的技术进步。(2)更低的成本。距离云数仓首次发布已经十年了。大多数公司采用它们来迁移传统的报表和基于仪表盘的分析。云数据仓库供应商确实在技术上进行了创新,以帮助实现这种迁移。解耦的存储和计算架构为我们提供了弹性的可伸缩性,并帮助简化了管理。
但是采用云计算主要是为了帮助IT现代化。他们没有支持企业的新需求。运营和面向客户的交互分析已经成为帮助员工更快地做出更好决策,并为客户提供更多的自助服务。这些新的场景需要10倍或更快的交互查询的性能;空前的数据、查询和用户规模;每个用户需要更低的成本。
自从云数据仓库首次发布以来,在过去的十年中,云数仓并没有在速度、规模和成本方面提供这些新场景所需的数量级的改进。事实上,云数据仓库继承了许多相同的限制,使数据仓库无法支持这些新场景。例如,大多数云数据仓库仍然主要以批处理为中心。它们不支持大规模的流计算,也不提供低延迟的可见性,这两者对于操作和面向客户的场景来说都是至关重要的。那些不能将存储和计算解耦的应用程序具有有限的数据、查询和用户可伸缩性。即使那些将存储和计算解耦的数据仓库,虽然它们提高了可伸缩性,但查询性能也比旧的专用数据仓库要慢。对半结构化数据(现在是数据的主要形式)的支持要么不完整,要么太慢,要么效率低下。
云数据仓库也经常会提高而不是降低成本。有太多的公司花光了他们的月度信贷,或分配的预算。主要的解决方案是限制查询。但是,限制分析的使用违背了将分析和数据交到每个人手中以便更快、更好地做出决策的目标。
Firebolt云数据仓库的设计目的是在速度、规模和效率方面实现综合改进,以经济有效地为ad-hoc、交互式运营和面向客户的分析提供快速、交互式的分析查询;换句话说,对每个人进行快速分析。本白皮书解释了总体架构,以及与前几代云数据仓库相比的关键区别,并提供了一些数据来说明在速度、规模、成本和性能方面可能会有多大的改进。
云数据仓库的需求
今天的云数据仓库需要支持的不仅仅是传统的报表和仪表盘,以及它们背后的分析团队。它必须支持针对批处理和流数据的临时和交互式分析,为100-1000倍以上的用户提供业务分析,因为公司直接将业务分析下推给员工,并为客户提供自助分析。它还需要支持数据工程师和数据工程生命周期。
因此,云数据仓库需要提供的不仅仅是第一代云数据仓库所引入的弹性可伸缩性和简单性。他们还必须在性能、可伸缩性、成本效率和灵活性方面提供一个数量级的改进,以支持这些新用户和他们的分析。今天的需求是:
100% SQL—SQL是数据的实际语言,尤其是对分析师和数据工程师来说。从ELT到任何数据的查询,每个任务都应该可以在SQL中实现。
秒级查询性能—由员工进行的临时、交互式分析和由客户进行的自助分析都需要在几秒钟或更短时间内运行的查询。
gb级规模—较新的数据类型—来自客户交互、连接设备或较新的应用程序—与来自传统应用程序和事务的数据相比规模巨大,而且增长得更快。大多数公司都有tb级的数据,甚至pb级。
弹性规模—写入和查询的工作负载的可预测性较差,这使得弹性规模对于效率和SLA来说都非常重要。
对JSON和其他半结构化数据的原生支持—虽然有些产品确实支持处理JSON,但它并不完整、高性能、低成本或简单。部分挑战在于JSON是作为文本存储的,而不是作为原生数据类型。但是数据工程师还是需要能够轻松地在SQL中操作JSON。
SQL的原生ELT支持—对于数据工程师来说,要在数小时或数天内完成新的分析,他们需要能够完全用SQL提取、加载和转换(ELT)他们自己的数据,而不需要等待单独的团队。
流分析支持—公司需要实时可见性,这意味着他们需要能够支持持续的写入和快速的查询。
高用户和查询并发性—与传统的分析团队相比,分析现在被交付给更多的员工和最终客户群体。它可能需要支持100到1000个并发用户和查询。
工作负载隔离—报表可以在任何时候批量完成,与此不同的是,多个工作负载和用户需要隔离,以帮助确保高优先级、接近实时的sla得到满足,并保护工作负载相互隔离。
数据工程师和DataOps的简单性——数据仓库部署不能再以降低更改以支持新数据需求的方式进行控制。云数据仓库需要支持DataOps,为数据工程师提供更多的控制,并实现更快的数据分析周期。
成本效率——成本需要降低10倍或更多,以支持10-100倍以上的用户消耗10倍或更多的数据。
早期的云数据仓库并不能满足所有这些需求。那些具有解耦存储和计算的是单机的,并提供了弹性伸缩性。它们还通过缓存为报表和其他重复查询工作负载提供了足够的性能。但是它们不能提供特定的、交互式的、可操作的或面向客户的分析所需的性能或效率,而缓存在这些方面的帮助并不大。
从Fivetran等独立基准测试来看,这一点很明显。研究发现,Snowflake、Redshift和谷歌BigQuery的性价比大致相同,对于未缓存数据的平均查询时间为8-11秒,对于1TB数据的集群,每年的24x7成本为15万美元或更高。即使是最昂贵的专业数据仓库,比如Teradata,每年每tb的成本也只有10万美元。
这些基准中隐含的成本过于昂贵,特别是当公司达到pb级的数据时,而且速度太慢。
面向员工和客户的分析以及自动化,需要更快、更划算的分析。当需要做接近实时的决策时,大多数人希望数据在几秒钟或更少的时间内得到。甚至有50%的人希望手机应用能够在2秒或更短的时间内返回。
要满足所有这些需求,就需要重新设计存储计算分离的体系结构,以解决三个主要的性能和效率限制。
数据访问—尽管网络是最大的瓶颈,但大多数云数据仓库通过网络获取整个数据段或数据分区。例如,在AWS中,10、25或100 Gbps 的网络最多每秒传输1gb、2.5或10gb。当处理tb级的数据时,数据访问需要几秒钟或更长时间。获取精确的数据范围而不是更大的段可以将访问次数削减10倍或更多。
查询执行—查询优化在性能上有很大的不同。这也是亚马逊最初选择使用ParAccel的原因之一;因为构建所有的优化都需要时间。然而,大多数云数据仓库缺乏许多经过验证的优化技术—从索引到基于成本的优化。
计算效率—解耦存储和计算架构是福也是祸。它们允许供应商使用几乎无限的规模来提高性能,而不是提高效率。
Firebolt云数据仓库
Firebolt云数据仓库的架构旨在为特定的、交互式的运营和面向客户的分析提供所需的速度和效率。像它的一些前辈一样,它是建立在一个解耦的存储和计算体系结构上的。但它通过优化解耦的存储和计算来提高速度、规模和效率,从而增加了前几代云数据仓库的功能。
与其他现代云数据仓库一样,Firebolt是一个多租户SaaS云数据仓库。它通过JDBC驱动程序和REST api在与其他云数据仓库类似的级别上支持ANSI SQL。
Firebolt还建立在一个解耦的存储和计算架构上,支持水平、线性扩展数据和计算可伸缩性,具有扩展和隔离计算工作负载和用户的能力。与其他存储一样,存储也构建在S3之上。在Firebolt的例子中,计算集群被称为引擎。它们被用于写入和所有类型的分析。工作负载隔离很简单。每当需要支持新的独立工作负载时,只需单击几下鼠标就可以启动一个新引擎。你也可以用同样的方式点击几下缩放。一旦用户连接到引擎并发送查询,数据就会被获取并缓存到引擎的每个节点的本地。
Firebolt增加了其他数据仓库不具备的特性,以帮助提高性能和效率。最大的区别在于解耦计算和存储如何在性能、规模和效率方面进行优化:
存储跨层管理—存储与计算解耦,所有数据通过公共数据访问层作为单个逻辑数据集,跨远程存储和节点上的SSD数据缓存进行管理。虽然远程存储有数据段,但只有小得多的数据范围被拉取和缓存到每个节点的SSD中。
索引加速数据访问和操作—Firebolt广泛使用索引来提高性能。每个表都有一个稀疏(主)索引,它由任意数量、任意顺序的列组成。此外,还有一些索引可以帮助进行聚合、字符串搜索或连接。索引极大地提高了性能,并克服了解耦存储和计算的一些限制。它们还会在写入期间更新,从而支持实时流分析场景。
查询优化是计算和存储感知的—Firebolt优化查询,利用节点间现有数据的位置,并驱动未来的数据分布,以提高每个引擎上的查询性能。
基于性能和效率构建的分布式、动态查询计划—Firebolt查询执行引擎基于存储、索引和查询优化,然后使用LLVM(低级别虚拟机)进行下推优化、向量化处理、以及许多其他的执行技术,以最大限度地提高性能和性价比。
这种使用索引的存储和计算优化既减少了远程数据访问,也减少了缓存10倍或更多的数据量,这也导致需要扫描和处理的数据减少了10倍。查询优化和索引减少了所需的数据量和计算量。这种组合帮助客户将查询性能提高4-6000x,同时将价格性能提高10倍或更多。
Firebolt存储
Firebolt的性能和效率提升从存储开始,它建立在Firebolt文件格式(F3)的基础上,发音为“Triple F”。Firebolt在每一层的数据存储和管理方式都不同——从远程存储到每个节点的本地SSD数据缓存。所有数据都是通过公共数据访问层来访问的,该层管理整个数据生命周期,从写入、数据存储和索引,到跨这些层的数据访问和缓存。
当今大多数存储计算分离的第一个大挑战是数据访问延迟,即获取给定查询所需的所有数据所花费的时间。在这种情况下,网络带宽是主要的瓶颈。AWS提供10Gbps-100Gbps的网络带宽,每秒最多可以传输1- 10gb的数据。即使使用100GB的数据,查询也很容易导致数秒的数据访问时间。您需要等待几分钟才能将1TB的容量加载到集群中。
降低访问时间的最好的方法是减少从存储中获取的数据量。大多数云数据仓库和查询引擎的数据访问效率非常低,因为它们从解耦存储中获取整个分区或段数据。许多算法实现分区级的剪枝和排序,以减少获取的分区数量。但是,如果您只需要每个分区中数据的一部分,那么获取整个分区是没有意义的。对于许多查询,特别是查找,您只需要1%或更少的分区。
Firebolt通过使用索引来访问更小的范围。例如,Firebolt只获取它需要的数据范围,而不是整个分区或段。使这成为可能的是稀疏索引。在Firebolt中,远程存储的单位是一个段,它可以是任何大小(更多信息,请参阅下面的数据写入部分)。在每个段中有更小的单位,称为range。Firebolt只访问更小范围的数据,而不是更大的数据段。只存储range大大减少了数据访问时间。它减少了扫描数据的数量,以及扫描时间。索引还可以在许多其他方面提供帮助。
索引
尽管索引在关系数据库(RDBMS)中被广泛使用,但是索引在大多数数据仓库中并没有被广泛使用。但是,在列存数据库中使用索引可以提高1-3个数量级的性能和效率。
Firebolt在F3中提供了对各种索引的本地支持,以提高性能、可伸缩性和性价比,而且还不断添加新的索引。这个不断增长的索引列表包括:
稀疏索引(主)
聚合索引
连接索引
元数据索引
字符串的索引
您可以将索引看作从两方面改进性能和成本。每个表的稀疏索引或主索引可以减少通过计算获取、存储和处理10倍以上的数据量。其他索引通过将数据和计算替换为缓存的、预先计算的结果来提高性能和降低成本。
Firebolt在每个原子写入操作期间自动更新索引,这确保索引始终与数据一致。
稀疏索引
稀疏索引极大地减少了为每个查询获取、存储和处理的数据量。它是表的主索引,由表中任意顺序任意数量的列组成,并在表定义旁边用一行SQL声明。
在写入数据时,Firebolt会根据稀疏索引自动排序和压缩数据,并增量地更新每个索引。然后,数据和索引作为一个新段提交。在初始声明之后,管理员不需要进行任何维护,比如清理或重新平衡。为了提高性能,Firebolt会随着时间的推移自动优化和合并片段。
数据总是通过F3访问,使用稀疏索引来查找和获取精确range的数据,而不是获取整个段、分区或块,这是其他云数据仓库所做的。只有获取这些小得多的范围,才能在第一次需要数据时通过网络获取10倍或更少的数据。这将减少10倍或更多的数据访问次数。稀疏索引还提高了查询性能,并需要更少的资源,因为Firebolt只在计算节点的SSD上本地存储、扫描和处理小得多的数据范围,而不是整个段。
聚合索引
聚合—从COUNT或SUM到GROUP BY操作—是任何交互式分析的核心,但它们需要大量的计算。一些公司使用物化视图来帮助预计算和存储聚合,但是物化视图的维护成本很高,而且功能有限。例如,一些物化视图不支持COUNT DISTINCT。您还需要重写查询以使用物化视图,除非查询优化器被设计为检测和使用它们。
由于这些限制和成本,虽然许多公司确实在数据仓库中使用了物化视图功能,但其他许多公司却使用Spark或各种ETL技术在数据仓库之外计算它们的聚合。这不仅会增加维护成本。完成任何更改可能需要数周时间,因为您必须与不同的团队协调,然后开发、测试和部署改动。
Firebolt添加了聚合索引,数据工程师可以在创建事实表时或之后添加一行SQL来完成所有这些工作。一个表可以有任意数量的聚合索引。在写入的过程中,Firebolt自动填充和维护每个聚合索引—可以包括原始数据、聚合和其他操作符。每当查询优化器看到使用聚合索引可以更快地执行的操作时,它就会自动将索引添加到查询计划中。数据工程师不需要重写查询。
聚合索引是作为存储在事实表旁边的表来实现的,它们有自己的稀疏索引,以使查询更快。在许多情况下,它们可以替换事实表作为查询的主要源。例如,它们可以自动维护groupby和其他聚合操作符(如COUNT DISTINCT)的许多粒度级别。
每当使用聚合索引时,它就用缓存的、预先计算的结果来代替访问、存储和计算数据的需要。通过减少相关数据访问时间提高了性价比。
连接索引
Firebolt 尽可能的优化了JOIN操作,这是分析中最昂贵的操作之一。
连接索引帮助用查找和其他更快、更便宜的操作符替换全表扫描。因为索引本身很小,所以连接索引存储在内存中以提高性能。例如,连接索引可以使查询优化器将多个表扫描转换为单个查找操作。
Firebolt还可以在连接之前使用“下推”谓词,从而在查找之前减少事实表数据集的大小。查询优化器将根据跨节点的数据位置找到谓词下推和索引的最佳组合,以最大化性能。这包括对嵌套连接和多级谓词下推的优化。
查询优化和连接索引的结合有助于为复杂的、tb级的表连接提供亚秒级的查询性能。
元数据索引
元数据索引有助于提高依赖于主索引以外的变量的操作符或谓词的查询性能。例如,一些元数据存储像COUNT这样的值。其他元数据跟踪MIN、MAX和其他值,以帮助进一步修剪范围。对于基数高的列,这种方法非常有效。Firebolt使用元数据和其他索引进行基于成本的查询优化。它还尽可能只使用索引运行查询,以避免访问数据,这有助于提高性能。
字符串索引
Firebolt有几个内置的索引来支持基于字符串的操作。默认情况下,稀疏索引支持字符串和LIKE操作。但是您也可以使用其他字符串索引,例如哈希索引来支持更快的EQUAL或GROUP BY操作。
查询优化
Firebolt广泛的查询优化是其能够提供秒级查询时间的主要原因之一。每次收到一个新的查询,Firebolt查询优化器就会立即开始构建最佳查询计划。它首先查看所需要的数据range在哪里,这些数据可能需要远程拉取,也查看本地缓存数据。
与其他几个数据仓库一样,Firebolt Query优化器解析每个查询,构建逻辑查询计划,然后使用基于成本和其他优化技术来获得最佳的物理查询计划。
但是Firebolt有几个关键的不同之处,有助于提高性能和效率。一个关键的区别是Firebolt使用了稀疏索引。对于每个表,稀疏索引使F3数据访问层能够减少通过网络获取的数据量,有时减少10倍或更多(图3a)。
另一个关键区别是实现的优化级别。查询优化器评估查询性能是否可以通过重新排序查询操作或使用索引代替来提高查询性能(图3b)。重排序有利于谓词下推,并使用聚合和连接索引来进一步减少数据访问和扫描。例如,您可以在执行联接之前将谓词“下推”为过滤器。这有助于在访问数据或执行连接之前减少数据集。Firebolt可以将下推进行到多个层级。这对于涉及多个事实表或维度表的星形模式和雪花模式有很大的不同。Firebolt还可以在多个级别下推GROUP BY和其他操作,而其他少数数据库只能支持下推一个层级。
一个复杂的嵌套连接查询和几个WHERE(谓词),GROUP BY,和ORDER BY操作(图4a)可以被几个级别的谓词下推和LOOKUP操作(图4b)所替代—所有这些操作都可以通过减少从存储获取的数据量和扫描次数来显著提高性能。最终的结果是一个实时组装的物理分布式查询计划,根据可用索引和查询所需的所有节点数据的位置提供最佳性能。
查询执行
最后一步是实际的查询执行。查询执行方面的许多创新都来自于与查询优化、存储和索引的集成,以最大化性能、规模和效率。像Presto这样的联邦查询引擎与存储的耦合程度不高。其他如Snowflake不区分远程存储和SSD,并将整个分区存储在缓存中,而不是更具体的范围。Firebolt跟踪哪些数据在存储和缓存中,然后构建查询计划以最大化性能。
在查询执行引擎中,有一些继承自公共研究和前几代的数据仓库和云数据仓库的创新。其中两个比较常见的是:
LLVM (Low Level Virtual Machine): Firebolt用C/ C++构建,使用LLVM在执行前快速动态的优化查询计划。
向量化处理:Firebolt利用查询向量化来处理整个列和数据范围,而不是一次只处理一行。将整个列分组为单次计算可以显著提高性能。
Firebolt也有一些独特的创新,它们是通过内部研究和与客户合作发现和实现的。除了上面提到的下推和查询优化技术之外,Firebolt还优化了数据和计算配置,通过使用机器和深度学习技术,预计会有更多的改进。
基于索引的优化:每个物理查询计划都部分地使用索引来构建基于当前数据范围位置的最快查询。一个初始的范围集被收集为一个索引“集”,通过查询优化过程减少索引“集”。这个最终的索引集用于执行查询。
自动数据平衡:在写入的过程中,Firebolt将寻求数据平衡,或者根据需要在S3中合并段及其索引。不需要“真空”,也不需要做其他类型的手动重新平衡或维护。
计算子树和运算符的重用:除了重用缓存中的数据外,Firebolt还重用它已经编译的部分查询计划。数据和计算的配置增加了重用,进一步提高了端到端性能。
解释计划:Firebolt公开了逻辑查询计划(图4b),以帮助用户理解优化。它还收集性能统计信息。Firebolt使用这些信息来帮助提出更多的建议。
可扩展性
在过去的二十年里,数据仓库的可扩展性有两个主要的进步。第一种是shard-nothing结构,它从跨节点划分数据和查询开始。它首次提供了线性的水平“扩展”。但您仍然需要在每个集群上保存所有数据。
第二种是存储计算分离架构,它增加了不同计算集群运行不同查询和根据需要从远程存储“按需”检索数据子集的能力。它允许在不同的集群上进行不同的计算,从而提高了可扩展性性。它还使可扩展性更有弹性,因为您可以轻松地提供和调整新的计算集群。
现代云数据仓库具有解耦的存储和计算以及shard-nothing的架构,通过将任意大小的数据存储在远离任何集群的远程存储中,能够支持PB字节级的数据。通过扩展节点大小、添加更多节点以及在不同的集群上运行不同的查询,它们已经能够支持大型、复杂的查询。它们还能够通过复制集群和跨集群划分用户来支持高并发用户。
但是,即使是最现代的云数据仓库也存在其他可扩展性的瓶颈。这些包括:
数据写入:大多数数据仓库仍然限于以批处理为中心的数据写入。它们不支持低延迟、大规模的流式写入。这在很大程度上是因为大多数数据仓库存储是列存的,需要为单行更新重写整个分区。
数据访问:大多数存储计算分离的架构将整个分区从存储拉取到计算集群中。这是一个主要问题,因为它使网络成为最大的瓶颈。
查询可伸缩性:具有大型连接或复杂嵌套的查询可能需要大量的SSD来存储分区,在处理时需要大量的内存来保存数据,以及大量的扫描和复杂处理计算。在许多情况下,唯一的解决方案是使用非常大的节点类型。
半结构化数据:大多数云数据仓库要么将半结构化数据存储为扁平字符串,要么根本不支持像JSON这样的格式,要求您将其“扁平”或“unnest”到表中的列中。但是处理字符串最终需要大量的计算和内存来保存所有用于扫描的JSON,这限制了可扩展性。
数据写入
数据仓库(包括现代云数据仓库)中最古老的瓶颈之一是写入。大多数仍然只针对基于批次的写入进行优化。过去,从大多数遗留应用程序中提取数据的最佳方法是批处理。随着时间的推移,随着业务需要更多的实时可见性,实时数据管道开始构建,使用了从更改数据捕获(Change data Capture, CDC)到消息传递等一系列技术。但大多数数据仓库仍然以批处理为中心,随着流数据量的增长,这一点变得更加明显。大多数云数据仓库不支持任何合理规模的连续写入。它们最多只能在后台使用微批处理,这导致从接收数据到在查询中看到数据之间有一分钟或更长时间的延迟。主要原因是写入受到储存的限制。
大多数云数据仓库依赖于列式存储,列式存储具有相对较大的不可变分区。每个分区中的每一列通常被压缩为一组单独的文件。为了添加或更新一行,必须重写与该行关联的所有列文件。对于连续写入,您可以用每个新行重写分区,或者批量处理更改。您可以将新数据批处理到新的分区中,并最终进行合并和重建分区。但是不管怎么样更新仍然需要重写。
Firebolt重新架构了写入和存储,不仅支持批处理,还支持流式写入和低延迟分析。
第一个变化是有点像联邦查询引擎。任何Firebolt引擎都可以通过将外部文件作为关系表公开来获取数据。然后,任何人都可以使用SQL从外部文件或其他数据源选择相关数据,执行任何操作,然后将数据插入到F3的目标表中。这使得数据工程师可以自己编写ELT并构建仪表盘,而无需先依赖他人完成工作。
在Firebolt中,任何引擎都可以用于写入。引擎中的每个节点都以非阻塞的方式立即将任意数量的行作为一个新段接收,无论每次写操作是1行还是100万行。如果希望横向扩展写入性能,可以添加更多节点来执行并行写入。这些节点将协同工作以优化写入过程。当数据被写入段内的数据范围时,数据会被排序和压缩。段及其范围也可以根据需要由写入引擎合并,以优化查询性能。
这样可行是因为每次写入或重写段操作都是事务性的,这意味着数据被提交到缓存并保证提交到S3。与写入表相关的数据段相关的每个索引都是同一个事务的一部分。这使得每次读取都是一致的,因为每次读取都是通过F3数据访问层和稀疏索引执行的。
使用稀疏索引,段对查询引擎不重要;它们仅用于远程存储优化。每个引擎仅仅获取数据range并存储在缓存中。这允许写入任意大小的新段。
半结构化数据性能和可扩展性
今天有更多的“大数据”,包括像JSON格式的半结构化数据,而不是“事务性”数据。但是在大多数数据仓库中,对半结构化数据的支持是有限的,甚至是不存在的。传统的方法是将数据平化或解压到表中。但这常常导致需要嵌套查询来分析数据,从而降低了性能。一些数据仓库增加了对将JSON存储为文本的支持。但这需要查询引擎跨所有行将所有JSON加载到内存中,并执行全文扫描进行处理。这导致需要大量内存和大量计算能力。
Firebolt将JSON作为原生JSON摄取、存储和处理。您可以使用带有数组函数和Lambda表达式的SQL来写入和查询JSON。在写入期间,您可以直接加载JSON,或部分UNNEST JSON作为列。JSON可以自动存储为嵌套数组类型。数组函数和Lambda表达式直接遍历嵌套数组,而不必将所有数据加载到RAM中。其结果是具有更好的可扩展性,所需的内存和CPU更少,从而降低成本和得到更快的查询时间。
例如,考虑一下上面的JSON(图7a)以及它是如何存储在Firebolt中的(图7b)。虽然您可以嵌套整个JSON,但您也可以创建一个事实表(图7c),并部分UNNEST一些数据,然后可以使用稀疏索引来优化性能。您还可以在查询中使用UNNEST和ARRAY函数的任何组合(图7d),以及作为函数的Lambda表达式。在所有情况下,Firebolt都是直接遍历原生的嵌套数组结构,而不是进行文本扫描,这提高了性能,并需要更少的缓存和计算。
效率
存储计算分离的一个主要的效率增益是您可以随时启动和停止计算集群。这可以极大地降低“突发”工作负载的计算成本,例如基于批处理的写入或变化很大的查询工作负载。
但云数据仓库仍然可能变得昂贵,特别是当它们允许任何查询或被用作原始数据的数据湖时。这主要是由于云数据仓库计算的成本,以及计算效率的缺乏。水平扩展的数据库常常依赖于shard-nothing架构,通过添加更多的计算来提高性能,而不是提高每个节点和集群的效率。这导致公司为了控制成本而限制分析,这违背了向更多人开放分析从而实现更好、更快的数据驱动决策的商业目标。
Firebolt不仅仅是为了性能而设计的,它还结合了性能、可扩展性和效率。它包含了许多特性,使公司能够扩大规模,并选择最优的性价比,或在给定的成本下的最佳性能。从更高效的存储和索引到查询优化和执行,再加上对最优资源的最贱选择,与运行在类似基础设施上的替代方案相比,Firebolt提供了10倍或更高的性价比。
节点类型选择
获得最高性价比的部分方法是为每个工作负载或查询选择计算、缓存和扩展或水平扩展选择最佳组合。节点类型可以是I/O密集型以支持更快的写入,也可以是计算密集型以支持查询,或者两者兼顾。根据查询的类型,向上或水平扩展可能对提高性能更有意义。
Firebolt允许管理员为每个引擎选择任意大小和类型的节点,并为每个引擎选择任意数量的节点(最多128个),以实现最佳的性价比。分割工作负载(如写入和查询),或使用不同sla的不同用户,可以实现更大的性价比。
通过索引提高效率
索引无需进行任何额外的优化仅仅通过减少每个查询所需的计算量可以帮助提高效率。通过只访问和存储用户及其特定查询所需的范围,每个表的稀疏索引有助于减少每个计算节点的缓存和计算需求。与其他存储计算分离的结构相比,这可以显著减少缓存需求,因为范围比段/分区小得多。因为所有的扫描都更小,需要的计算量也更少。即使没有任何索引,SQL中的原生JSON存储和Lambda表达式也可以减少10倍的集群需求。
添加更多的索引不仅可以提高性能。它还可以进一步减少计算需求。对于任何重复ad-hoc或者报表盘,聚合索引可以通过在写入期间预先计算一次所需的聚合和其他操作,从而显著降低成本。Firebolt将只访问和使用指标所需的索引,而不是原始数据。连接索引通过减少扫描的数据量,以类似的方式降低事实连接和维连接的计算成本。
在早期部署版本中,写入会使用总计算成本的10-15%。这包括将外部表中的数据加载到Firebolt中。增加更多的索引只增加了不到3%的额外成本。这就是为什么在某些情况下,通过减少计算需求,索引可以为分析节省高达50%的计算成本。
存储优化
Firebolt存储不需要任何手动优化,比如重新排序和重新平衡分区或清理空数据。不管是写入还是随后,它会在后台自动合并数据段,以提高性能。例如,持续的写入将会以非常低的延迟添加大量的新数据段,并且数据范围将会重叠。随着时间的推移,Firebolt将更新的部分合并为旧的部分,并在它认为有助于提高性能的时候合并范围。每当发生合并的时候,索引都会更新指向新的范围。
说明
文章中提到的数据范围和range是同一个概念,就是一个数据块的概念。每个range被单独拉取到本地并进行缓存。数据段(也就是segment)是比range大一点的概念,相当于ClickHouse的data part,每次写入都会形成一个segment,但是索引是直接定位range的,这样可以减少从S3拉取的数据量。
文章翻译于Firebolt的官方网站,不知道是不是由于这篇白皮书也是由其他语言翻译成英语而来,英文原文读起来不是很通顺,导致翻译起来感觉很奇怪。也算是三手资料了。