了解槽
BigQuery 槽是 BigQuery 执行 SQL 查询的虚拟 CPU。在查询执行期间,BigQuery 会根据查询大小和复杂程度自动计算查询所需的槽数。
您可以选择使用按需价格模式或基于容量的价格模式。两种模式均使用槽进行数据处理。使用基于容量的价格模式,您可以为专用或自动扩缩的查询处理容量付费。基于容量的价格模式可让您明确控制槽和分析容量,但按需价格模式无法做到。
使用基于容量的价格模式的客户可明确选择要预留的槽数。查询会在该容量内运行,并且在部署该容量后需要为其持续支付费用。例如,如果您购买 2,000 个 BigQuery 槽,则在任何给定时间,查询总共只能使用 2,000 个虚拟 CPU。在删除之前,您拥有 2,000 个槽的容量,并需要为其付费。
采用 BigQuery 按需价格模式的项目受每个项目槽配额的限制,且具有瞬时突发功能。对于大多数采用按需模式的用户而言,默认槽容量绰绰有余。根据工作负载的实际情况,访问的槽越多,查询性能也就越高。如需检查您的账号使用的槽数,请参阅 BigQuery 监控。
估算要购买的槽数
BigQuery 的架构支持通过增加资源来高效扩容。根据工作负载的实际情况,增加容量可能会为您带来更多益处。因此,选择最佳的槽购买数取决于您对性能、吞吐量和效用的要求。
您可以使用基准槽和自动扩缩槽进行实验,以确定最佳槽配置。例如,您可以依次使用 500 个基准槽、1,000 个槽、1,500 个槽和 2,000 个槽来测试工作负载,并观察这些槽数量对性能的影响。
您还可以检查项目当前的槽使用量以及您每月希望支付的费用。按需结算工作负载存在 2000 个槽的软上限,但重要的是使用 INFORMATION_SCHEMA.JOBS*
视图、Cloud Logging、Jobs API 或 BigQuery 审核日志检查您的项目目前实际使用了多少个槽。如需了解详情,请参阅直观显示可用的槽和分配的槽。
购买槽并运行工作负载至少七天后,您可以使用槽估算器来分析性能并模拟添加或减少槽的效果。如需了解详情,请参阅估算槽容量要求。
使用槽执行查询
BigQuery 在执行查询作业时,会将声明性 SQL 语句转换为执行图。此执行图会分解为一系列查询阶段,而这些阶段本身是由多组更精细的执行步骤组成。BigQuery 会利用高度分布式的并行架构来运行这些查询,而这些阶段则会建立许多潜在工作器可能并行执行的工作单元模型。各阶段会使用快速分布式 Shuffle 架构相互通信,Google Cloud 博客详细介绍了该架构。
BigQuery 查询执行过程是动态的,也就是说,您可以在查询执行期间修改查询计划。在查询运行时引入的阶段通常用于改进所有查询工作器的数据分布。
BigQuery 可以并发运行多个阶段。 BigQuery 可使用推测性执行技术来加速查询,并可动态地重新划分阶段以实现最佳并行性。
在查询的每个阶段,BigQuery 槽会执行个别工作单元。例如,如果 BigQuery 确定某一阶段的最佳并行化因子为 10,则它会请求 10 个槽以用于处理该阶段。
在槽资源不足的情况下执行查询
如果查询请求的槽数超过当前可用的槽数,BigQuery 会将个别工作单元排入队列,并等待槽变为可用状态。随着查询继续执行以及槽被释放,系统会动态地选取这些已排入队列的工作单元用于执行。
BigQuery 可以为查询的特定阶段请求任意数量的槽。所请求的槽数与您购买的容量无关,而是指示 BigQuery 为该阶段选择的最佳并行化因子。工作单元会排入队列并在有可用的槽时执行。
如果查询所需的槽数超出了您承诺使用的槽数,系统不会向您收取额外槽的费用,也不会根据额外的按需使用费率收取相关费用。您的各个工作单元会排队等候。
例如,
- 查询阶段请求 2000 个槽,但只有 1000 个槽可用。
- BigQuery 会将 1000 个可用槽全部占用,并将另外 1000 个槽排入队列。
- 此后,如果有 100 个槽完成了其工作,那么这些槽会从 1000 个已排入队列的工作单元中动态选取 100 个工作单元。其余的 900 个已排入队列的工作单元继续保留。
- 此后,如果有 500 个槽完成了其工作,那么这些槽会从 900 个已排入队列的工作单元中动态选取 500 个工作单元。其余的 400 个已排入队列的工作单元继续保留。
空闲槽
在任何给定时间,某些槽都可能处于空闲状态。这可能包括:
- 未分配给任何预留的槽承诺。
- 分配给预留基准但未使用的槽。
默认情况下,在预留中运行的查询自动使用来自同一管理项目中的其他预留的空闲槽。这意味着只要有容量,作业就可以一直运行。空闲容量会根据需要立即抢占回原始分配的预留,而不管需要资源的查询的优先级是什么。此操作会自动实时进行。
为防止此行为并确保预留仅使用预配的槽,请将 ignore_idle_slots
设置为 true
。ignore_idle_slots
设置为 true
的预留可以与其他预留共享其空闲槽。
您不能在不同版本的预留之间共享空闲槽。您只能共享基准槽或承诺槽。自动扩缩的槽可能暂时可用,但无法共享,因为它们可能会缩容。
只要 ignore_idle_slots
为 false,即使预留的槽数为 0
,也仍然可以访问未使用的槽。如果您仅使用 default
预留,则最好关闭 ignore_idle_slots
。然后,您可以向该预留分配项目或文件夹,并且它仅使用空闲槽。
ML_EXTERNAL
类型的分配例外,因为 BigQuery ML 外部模型创建作业使用的槽不是可抢占的。具有 ML_EXTERNAL
和 QUERY
分配类型的预留中的槽只有在未被 ML_EXTERNAL
作业占用情况下才能供其他查询作业使用。此外,这些作业无法使用其他预留中的空闲槽。
预留中的槽分配
BigQuery 使用一种称为公平调度的算法在单个预留中分配槽容量。
BigQuery 调度器会强制先在一个预留中正在运行的查询所属的各项目之间均匀共享槽,然后再在给定项目的作业内进行共享。调度器提供最终公平性。在短时间内,某些作业可能会获得不成比例的槽,但调度器最终会纠正此情况。调度器的目标是在主动逐出正在运行的任务(导致浪费槽时间)和过于宽松的逐出(导致包含长时间运行的任务的作业获得不成比例的槽时间)之间找到平衡点。
如果某个重要的作业需要的槽数始终比它从调度器接收到的槽数多,请考虑创建一个具有保证槽数的额外预留,并将该作业分配给该预留。
BigQuery 公平调度机制
槽在项目之间均匀分布,然后在项目中的作业内分布。 这意味着所有查询都可以随时访问所有可用槽,并且系统可以自动根据每个活跃查询的容量需求变化在这些查询之间动态地重新分配容量。在以下情况下,您可以在查询完成后提交新的查询来执行:
- 只要您提交新的查询,系统就会自动在各执行中查询之间重新分配容量。当每个查询的可用容量增加时,个别工作单元可以正常暂停、恢复及排入队列。
- 每当有查询完成时,该查询使用的容量都会自动立即提供给其他所有查询使用。
- 只要查询的容量需求因查询动态 DAG 的更改而发生变化,BigQuery 就会自动重新评估此查询和其他所有查询的可用容量,并根据需要重新分配和暂停槽。
根据查询的复杂性和大小,查询可能并不需要其有权使用的所有槽,也可能需要使用更多的槽。在公平调度机制的作用下,BigQuery 会动态地确保所有槽在任何时间点都会得到充分利用。