跳至主要内容

工作负载调度

当 ClickHouse 同时执行多个查询时,它们可能会使用共享资源(例如磁盘)。可以应用调度约束和策略来规范不同工作负载之间如何利用和共享资源。对于每个资源,都可以配置一个调度层次结构。层次结构根表示一个资源,而叶子是队列,保存超过资源容量的请求。

注意

目前,只能使用所述方法调度远程磁盘 IO。有关 CPU 调度的信息,请参阅有关线程池的设置和 concurrent_threads_soft_limit_num。有关灵活的内存限制,请参阅 内存超额分配

磁盘配置

要为特定磁盘启用 IO 调度,您必须在存储配置中指定 read_resource 和/或 write_resource。它告诉 ClickHouse 对于使用给定磁盘的每个读写请求应该使用哪个资源。读写资源可以引用同一个资源名称,这对于本地 SSD 或 HDD 很有用。多个不同的磁盘也可以引用同一个资源,这对于远程磁盘很有用:如果您想能够在例如“生产”和“开发”工作负载之间公平分配网络带宽。

示例

<clickhouse>
<storage_configuration>
...
<disks>
<s3>
<type>s3</type>
<endpoint>https://clickhouse-public-datasets.s3.amazonaws.com/my-bucket/root-path/</endpoint>
<access_key_id>your_access_key_id</access_key_id>
<secret_access_key>your_secret_access_key</secret_access_key>
<read_resource>network_read</read_resource>
<write_resource>network_write</write_resource>
</s3>
</disks>
<policies>
<s3_main>
<volumes>
<main>
<disk>s3</disk>
</main>
</volumes>
</s3_main>
</policies>
</storage_configuration>
</clickhouse>

工作负载标记

可以使用设置 workload 标记查询以区分不同的工作负载。如果未设置 workload,则使用值“default”。请注意,您可以使用设置配置文件指定其他值。可以使用设置约束来使 workload 保持不变,如果您希望用户的所有查询都使用 workload 设置的固定值进行标记。

可以为后台活动分配 workload 设置。合并和变异分别使用 merge_workloadmutation_workload 服务器设置。这些值也可以使用 merge_workloadmutation_workload merge tree 设置为特定表覆盖。

让我们考虑一个具有两个不同工作负载的系统示例:“生产”和“开发”。

SELECT count() FROM my_table WHERE value = 42 SETTINGS workload = 'production'
SELECT count() FROM my_table WHERE value = 13 SETTINGS workload = 'development'

资源调度层次结构

从调度的角度来看,资源表示调度节点的层次结构。

可能的节点类型

  • inflight_limit(约束) - 如果并发进行中的请求数超过 max_requests 或其总成本超过 max_cost,则阻止;必须有一个子节点。
  • bandwidth_limit(约束) - 如果当前带宽超过 max_speed(0 表示无限制)或突发超过 max_burst(默认等于 max_speed),则阻止;必须有一个子节点。
  • fair(策略) - 根据最大-最小公平性从其子节点之一选择下一个要服务的请求;子节点可以指定 weight(默认为 1)。
  • priority(策略) - 根据静态优先级从其子节点之一选择下一个要服务的请求(较低的值表示较高的优先级);子节点可以指定 priority(默认为 0)。
  • fifo(队列) - 层次结构的叶子,能够保存超过资源容量的请求。

为了能够使用底层资源的全部容量,您应该使用 inflight_limit。请注意,较低的 max_requestsmax_cost 数量可能会导致资源利用率不充分,而过高的数量可能会导致调度程序内部的队列为空,这反过来会导致子树中的策略被忽略(不公平或忽略优先级)。另一方面,如果您想保护资源免受过高利用率的影响,则应使用 bandwidth_limit。当在 duration 秒内消耗的资源量超过 max_burst + max_speed * duration 字节时,它会进行节流。同一个资源上的两个 bandwidth_limit 节点可用于限制短时间间隔内的峰值带宽和较长时间间隔内的平均带宽。

以下示例显示了如何在图片中定义 IO 调度层次结构

<clickhouse>
<resources>
<network_read>
<node path="/">
<type>inflight_limit</type>
<max_requests>100</max_requests>
</node>
<node path="/fair">
<type>fair</type>
</node>
<node path="/fair/prod">
<type>fifo</type>
<weight>3</weight>
</node>
<node path="/fair/dev">
<type>fifo</type>
</node>
</network_read>
<network_write>
<node path="/">
<type>inflight_limit</type>
<max_requests>100</max_requests>
</node>
<node path="/fair">
<type>fair</type>
</node>
<node path="/fair/prod">
<type>fifo</type>
<weight>3</weight>
</node>
<node path="/fair/dev">
<type>fifo</type>
</node>
</network_write>
</resources>
</clickhouse>

工作负载分类器

工作负载分类器用于定义查询指定的 workload 与应为特定资源使用的叶子队列之间的映射。目前,工作负载分类很简单:仅提供静态映射。

示例

<clickhouse>
<workload_classifiers>
<production>
<network_read>/fair/prod</network_read>
<network_write>/fair/prod</network_write>
</production>
<development>
<network_read>/fair/dev</network_read>
<network_write>/fair/dev</network_write>
</development>
<default>
<network_read>/fair/dev</network_read>
<network_write>/fair/dev</network_write>
</default>
</workload_classifiers>
</clickhouse>

另请参阅