This is an automated email from the ASF dual-hosted git repository. yiguolei pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris-website.git
The following commit(s) were added to refs/heads/master by this push: new 3d153beda23 update workload management sidebar (#1625) 3d153beda23 is described below commit 3d153beda23356af0a32feee26810881ced0f5de Author: wangtianyi2004 <376612...@qq.com> AuthorDate: Thu Dec 26 16:14:41 2024 +0800 update workload management sidebar (#1625) --- .../docusaurus-plugin-content-docs/current.json | 4 + .../concurrency-control-and-queuing.md | 3 +- .../workload-management/sql-blocking.md | 2 +- .../version-2.1.json | 4 + .../concurrency-control-and-queuing.md | 103 +++ .../workload-management/sql-blocking.md | 40 +- .../workload-management/workload-group.md | 723 +++++++++++++++++---- .../version-3.0.json | 4 + .../concurrency-control-and-queuing.md | 103 +++ .../workload-management/sql-blocking.md | 2 +- .../workload-management/workload-group.md | 723 +++++++++++++++++---- sidebars.json | 12 +- versioned_sidebars/version-2.1-sidebars.json | 10 +- versioned_sidebars/version-3.0-sidebars.json | 12 +- 14 files changed, 1456 insertions(+), 289 deletions(-) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current.json b/i18n/zh-CN/docusaurus-plugin-content-docs/current.json index 8e77409a29b..815b73f0407 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current.json +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current.json @@ -223,6 +223,10 @@ "message": "资源管理", "description": "The label for category Managing Resource in sidebar docs" }, + "sidebar.docs.category.Resource Isolation": { + "message": "资源隔离", + "description": "The label for category Resource Isolation in sidebar docs" + }, "sidebar.docs.category.Managing Query": { "message": "查询管理", "description": "The label for category Managing Query in sidebar docs" diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/admin-manual/workload-management/concurrency-control-and-queuing.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/admin-manual/workload-management/concurrency-control-and-queuing.md index 1ca4295aa37..c3212be24df 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/admin-manual/workload-management/concurrency-control-and-queuing.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/admin-manual/workload-management/concurrency-control-and-queuing.md @@ -1,4 +1,3 @@ - --- { "title": "并发控制与排队", @@ -101,4 +100,4 @@ remote_read_bytes_per_second: -1 ``` set bypass_workload_group = true; -``` \ No newline at end of file +``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/admin-manual/workload-management/sql-blocking.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/admin-manual/workload-management/sql-blocking.md index 9d9cafffa08..8da5b0904d8 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/admin-manual/workload-management/sql-blocking.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/admin-manual/workload-management/sql-blocking.md @@ -290,7 +290,7 @@ properties('workload_group'='normal') ### Workload Policy 效果演示 #### 1 session 变量修改测试 -尝试修改 Admin 账户的 Aession 变量中的并发相关的参数 +尝试修改 Admin 账户的 session 变量中的并发相关的参数 ```sql // 登录 admin账户查看并发参数 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1.json index 62b24f3b637..c1dce7a932e 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1.json +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1.json @@ -375,6 +375,10 @@ "message": "负载管理", "description": "The label for category Managing Workload in sidebar docs" }, + "sidebar.docs.category.Resource Isolation": { + "message": "资源隔离", + "description": "The label for category Resource Isolation in sidebar docs" + }, "sidebar.docs.category.Best Practices": { "message": "最佳实践", "description": "The label for category Best Practices in sidebar docs" diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1/admin-manual/workload-management/concurrency-control-and-queuing.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1/admin-manual/workload-management/concurrency-control-and-queuing.md index e69de29bb2d..0fb79f00153 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1/admin-manual/workload-management/concurrency-control-and-queuing.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1/admin-manual/workload-management/concurrency-control-and-queuing.md @@ -0,0 +1,103 @@ +--- +{ +"title": "并发控制与排队", +"language": "zh-CN" +} +--- + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + +并发控制与排队是一种资源管理机制,当多个查询同时请求资源,达到系统并发能力的上限时,Doris 会根据预设的策略和限制条件对查询进行排队管理,确保系统在高负载情况下仍能平稳运行,避免OOM、系统卡死等问题。 + +Doris 的并发控制与排队机制主要通过 workload group 来实现。workload group 定义了查询的资源使用上限,包括最大并发数、排队队列长度和超时时间等参数。通过合理配置这些参数,可以达到资源管控的目的。 + +## 基本使用 + +``` +create workload group if not exists queue_group +properties ( + "max_concurrency" = "10", + "max_queue_size" = "20", + "queue_timeout" = "3000" +); +``` + +**参数说明** + +* max_concurrency:最大查询并发数,默认值为整型最大值,也就是不做并发的限制。运行中的查询数量达到该值时,新来的查询会进入排队的逻辑。 + +* max_queue_size:查询排队队列的长度,当排队队列已满时,新来的查询会被拒绝。默认值为 0,含义是不排队,当查询数达到最大时查询会直接失败。 + +* queue_timeout:查询在排队队列中的超时时间,单位为毫秒,如果查询在队列中的排队时间超过这个值,那么就会直接抛出异常给客户端。默认值为 0,含义是不排队,查询进入队列后立即返回失败。 + + +如果集群中目前有1台FE,那么这个配置的含义为,集群中同时运行的查询数最大不超过10个,当最大并发已满时,新来的查询会排队,队列的长度不超过20。查询在队列中排队的时间最长为3s,排队超过3s的查询会直接返回失败给客户端。 + +:::tip +目前的排队设计是不感知 FE 的个数的,排队的参数只在单 FE 粒度生效,例如: + +一个 Doris 集群配置了一个 work load group,设置 max_concurrency = 1; +如果集群中有 1FE,那么这个 workload group 在 Doris 集群视角看同时只会运行一个 SQL; +如果有 3 台 FE,那么在 Doris 集群视角看最大可运行的 SQL 个数为 3 。 +::: + +## 查看排队状态 + +**语法** + +``` +show workload groups +``` + +**示例** + +``` +mysql [(none)]>show workload groups\G; +*************************** 1. row *************************** + Id: 1 + Name: normal + cpu_share: 20 + memory_limit: 50% + enable_memory_overcommit: true + max_concurrency: 2147483647 + max_queue_size: 0 + queue_timeout: 0 + cpu_hard_limit: 1% + scan_thread_num: 16 + max_remote_scan_thread_num: -1 + min_remote_scan_thread_num: -1 + memory_low_watermark: 50% + memory_high_watermark: 80% + tag: + read_bytes_per_second: -1 +remote_read_bytes_per_second: -1 + running_query_num: 0 + waiting_query_num: 0 +``` + +```running_query_num```代表运行中的查询数量,```waiting_query_num```代表排队中的查询数量 + +## 绕开排队的逻辑 + +在有些运维情况下,管理员账户需要绕开排队的逻辑执行SQL对系统进行一些管理操作,那么可以通过设置session变量,来绕开排队的逻辑: + +``` +set bypass_workload_group = true; +``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1/admin-manual/workload-management/sql-blocking.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1/admin-manual/workload-management/sql-blocking.md index 5ccb2d622ae..8da5b0904d8 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1/admin-manual/workload-management/sql-blocking.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1/admin-manual/workload-management/sql-blocking.md @@ -24,7 +24,7 @@ specific language governing permissions and limitations under the License. --> -查询熔断是一种保护机制,用于防止长时间运行或消耗过多资源的查询对系统产生负面影响。当查询超过预设的资源或时间限制时,熔断机制会自动终止该查询,以避免对系统性能、资源使用以及其他查询造成不利影响。这种机制确保了集群在多用户环境下的稳定性,防止单个查询导致系统资源耗尽、响应变慢或发生死锁,从而提高整体的可用性和效率。 +查询熔断是一种保护机制,用于防止长时间运行或消耗过多资源的查询对系统产生负面影响。当查询超过预设的资源或时间限制时,熔断机制会自动终止该查询,以避免对系统性能、资源使用以及其他查询造成不利影响。这种机制确保了集群在多用户环境下的稳定性,防止单个查询导致系统资源耗尽、响应变慢,从而提高整体的可用性和效率。 在 Doris 内,有两种熔断策略: @@ -213,20 +213,20 @@ A:可以。修改阻止规则,将其属性中的"enable"改为"false"即可 #### Q:阻止规则中的正则表达式使用哪种规范? A:阻止规则的正则表达式使用 java 的正则表达式规范。常用表达式可以参考 SQL 语法手册。完整的手册可以参考 https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html -## Workload Group Policy +## Workload Policy -### 注意事项 -- 同一个 Policy 的 Condition 和 Action 要么都是 FE 的,要么都是 BE 的,比如 set_session_variable 和 cancel_query 无法配置到同一个 Policy 中。Condition be_scan_rows 和 Condition username 无法配置到同一个 Policy 中。 -- 由于目前的 Policy 是异步线程以固定时间间隔执行的,因此策略的生效存在一定的滞后性。比如用户配置了 scan 行数大于 100 万就取消查询的策略,如果此时集群资源比较空闲,那么有可能在取消策略生效之前查询就已经结束了。目前这个时间间隔为 500ms,这意味着运行时间过短的查询可能会绕过策略的检查。 -- 当前支持的负载类型包括 select/insert select/stream load/broker load/routine load。 -- 一个查询可能匹配到多个 Policy,但是只有优先级最高的 Policy 会生效。 -- 目前不支持 Action 和 Condition 的修改,只能通过删除新建的方式修改。 +SQL Block Rule 是一种在规划时进行熔断的配置,但是由于规划中代价的计算可能不准确(尤其是针对一些非常复杂的查询时,更加难以准确估算),所以会导致规则不生效或者误判。Workload Policy 弥补了这个缺陷,它可以在查询运行时对一些指标进行实时的监测,对运行时状态不符合预期的查询进行熔断,避免不符合预期的大查询占用过多资源从而影响集群的稳定性,常用的运行时监控指标如下: -### 熔断策略范围 +* 查询执行时间 +* 查询在单BE上的扫描行数 +* 查询在单BE上的扫描行数扫描字节数 +* 查询的在单BE上的内存使用 + +### 版本说明 自 Doris 2.1 版本起,可以通过 Workload Policy 可以实现大查询的熔断。 -| 版本 | 2.1 | +| 版本 | 2.1 | |--------------------|-----| | select | √ | | insert into select | √ | @@ -234,7 +234,7 @@ A:阻止规则的正则表达式使用 java 的正则表达式规范。常用 | stream load | √ | | routine load | √ | | backup | X | -| compAction | X | +| compaction | X | ### 创建熔断策略 使用 `CREATE WORKLOAD Policy` 命令可以创建资源管理策略。 @@ -249,9 +249,7 @@ properties('enabled'='true'); ``` 在创建 Workload Policy 时需要指定以下内容: - - Conditions 表示策略触发条件,可以多个 Condition 串联,使用逗号“,”隔开,表示“与”的关系。在上例中 query_time > 1000 表示在查询时间大于 1s 时触发 Policy; - - Action 表示条件触发时采取的动作,目前一个 Policy 只能定义一个 Action(除 set_session_variable)。在上例中,cancel_query 表示取消查询; - Properties,定义了当前 Policy 的属性,包括是否启用和优先级。 @@ -282,11 +280,17 @@ Actions(cancel_query) properties('workload_group'='normal') ``` +### 注意事项 +- 同一个 Policy 的 Condition 和 Action 要么都是 FE 的,要么都是 BE 的,比如 set_session_variable 和 cancel_query 无法配置到同一个 Policy 中。Condition be_scan_rows 和 Condition username 无法配置到同一个 Policy 中。 +- 由于目前的 Policy 是异步线程以固定时间间隔执行的,因此策略的生效存在一定的滞后性。比如用户配置了 scan 行数大于 100 万就取消查询的策略,如果此时集群资源比较空闲,那么有可能在取消策略生效之前查询就已经结束了。目前这个时间间隔为 500ms,这意味着运行时间过短的查询可能会绕过策略的检查。 +- 当前支持的负载类型包括 select/insert select/stream load/broker load/routine load。 +- 一个查询可能匹配到多个 Policy,但是只有优先级最高的 Policy 会生效。 +- 目前不支持 Action 和 Condition 的修改,只能通过删除新建的方式修改。 + ### Workload Policy 效果演示 #### 1 session 变量修改测试 - -尝试修改 Admin 账户的 Session 变量中的并发相关的参数 +尝试修改 Admin 账户的 session 变量中的并发相关的参数 ```sql // 登录 admin账户查看并发参数 @@ -314,7 +318,6 @@ mySQL [(none)]>show variables like '%parallel_fragment_exec_instance_num%'; ``` #### 2 大查询熔断测试 - 测试对运行时间超过 3s 的查询进行熔断,以下是一个 ckbench 的 q29 运行成功时的审计日志,可以看到这个 SQL 跑完需要 4.5s 的时间 ```sql @@ -338,7 +341,6 @@ mySQL [hits]>SELECT REGEXP_REPLACE(Referer, '^https?://(?:www\.)?([^/]+)/.*$', ' ``` 创建一个运行时间超过 3s 就取消查询的 Policy - ```sql create workload Policy test_cancel_3s_query Conditions(query_time > 3000) @@ -346,8 +348,8 @@ Actions(cancel_query) ``` 再次执行 SQL 可以看到 SQL 执行会直接报错 - ```sql mySQL [hits]>SELECT REGEXP_REPLACE(Referer, '^https?://(?:www\.)?([^/]+)/.*$', '\1') AS k, AVG(length(Referer)) AS l, COUNT(*) AS c, MIN(Referer) FROM hits WHERE Referer <> '' GROUP BY k HAVING COUNT(*) > 100000 ORDER BY l DESC LIMIT 25; -ERROR 1105 (HY000): errCode = 2, detailMessage = (10.16.10.8)[CANCELLED]query cancelled by workload Policy,id:12345 +ERROR 1105 (HY000): errCode = 2, detailMessage = (127.0.0.1)[CANCELLED]query cancelled by workload Policy,id:12345 ``` + diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1/admin-manual/workload-management/workload-group.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1/admin-manual/workload-management/workload-group.md index cc325ca3290..015490ed518 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1/admin-manual/workload-management/workload-group.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1/admin-manual/workload-management/workload-group.md @@ -24,162 +24,218 @@ specific language governing permissions and limitations under the License. --> -在 Doris 中使用 Workload Group 管理与限制资源。通过资源管控方式可以有效限制查询与导入等负载所用的 CPU、内存与 IO 资源,也可以创建查询队列,控制集群中的查询最大并发量。自 Doris 2.1 版本后,使用基于 CGroup 对 CPU 资源进行限制。在使用 Workload 资源管控功能前,需要先配置 CGroup 环境。在创建 Workload Group 管控资源前,需要根据业务选择对资源进行软限或硬限: +Workload Group 是一种进程内实现的对负载进行逻辑隔离的机制,它通过对BE进程内的资源(CPU,IO,Memory)进行细粒度的划分或者限制,达到资源隔离的目的,它的原理如下图所示: -- 设置资源软限,在没有资源争用时,可以借用其他 Workload Group 资源,超过软限; + -- 设置资源硬限,无论是否存在资源争用,都无法超过硬限设置的资源配额。 - -在使用 Workload 资源管控时,需要执行以下操作: +目前支持的隔离能力包括: -1. 创建 Workload Group; +* 管理CPU资源,支持CPU硬限和CPU软限; +* 管理内存资源,支持内存硬限和内存软限; +* 管理IO资源,包括读本地文件和远程文件产生的IO。 -2. 向 Workload Group 中添加资源限制规则; -3. 为租户绑定 Workload Group。 +## 版本说明 -## 版本升级说明 +- 自 Doris 2.0 版本开始提供 Workload Group 功能。在 Doris 2.0 版本中,Workload Group 功能不依赖于 CGroup,而 Doris 2.1 版本中需要依赖 CGroup。 -自 Doris 2.0 版本开始提供 Workload 资源管控功能。在 Doris 2.0 版本中,Workload 资源管控不依赖于 CGroup,而 Doris 2.1 版本中需要依赖 CGroup。 +- 从 Doris 1.2 升级到 2.0:建议集群升级完成后,再开启 Workload Group功能。只升级部分 follower FE 节点,可能会因为未升级的 FE 节点没有 Workload Group 的元数据信息,导致已升级的 follower FE 节点查询失败。 -- 从 Doris 1.2 升级到 2.0:建议集群升级完成后,再开启 Workload 资源管控功能。只升级部分 follower FE 节点,可能会因为未升级的 FE 节点没有 Workload Group 的元数据信息,导致已升级的 follower FE 节点查询失败。 +- 从 Doris 2.0 升级到 2.1:由于 2.1 版本的 Workload Group 功能依赖于 CGroup,需要先配置 CGroup 环境,再升级到 Doris 2.1 版本。 -- 从 Doris 2.0 升级到 2.1:由于 2.1 版本的 Workload 资源管控功能依赖于 CGroup,需要先配置 CGroup 环境,在升级到 Doris 2.1 版本。 +## 配置workload group -## 配置 CGroup 环境 +### 配置 CGroup 环境 -在 Doris 的 2.0 版本使用基于 Doris 的调度实现 CPU 资源的限制,虽然提供了极大的灵活性,但由于 CPU 的隔离不够精准,无法提供 CPU 的硬隔离限制。从 2.1 版本起,Doris 使用基于 CGroup 对 CPU 资源进行限制,因此建议对资源隔离有强烈需求的用户升级到 2.1 版本,同时在所有 BE 节点上已经安装好 CGroup 的环境。 -用户如果在 2.0 版本使用了 Workload Group 的软限并升级到了 2.1 版本,那么也需要配置 CGroup,否则可能导致软限失效。在不配置 cgroup 的情况下,用户可以使用 Workload Group 除 CPU 限制外的所有功能。 +在使用2.1版本的Workload Group功能之前,需要 BE 所在的节点上已经安装好 CGroup 的环境。 -:::tip -1. Doris BE 节点能够很好的使用机器的 CPU 与内存资源,建议单台机器上只部署一个 BE 实例,目前的 Workload 资源管控不支持一个机器多个 BE 的部署方式; -2. 当机器重启之后,以下的 CGroup 配置就会清空。如果期望配置重启之后可以也可以生效,可以使用 systemd 把操作设置成系统的自定义服务,这样在每次机器重启的时候,自动完成创建和授权操作 -3. 如果是在容器内使用 CGroup,需要容器具备操作宿主机的权限。 -::: +用户如果在 2.0 版本使用了 Workload Group 的软限并升级到了 2.1 版本,那么也需要配置 CGroup,否则可能导致CPU软限失效。 -### 确定 BE 节点安装 CGroup -通过检查 /proc/filesystems 文件可以判断是否安装 CGroup: +目前支持的 CGroup 版本为 CGroup v1 和 CGroup v2。 -``` -cat /proc/filesystems | grep cgroup -nodev cgroup -nodev cgroup2 -nodev cgroupfs -``` +如果是在容器内使用 CGroup,需要容器具备操作宿主机的权限。 -在上述返回结果中,列出了 cgroup,cgroup2 与 cgroupfs,这表明内核支持了 CGroup。还需要进一步查看 CGroup 版本。 +在不配置 CGroup 的情况下,用户可以使用 Workload Group 除 CPU 限制外的所有功能。 -#### 确定 CGroup 版本 -系统使用 CGroup V1,会有多个子系统分别挂在在 /sys/fs/cgroup 目录下。如果包含了 /sys/fs/cgroup/cpu 目录,说明目前生效的是 CGroup V1: +以下为CGroup环境配置流程: +1. 首先确认 BE 所在节点是否已经安装好 GGroup,输出结果中```cgroup``` 代表目前的环境已经安装CGroup V1,```cgroup2``` 代表目前的环境已安装CGroup V2,至于具体是哪个版本生效,可以通过下一步确认。 ```shell -## 包含 /sys/fs/cgroup/cpu 目录,CGroup V1 生效 -ls /sys/fs/cgroup/cpu +cat /proc/filesystems | grep cgroup +nodev cgroup +nodev cgroup2 +nodev cgroupfs ``` -系统使用 CGroup V2,会采用统一的层级结构,所有的控制器都在一个文件系统中管理。如果包含了 /sys/fs/cgroup/cgroup.controllers 目录,则证明目前生效的是 CGroup V2: - +2. 通过路径名称可以确认目前生效的 CGroup 版本。 ```shell -## 包含 /sys/fs/cgroup/cgroup.controllers 目录,CGroup V2 生效 -ls /sys/fs/cgroup/cgroup.controllers +如果存在这个路径说明目前生效的是cgroup v1 +/sys/fs/cgroup/cpu/ + + +如果存在这个路径说明目前生效的是cgroup v2 +/sys/fs/cgroup/cgroup.controllers ``` -在 Doris 中使用 Workload 管控资源,需要针对于 CGroup 的版本分别配置。 -### 使用 CGroup V1 版本 -如果使用 CGroup V1 版本,需要为 Doris 在 /sys/fs/cgroup/cpu 目录下创建 CPU 管控目录。您可以自定义该目录名称,下例中使用 /sys/fs/cgroup/cpu/doris: +3. 在 CGroup 路径下新建一个名为 doris 的目录,这个目录名用户可以自行指定 ```shell -## Create cgroup dir for Doris +如果是cgroup v1就在cpu目录下新建 mkdir /sys/fs/cgroup/cpu/doris -## Modify the Doris cgroup directory permissions -chmod 770 /sys/fs/cgroup/cpu/doris -## Grant user permissions for Doris usage -chown -R doris:doris /sys/fs/cgroup/cpu/doris +如果是cgroup v2就在直接在cgroup目录下新建 +mkdir /sys/fs/cgroup/doris ``` -### 使用 CGroup V2 版本 -因为 CGroup V2 对于权限管控比较严格,需要具备根目录的 cgroup.procs 文件的写权限才能实现进程在 group 之间的移动。 -通过以下命令为 cgroup.procs 目录授权: +4. 需要保证 Doris 的 BE 进程对于这个目录有读/写/执行权限 +```shell +// 如果是CGroup v1,那么命令如下: +// 1. 修改这个目录的权限为可读可写可执行 +chmod 770 /sys/fs/cgroup/cpu/doris +// 2. 把这个目录的归属划分给doris的账户 +chown -R doris:doris /sys/fs/cgroup/cpu/doris + + +// 如果是CGroup v2,那么命令如下: +// 1. 修改这个目录的权限为可读可写可执行 +chmod 770 /sys/fs/cgroup/doris +// 2. 把这个目录的归属划分给doris的账户 +chown -R doris:doris /sys/fs/cgroup/doris +``` +5. 如果目前环境里生效的是CGroup v2版本,那么还需要做以下操作。这是因为CGroup v2对于权限管控比较严格,需要具备根目录的cgroup.procs文件的写权限才能实现进程在group之间的移动。 + 如果是CGroup v1那么不需要这一步。 ```shell chmod a+w /sys/fs/cgroup/cgroup.procs ``` -### 为 BE 节点配置 CGroup 环境 -在使用 Workload 进行资源管控前,需要在 BE 的配置文件 be/conf/be.conf 中配置 CGroup 的路径: -``` +6. 修改 BE 的配置,指定 cgroup 的路径 +```shell +如果是Cgroup v1,那么配置路径如下 doris_cgroup_cpu_path = /sys/fs/cgroup/cpu/doris -``` -在配置 be.conf 文件后,需要重启 BE 节点,在 BE.INFO 日志文件中可以查看到 add thread {pid} to group 提示,表示配置成功。 -## 使用 Workload Group 管理资源 -在创建 Workload Group 后,可以为 Workload Group 添加资源限制规则。Doris 目前支持以下资源的规则限制: +如果是Cgroup v2,那么配置路径如下 +doris_cgroup_cpu_path = /sys/fs/cgroup/doris +``` -- 对 CPU 进行硬限或软限 +7. 重启 BE,在日志(be.INFO)可以看到"add thread xxx to group"的字样代表配置成功 -- 对内存进行硬限或软限 +:::tip +1. 建议单台机器上只部署一个 BE 实例,目前的 Workload Group 功能不支持一个机器上部署多个 BE ; +2. 当机器重启之后,CGroup 路径下的所有配置就会清空。如果期望CGroup配置持久化,可以使用 systemd 把操作设置成系统的自定义服务,这样在每次机器重启的时可以自动完成创建和授权操作 +3. 如果是在容器内使用 CGroup,需要容器具备操作宿主机的权限。 +::: -- 对远程或本地 IO 进行限制 +#### 在容器中使用Workload Group的注意事项 +Workload的CPU管理是基于CGroup实现的,如果期望在容器中使用Workload Group,那么需要以特权模式启动容器,容器内的Doris进程才能具备读写宿主机CGroup文件的权限。 +当Doris在容器内运行时,Workload Group的CPU资源用量是在容器可用资源的情况下再划分的,例如宿主机整机是64核,容器被分配了8个核的资源,Workload Group配置的CPU硬限为50%, +那么Workload Group实际可用核数为4个(8核 * 50%)。 -- 创建查询队列管理查询作业 +WorkloadGroup的内存管理和IO管理功能是Doris内部实现,不依赖外部组件,因此在容器和物理机上部署使用并没有区别。 -### 创建自定义 Workload Group -需要使用具有 ADMIN 权限的用户创建 Workload Group,同时添加资源规则。通过 `CREATE WORKLOAD GROUP` 语句可以创建自定义 Workload Group。自 Doris 2.1 版本起,系统会自动创建名为 Normal 的 Workload Group,用户会默认绑定到 Normal 下。在以下示例中创建了 Workload Group g1,同时添加了 CPU 与内存资源的限制规则: +如果要在K8S上使用Doris,建议使用Doris Operator进行部署,可以屏蔽底层的权限细节问题。 +### 创建Workload Group ``` -CREATE Workload Group IF NOT EXISTS g1 -PROPERTIES( - "cpu_share"="1024", - "memory_limit"="30%" -); +mysql [information_schema]>create workload group if not exists g1 + -> properties ( + -> "cpu_share"="1024" + -> ); +Query OK, 0 rows affected (0.03 sec) + ``` +可以参考 [CREATE-WORKLOAD-GROUP](../../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-WORKLOAD-GROUP)。 -### 修改 Workload Group 的资源规则 +此时配置的 CPU 限制为软限。自 2.1 版本起,系统会自动创建一个名为```normal```的 group,不可删除。 -访问 Doris 系统表 `information_schema.workload_groups` 可以查看创建的 Workload Group 信息。 -删除 Workload Group 可以参考 [DROP WORKLOAD GROUP](../../sql-manual/sql-statements/cluster-management/compute-management/DROP-RESOURCE); -通过 ALTER-WORKLOAD-GROUP 命令可以调整与修改 Workload Group 配置,参考 [ALTER-WORKLOAD-GROUP](../../sql-manual/sql-statements/cluster-management/compute-management/ALTER-WORKLOAD-GROUP.md). +### Workload Group属性 -#### 添加与修改资源项 -在以下示例中,为 g1 资源组修改了内存限制规则: +* cpu_share: 可选,默认值为 -1。有效值的取值范围是正整数。用于设置 workload group 获取 CPU 时间的多少,可以实现 CPU 资源软隔离。cpu_share 是相对值,表示正在运行的 workload group 可获取 CPU 资源的权重。例如,用户创建了 3 个 workload group g-a、g-b 和 g-c,cpu_share 分别为 10、30、40,某一时刻 g-a 和 g-b 正在跑任务,而 g-c 没有任务,此时 g-a 可获得 25% (10 / (10 + 30)) 的 CPU 资源,而 g-b 可获得 75% 的 CPU 资源。如果系统只有一个 workload group 正在运行,则不管其 cpu_share 的值为多少,它都可获取全部的 CPU 资源。 -```sql -ALTER Workload Group g1 PROPERTIES('memory_limit'='10%'); -``` +* memory_limit: 可选,默认值 -1,含义为不限制内存使用。有效值的取值范围 1%~100%,用于设置 workload group 可以使用 be 内存的百分比。Workload Group 可用的最大内存,所有 group 的累加值不可以超过 100%,通常与 enable_memory_overcommit 配合使用。如果一个机器的内存为 64G,mem_limit=50%,那么该 group 的实际物理内存=64G * 90%(be conf mem_limit) * 50%= 28.8G,这里的 90% 是 BE 进程级别的 mem_limit 参数,限制整个 BE 进程的内存用量。一个集群中所有 Workload Group 的 memory_limit 的累加值不能超过 100%。 -通过 information_schema.workload_groups 系统表可以查看到修改后的内存限制: +* enable_memory_overcommit: 可选,用于开启 workload group 内存软隔离,默认为 true。如果设置为 false,则该 workload group 为内存硬隔离,系统检测到 workload group 内存使用超出限制后将立即 cancel 组内内存占用最大的若干个任务,以释放超出的内存;如果设置为 true,则该 workload group 为内存软隔离,如果系统有空闲内存资源则该 workload group 在超出 memory_limit 的限制后可继续使用系统内存,在系统总内存紧张时会 cancel 组内内存占用最大的若干个任务,释放部分超出的内存以缓解系统内存压力。建议在有 workload group 开启该配置时,所有 workload group 的 memory_limit 总和低于 100%,剩余部分用于 workload group 内存超发。 -```sql -SELECT name, memory_limit FROM information_schema.workload_groups; -+--------+--------------+ -| name | memory_limit | -+--------+--------------+ -| normal | 30% | -| g1 | 10% | -+--------+--------------+ +* cpu_hard_limit:可选,默认值 -1,含义为不限制CPU上限。取值范围 1%~100%,CPU 硬限制模式下,Workload Group 最大可用的 CPU 百分比,不管当前机器的 CPU 资源是否被用满,Workload Group 的最大 CPU 用量都不能超过 cpu_hard_limit, + 所有 Workload Group 的 cpu_hard_limit 累加值不能超过 100%。2.1 版本新增属性,2.0版本不支持该功能。 + +* max_concurrency:可选,最大查询并发数,默认值为整型最大值,也就是不做并发的限制。运行中的查询数量达到该值时,新来的查询会进入排队的逻辑。 + +* max_queue_size:可选,查询排队队列的长度,当排队队列已满时,新来的查询会被拒绝。默认值为 0,含义是不排队,当查询数达到最大时查询会直接失败。 + +* queue_timeout:可选,查询在排队队列中的超时时间,单位为毫秒,如果查询在队列中的排队时间超过这个值,那么就会直接抛出异常给客户端。默认值为 0,含义是不排队,查询进入队列后立即返回失败。 + +* scan_thread_num:可选,当前 workload group 用于 scan 的线程个数,默认值为 -1,含义是不生效,此时以 be 配置中的 scan 线程数为准。取值为大于 0 的整数。 + +* max_remote_scan_thread_num:可选,读外部数据源的scan线程池的最大线程数,默认值为-1,当该值为-1时,实际的线程数由BE自行决定,通常和核数相关。 + +* min_remote_scan_thread_num:可选,读外部数据源的scan线程池的最小线程数,默认值为-1,当该值为-1时,实际的线程数由BE自行决定,通常和核数相关。 + +* tag:可选,默认为空,为Workload Group指定标签,相同标签的Workload Group资源累加值不能超过100%,如果期望指定多个值,可以使用英文逗号分隔。 + +* read_bytes_per_second:可选,含义为读Doris内表时的最大IO吞吐,默认值为-1,也就是不限制IO带宽。需要注意的是这个值并不绑定磁盘,而是绑定文件夹。 + 比如为Doris配置了2个文件夹用于存放内表数据,那么每个文件夹的最大读IO不会超过该值,如果这2个文件夹都配置到同一块盘上,最大吞吐控制就会变成2倍的read_bytes_per_second。落盘的文件目录也受该值的约束。 + +* remote_read_bytes_per_second:可选,含义为读Doris外表时的最大IO吞吐,默认值为-1,也就是不限制IO带宽。 + +:::tip + +1. 目前暂不支持 CPU 的软限和硬限的同时使用,一个集群某一时刻只能是软限或者硬限,下文中会描述切换方法。 + +2. 所有属性均为可选,但是在创建 Workload Group 时需要指定至少一个属性。 + +3. 需要注意 CGroup v1 CGroup v2 版本 CPU 软限默认值是有区别的, CGroup v1 的 CPU 软限默认值为1024,取值范围为2到262144。而 CGroup v2 的 CPU 软限默认值为100,取值范围是1到10000。 + 如果软限填了一个超出范围的值,这会导致 CPU 软限在BE修改失败。是在CGroup v1的环境上如果按照CGroup v2的默认值100设置,这可能导致这个workload group的优先级在该机器上是最低的。 + ::: + +## 查看Workload Group +1. 通过show语句查看 +``` +show workload groups; ``` +可以参考[SHOW-WORKLOAD-GROUPS](../../sql-manual/sql-statements/Show-Statements/SHOW-WORKLOAD-GROUPS)。 -#### 配置资源软限与硬限 +2. 通过系统表查看 +``` +mysql [information_schema]>select * from information_schema.workload_groups where name='g1'; ++-------+------+-----------+--------------+--------------------------+-----------------+----------------+---------------+----------------+-----------------+----------------------------+----------------------------+----------------------+-----------------------+------+-----------------------+------------------------------+ +| ID | NAME | CPU_SHARE | MEMORY_LIMIT | ENABLE_MEMORY_OVERCOMMIT | MAX_CONCURRENCY | MAX_QUEUE_SIZE | QUEUE_TIMEOUT | CPU_HARD_LIMIT | SCAN_THREAD_NUM | MAX_REMOTE_SCAN_THREAD_NUM | MIN_REMOTE_SCAN_THREAD_NUM | MEMORY_LOW_WATERMARK | MEMORY_HIGH_WATERMARK | TAG | READ_BYTES_PER_SECOND | REMOTE_READ_BYTES_PER_SECOND | ++-------+------+-----------+--------------+--------------------------+-----------------+----------------+---------------+----------------+-----------------+----------------------------+----------------------------+----------------------+-----------------------+------+-----------------------+------------------------------+ +| 14009 | g1 | 1024 | -1 | true | 2147483647 | 0 | 0 | -1 | -1 | -1 | -1 | 50% | 80% | | -1 | -1 | ++-------+------+-----------+--------------+--------------------------+-----------------+----------------+---------------+----------------+-----------------+----------------------------+----------------------------+----------------------+-----------------------+------+-----------------------+------------------------------+ +1 row in set (0.05 sec) +``` -使用 Workload Group 功能,可以为 CPU 以及内存资源设置软限与硬限,对于远程与本地 IO,只提供硬限能力: +## 修改Workload Group +``` +mysql [information_schema]>alter workload group g1 properties('cpu_share'='2048'); +Query OK, 0 rows affected (0.00 sec -- 软限:软限作为资源的警戒线,用户正常操作中不会超过这个限度。当其他 Workload Group 负载较低时,可以借用其他 Workload Group 资源,超过软限设置; +mysql [information_schema]>select cpu_share from information_schema.workload_groups where name='g1'; ++-----------+ +| cpu_share | ++-----------+ +| 2048 | ++-----------+ +1 row in set (0.02 sec) -- 硬限:硬限作为资源的绝对使用上限,无论其他 Workload Group 是否有负载,都不能超过硬限上限。硬限通常用来防止系统资源被滥用。 +``` -| | 软限开关与参数 | 硬限开关与参数 | 说明 | -| ----------- |----------------------------------------------------------------------|------------------------------------------------------------------------------------|-----| -| CPU | 开关:FE Config - enable_cpu_hard_limit = false 参数:Property - cpu_share | 开关:FE Config - enable_cpu_hard_limit = true <br /> 参数:property - cpu_hard_limit 修改 CPU 硬限 |不同 Workload Group 只能同时设置软限或硬限,无法设置部分组硬限及部分组软限 | -| Memory | 开关:property - enable_memory_overcommit = true <br /> 参数:property - memory_limit | 开关:property - enable_memory_overcommit = false <br /> 参数:property - memory_limit | 不同 Workload Group 可以任意设置软限或硬限,部分组可以设置硬限,部分组可以设置软限 | -| 本地 IO | 无 | 参数:read_bytes_per_second | 暂时只提供本地 IO 硬限 | -| 远程 IO | 无 | 参数:remote_read_bytes_per_second | 暂时只提供远程 IO 硬限 | +可以参考:[ALTER-WORKLOAD-GROUP](../../sql-manual/sql-statements/Data-Definition-Statements/Alter/ALTER-WORKLOAD-GROUP)。 +## 删除Workload Group +``` +mysql [information_schema]>drop workload group g1; +Query OK, 0 rows affected (0.01 sec) +``` -### 为租户绑定 Workload Group +可以参考:[DROP-WORKLOAD-GROUP](../../sql-manual/sql-statements/Data-Definition-Statements/Drop/DROP-WORKLOAD-GROUP)。 -使用非 ADMIN 用户,需要先确定是否具有该 Workload Group 的权限。通过查看 information_schema.workload_groups 系统表判断是否具有使用 Workload Group 的权限。当可以查询到 Workload Group 时,代表具有使用该 Workload Group 的权限。下例中代表可以使用 g1 与 normal Workload Group: +## 为用户设置Workload Group +在把用户绑定到某个Workload Group之前,需要先确定该用户是否具有某个 Workload Group 的权限。 +可以使用这个用户查看 information_schema.workload_groups 系统表,返回的结果就是当前用户有权限使用的Workload Group。 +下面的查询结果代表当前用户可以使用 g1 与 normal Workload Group: ```sql SELECT name FROM information_schema.workload_groups; @@ -191,56 +247,465 @@ SELECT name FROM information_schema.workload_groups; +--------+ ``` -如果无法看到 g1 Workload Group,可以使用 GRANT 语句为用户授权。 -在为租户绑定 Workload Group 时,可以通过设置 user property 或指定 session 变量两种方式。当同时使用了两种方式时,session 变量的优先级要高于 user property: +如果无法看到 g1 Workload Group,可以使用ADMIN账户执行 GRANT 语句为用户授权。例如: +``` +"GRANT USAGE_PRIV ON WORKLOAD GROUP 'g1' TO 'user_1'@'%';" +``` +这个语句的含义是把名为 g1 的 Workload Group的使用权限授予给名为 user_1 的账户。 +更多授权操作可以参考[grant 语句](../../sql-manual/sql-statements/Account-Management-Statements/GRANT)。 + +**两种绑定方式** +1. 通过设置 user property 将 user 默认绑定到 workload group,默认为`normal`,需要注意的这里的value不能填空,否则语句会执行失败,如果不知道要设置哪些group,可以设置为`normal`,`normal`为全局默认的group。 +``` +set property 'default_workload_group' = 'g1'; +``` +执行完该语句后,当前用户的查询将默认使用'g1'。 + + +2. 通过 session 变量指定 workload group, 默认为空: +``` +set workload_group = 'g1'; +``` +当同时使用了两种方式时为用户指定了Workload Group,session 变量的优先级要高于 user property 。 + +## CPU 软硬限模式切换的说明 +目前 Doris 暂不支持同时运行 CPU 的软限和硬限,一个 Doris 集群在任意时刻只能是 CPU 软限或者 CPU 硬限。 +用户可以在两种模式之间进行切换,切换方法如下: + +1 假如当前的集群配置是默认的 CPU 软限,期望改成 CPU 的硬限,需要把 Workload Group 的 cpu_hard_limit 参数修改成一个有效的值 +``` +alter workload group test_group properties ( 'cpu_hard_limit'='20%' ); +``` +集群中所有的Workload Group都需要修改,所有 Workload Group 的 cpu_hard_limit 的累加值不能超过 100% 。 + +由于 CPU 的硬限无法给出一个有效的默认值,因此如果只打开开关但是不修改属性,那么 CPU 的硬限也无法生效。 + +2 在所有 FE 中打开 CPU 硬限的开关 +``` +1 修改磁盘上fe.conf的配置 +experimental_enable_cpu_hard_limit = true +2 修改内存中的配置 +ADMIN SET FRONTEND CONFIG ("enable_cpu_hard_limit" = "true"); +``` + +如果用户期望从 CPU 的硬限切换回 CPU 的软限,需要在所有 FE 修改 enable_cpu_hard_limit 的值为 false 即可。 +CPU 软限的属性 cpu_share 默认会填充一个有效值 1024(如果之前未指定 cpu_share 的值),用户可以根据 group 的优先级对 cpu_share 的值进行重新调整。 + +## 效果测试 +### 内存硬限 +Adhoc 类查询通常输入的 SQL 不确定,使用的内存资源也不确定,因此存在少数查询占用很大内存的风险。 +可以对这类负载可以划分到独立的分组,通过 Workload Group 对内存的硬限的功能,避免突发性的大查询占满所有内存,导致其他查询没有可用内存或者 OOM。 +当这个 Workload Group 的内存使用超过配置的硬限值时,会通过杀死查询的方式释放内存,避免进程内存被打满。 + +**测试环境** + +1FE,1BE,BE 配置为 96 核,内存大小为 375G。 + +测试数据集为 clickbench,测试方法为使用 jmeter 起三并发执行 q29。 + +**测试不开启 Workload Group 的内存硬限** + +1. 查看进程使用内存。ps 命令输出第四列代表进程使用的物理内存的用量,单位为 kb,可以看到当前测试负载下,进程的内存使用为 7.7G 左右。 + + ```sql + [ ~]$ ps -eo pid,comm,%mem,rss | grep 1407481 + 1407481 doris_be 2.0 7896792 + [ ~]$ ps -eo pid,comm,%mem,rss | grep 1407481 + 1407481 doris_be 2.0 7929692 + [ ~]$ ps -eo pid,comm,%mem,rss | grep 1407481 + 1407481 doris_be 2.0 8101232 + ``` + +2. 使用 Doris 系统表查看当前 Workload Group 的内存用量,Workload Group 的内存用量为 5.8G 左右。 + + ```sql + mysql [information_schema]>select MEMORY_USAGE_BYTES / 1024/ 1024 as wg_mem_used_mb from workload_group_resource_usage where workload_group_id=11201; + +-------------------+ + | wg_mem_used_mb | + +-------------------+ + | 5797.524360656738 | + +-------------------+ + 1 row in set (0.01 sec) + + mysql [information_schema]>select MEMORY_USAGE_BYTES / 1024/ 1024 as wg_mem_used_mb from workload_group_resource_usage where workload_group_id=11201; + +-------------------+ + | wg_mem_used_mb | + +-------------------+ + | 5840.246627807617 | + +-------------------+ + 1 row in set (0.02 sec) + + mysql [information_schema]>select MEMORY_USAGE_BYTES / 1024/ 1024 as wg_mem_used_mb from workload_group_resource_usage where workload_group_id=11201; + +-------------------+ + | wg_mem_used_mb | + +-------------------+ + | 5878.394917488098 | + +-------------------+ + 1 row in set (0.02 sec) + ``` + +这里可以看到进程的内存使用通常要远大于一个 Workload Group 的内存用量,即使进程内只有一个 Workload Group 在跑,这是因为 Workload Group 只统计了查询和部分导入的内存,进程内的其他组件比如元数据,各种 Cache 的内存是不计算 Workload Group 内的,也不由 Workload Group 管理。 + +**测试开启 Workload Group 的内存硬限** +1. 执行 SQL 命令修改内存配置。 + + ```sql + alter workload group g2 properties('memory_limit'='0.5%'); + alter workload group g2 properties('enable_memory_overcommit'='false'); + ``` + +2. 执行同样的测试,查看系统表的内存用量,内存用量为 1.5G 左右。 + + ```sql + mysql [information_schema]>select MEMORY_USAGE_BYTES / 1024/ 1024 as wg_mem_used_mb from workload_group_resource_usage where workload_group_id=11201; + +--------------------+ + | wg_mem_used_mb | + +--------------------+ + | 1575.3877239227295 | + +--------------------+ + 1 row in set (0.02 sec) + + mysql [information_schema]>select MEMORY_USAGE_BYTES / 1024/ 1024 as wg_mem_used_mb from workload_group_resource_usage where workload_group_id=11201; + +------------------+ + | wg_mem_used_mb | + +------------------+ + | 1668.77405834198 | + +------------------+ + 1 row in set (0.01 sec) + + mysql [information_schema]>select MEMORY_USAGE_BYTES / 1024/ 1024 as wg_mem_used_mb from workload_group_resource_usage where workload_group_id=11201; + +--------------------+ + | wg_mem_used_mb | + +--------------------+ + | 499.96760272979736 | + +--------------------+ + 1 row in set (0.01 sec) + ``` + +3. 使用 ps 命令查看进程的内存用量,内存用量为 3.8G 左右。 + + ```sql + [ ~]$ ps -eo pid,comm,%mem,rss | grep 1407481 + 1407481 doris_be 1.0 4071364 + [ ~]$ ps -eo pid,comm,%mem,rss | grep 1407481 + 1407481 doris_be 1.0 4059012 + [ ~]$ ps -eo pid,comm,%mem,rss | grep 1407481 + 1407481 doris_be 1.0 4057068 + ``` + +4. 同时客户端会观察到大量由于内存不足导致的查询失败。 + + ```sql + 1724074250162,14126,1c_sql,HY000 1105,"java.sql.SQLException: errCode = 2, detailMessage = (127.0.0.1)[MEM_LIMIT_EXCEEDED]GC wg for hard limit, wg id:11201, name:g2, used:1.71 GB, limit:1.69 GB, backend:10.16.10.8. cancel top memory used tracker <Query#Id=4a0689936c444ac8-a0d01a50b944f6e7> consumption 1.71 GB. details:process memory used 3.01 GB exceed soft limit 304.41 GB or sys available memory 101.16 GB less than warning water mark 12.80 GB., Execute again after enough memory, det [...] + ``` + +这个报错信息中可以看到,Workload Group 使用了 1.7G 的内存,但是 Workload Group 的限制是 1.69G,这里的计算方式是这样的 1.69G = 物理机内存 (375) * mem_limit(be.conf 中的值,默认为 0.9) * 0.5%(Workload Group 的配置) +也就是说,Workload Group 中配置的内存百分比是基于 Doris 进程可用内存再次进行计算的。 + + +**使用建议** + +如上文测试,硬限可以控制 Workload Group 的内存使用,但却是通过杀死查询的方式释放内存,这对用户来说体验会非常不友好,极端情况下可能会导致所有查询都失败。 +因此在生产环境中推荐内存硬限配合查询排队的功能一起使用,可以在限制内存使用的同时保证查询的成功率。 + + + +### CPU 硬限 +Doris 的负载大体可以分为三类: +1. 核心报表查询,通常给公司高层查看报表使用,负载不一定很高,但是对可用性要求较高,这类查询可以划分到一个分组,配置较高优先级的软限,保证 CPU 资源不够时可以获得更多的 CPU 资源。 +2. Adhoc 类查询,这类查询通常偏探索分析,SQL 比较随机,具体的资源用量也比较未知,优先级通常不高。因此可以使用 CPU 硬限进行管理,并配置较低的值,避免占用过多 CPU 资源降低集群可用性。 +3. ETL 类查询,这类查询的 SQL 比较固定,资源用量通常也比较稳定,偶尔会出现上游数据量增长导致资源用量暴涨的情况,因此可以使用 CPU 硬限进行配置。 + +不同的负载对 CPU 的消耗不一样,用户对响应延时的需求也不一样。当 BE 的 CPU 被用的很满时,可用性会变差,响应延时会变高。比如可能一个 Adhoc 的分析类查询把整个集群的 CPU 打满,导致核心报表的延时变大,影响到了 SLA。所以需要 CPU 隔离机制来对不同的业务进行隔离,保障集群的可用性和 SLA。 +Workload Group 支持 CPU 的软限和硬限,目前比较推荐在线上环境把 Workload Group 配置成硬限。原因是 CPU 的软限通常在 CPU 被打满时才能体现出优先级的作用,但是在 CPU 被用满时,Doris 的内部组件(例如 rpc 组件)以及操作系统可用的 CPU 会减少,此时集群整体的可用性是下降比较严重的,因此生产环境通常需要避免 CPU 资源被打满的情况,当然其他资源也一样,内存资源同理。 + + +**测试环境** + +1FE,1BE,96 核机器。 +数据集为 clickbench,测试 sql 为 q29。 + +**发起测试** +1. 使用 jmeter 发起 3 并发查询,把 BE 进程的 CPU 使用压到比较高的使用率,这里测试的机器是 96 核,使用 top 命令看到 BE 进程 CPU 使用率为 7600% 的含义是该进程目前使用中的核数是 76 个。 + +  + +2. 修改使用中的 Workload Group 的 CPU 硬限为 10%。 + + ```sql + alter workload group g2 properties('cpu_hard_limit'='10%'); + ``` + +3. 集群开启硬限模式,此时集群中所有 Group 都会切换为硬限。 + + ```sql + ADMIN SET FRONTEND CONFIG ("enable_cpu_hard_limit" = "true"); + ``` + +4. 重新压测查询负载,可以看到当前进程只能使用 9 到 10 个核,占总核数的 10% 左右。 + +  + +需要注意的是,这里的测试最好使用查询负载会比较能体现出效果,因为如果是高吞吐导入的话,可能会触发 Compaction,使得实际观测的值要比 Workload Group 配置的值大。而 Compaction 的负载目前是没有归入 Workload Group 的管理的。 + +5. 除了使用 Linux 的系统命令外,还可以通过使用 Doris 的系统表观察 Group 目前的 CPU 使用为 10% 左右。 + + ```sql + mysql [information_schema]>select CPU_USAGE_PERCENT from workload_group_resource_usage where WORKLOAD_GROUP_ID=11201; + +-------------------+ + | CPU_USAGE_PERCENT | + +-------------------+ + | 9.57 | + +-------------------+ + 1 row in set (0.02 sec) + ``` + +**注意事项** + +1. 在实际配置的时候,所有 Group 的 CPU 累加值最好不要正好等于 100%,这主要是为了保证低延迟场景的可用性。因为需要让出一部分资源给其他组件使用。当然如果对延迟不是很敏感的场景,期望最高的资源利用率,那么可以考虑所有 Group 的 CPU 累加值配置等于 100%。 +2. 目前 FE 向 BE 同步 Workload Group 元数据的时间间隔为 30 秒,因此对于 Workload Group 的变更最大需要等待 30 秒才能生效。 + + +### 本地IO 硬限 +OLAP 系统在做 ETL 或者大的 Adhoc 查询时,需要读取大量的数据,Doris 为了加速数据分析过程,内部会使用多线程并行的方式对多个磁盘文件扫描,会产生巨大的磁盘 IO,就会对其他的查询(比如报表分析)产生影响。 +可以通过 Workload Group 对离线的 ETL 数据处理和在线的报表查询做分组,限制离线数据处理 IO 带宽的方式,降低它对在线报表分析的影响。 + +**测试环境** + +1FE,1BE, 配置为 96 核。 + +测试数据集为 clickbench。 + +**不开启 IO 硬限测试** +1. 关闭缓存。 -- 使用 user property 绑定 Workload Group:一般由管理员使用 SET-PROPERTY 命令为租户绑定默认的 Workload Group。在以下示例中,为 test_wlg 租户绑定了默认 Workload Group g1: + ```sql + // 清空操作系统缓存 + sync; echo 3 > /proc/sys/vm/drop_caches + + // 禁用 BE 的 page cache + disable_storage_page_cache = true + ``` - ```sql - set property for 'test_wlg' 'default_workload_group' = 'g1'; - ``` +2. 对 clickbench 的表执行全表扫描,执行单并发查询即可。 + + ```sql + set dry_run_query = true; + select * from hits.hits; + ``` -- 使用 session 变量绑定 Workload Group:在业务开发的过程中,即便管理员配置了默认的 Workload Group,也可以在 session 中通过 workload_group 变量修改。在以下示例中,为当前 session 配置了绑定 Workload Group g1: +3. 通过 Doris 的内表查看当前 Group 的最大吞吐为 3GB 每秒。 - ```sql - SET workload_group = 'g1'; - ``` + ```sql + mysql [information_schema]>select LOCAL_SCAN_BYTES_PER_SECOND / 1024 / 1024 as mb_per_sec from workload_group_resource_usage where WORKLOAD_GROUP_ID=11201; + +--------------------+ + | mb_per_sec | + +--------------------+ + | 1146.6208400726318 | + +--------------------+ + 1 row in set (0.03 sec) + + mysql [information_schema]>select LOCAL_SCAN_BYTES_PER_SECOND / 1024 / 1024 as mb_per_sec from workload_group_resource_usage where WORKLOAD_GROUP_ID=11201; + +--------------------+ + | mb_per_sec | + +--------------------+ + | 3496.2762966156006 | + +--------------------+ + 1 row in set (0.04 sec) + + mysql [information_schema]>select LOCAL_SCAN_BYTES_PER_SECOND / 1024 / 1024 as mb_per_sec from workload_group_resource_usage where WORKLOAD_GROUP_ID=11201; + +--------------------+ + | mb_per_sec | + +--------------------+ + | 2192.7690029144287 | + +--------------------+ + 1 row in set (0.02 sec) + ``` -## 为 Workload Group 设置分组 +4. 使用 pidstat 命令查看进程 IO,图中第一列是进程 id,第二列是读 IO 的吞吐(单位是 kb/s)。可以看到不限制 IO 时,最大吞吐为 2G 每秒。 -在多负载或多租户环境中,一个 Doris 集群可能被拆分成多个子集群使用,如部分节点用于外部存储的联邦查询,部分节点用于内表实时查询。Workload Group 可以为 BE 节点打标签(tag),标签相同的 BE 节点组成子集群。每个子集群的资源独立计算,子集群内累加值不能超过 100%。在下例中,将七台机器分成 sub_a 与 sub_b 两个子集群,两个子集群中分别创建了两个 Workload Group。 -在多负载或多租户的环境中,一个 Doris 集群可能被拆分成多个子集群使用,如部分节点用于外部存储的联邦查询,部分节点用于内部表的事实查询,两个自己群在数据分布与资源使用上完全隔离。在同一个子集群群内,需要创建多个租户并创建租户之间的资源使用隔离规则。针对于这类复杂的资源隔离要求,可以结合 Resource Group 与 Workload Group 功能,使用 Resource Group 实现多个子集群的节点粒度隔离,在自己群内使用 Workload Group 进行租户间的资源隔离。如下图中划分成 A、B 两个子集群,每个子集群中有各自的 Workload Group 进行资源管控: +  - -1. 创建 A 与 B 两个 Resource Group,将 7 台机器划分成两个子集群 +**开启 IO 硬限后测试** +1. 关闭缓存。 ```sql - -- create resource group sub_cluster_a - ALTER SYSTEM MODIFY BACKEND "192.168.88.31:9050" SET("tag.location" = "sub_cluster_a"); - ALTER SYSTEM MODIFY BACKEND "192.168.88.32:9050" SET("tag.location" = "sub_cluster_a"); - ALTER SYSTEM MODIFY BACKEND "192.168.88.33:9050" SET("tag.location" = "sub_cluster_a"); + // 清空操作系统缓存 + sync; echo 3 > /proc/sys/vm/drop_caches - -- create resource group sub_cluster_b - ALTER SYSTEM MODIFY BACKEND "192.168.88.34:9050" SET("tag.location" = "sub_cluster_b"); - ALTER SYSTEM MODIFY BACKEND "192.168.88.35:9050" SET("tag.location" = "sub_cluster_b"); + // 禁用 BE 的 page cache + disable_storage_page_cache = true ``` -2. 为子集群创建 Workload Group 进行内存资源隔离 +2. 修改 Workload Group 的配置,限制每秒最大吞吐为 100M。 ```sql - -- create Workload Groups for sub cluster A - CREATE Workload Group a_wlg_1 PROPERTIES('tag' = "sub_cluster_a", "memory_limit" = "30"); - CREATE Workload Group a_wlg_2 PROPERTIES('tag' = "sub_cluster_a", "memory_limit" = "30"); - CREATE Workload Group a_wlg_3 PROPERTIES('tag' = "sub_cluster_a", "memory_limit" = "30"); + // 限制当前 Group 的读吞吐为每秒 100M + alter workload group g2 properties('read_bytes_per_second'='104857600'); + ``` - -- create Workload Groups for sub cluster B - CREATE Workload Group b_wlg_1 PROPERTIES('tag' = "sub_cluster_b", "memory_limit" = "30"); - CREATE Workload Group b_wlg_2 PROPERTIES('tag' = "sub_cluster_b", "memory_limit" = "30"); +3. 使用 Doris 系统表查看 Workload Group 的最大 IO 吞吐为每秒 98M。 + + ```sql + mysql [information_schema]>select LOCAL_SCAN_BYTES_PER_SECOND / 1024 / 1024 as mb_per_sec from workload_group_resource_usage where WORKLOAD_GROUP_ID=11201; + +--------------------+ + | mb_per_sec | + +--------------------+ + | 97.94296646118164 | + +--------------------+ + 1 row in set (0.03 sec) + + mysql [information_schema]>select LOCAL_SCAN_BYTES_PER_SECOND / 1024 / 1024 as mb_per_sec from workload_group_resource_usage where WORKLOAD_GROUP_ID=11201; + +--------------------+ + | mb_per_sec | + +--------------------+ + | 98.37584781646729 | + +--------------------+ + 1 row in set (0.04 sec) + + mysql [information_schema]>select LOCAL_SCAN_BYTES_PER_SECOND / 1024 / 1024 as mb_per_sec from workload_group_resource_usage where WORKLOAD_GROUP_ID=11201; + +--------------------+ + | mb_per_sec | + +--------------------+ + | 98.06641292572021 | + +--------------------+ + 1 row in set (0.02 sec) ``` -## 注意事项 +4. 使用 pid 工具查看进程最大 IO 吞吐为每秒 131M。 + +  + +**注意事项** +1. 系统表中的 LOCAL_SCAN_BYTES_PER_SECOND 字段代表的是当前 Workload Group 在进程粒度的统计汇总值,比如配置了 12 个文件路径,那么 LOCAL_SCAN_BYTES_PER_SECOND 就是这 12 个文件路径 IO 的最大值,如果期望查看每个文件路径分别的 IO 吞吐,可以在 grafana 上或者 BE 的 bvar 监控查看明细的值。 + +2. 由于操作系统和 Doris 的 Page Cache 的存在,通过 linux 的 IO 监控脚本看到的 IO 通常要比系统表看到的要小。 + + +### 远程 IO 硬限 +BrokerLoad 和 S3Load 是常用的大批量数据导入方式,用户可以把数据先上传到 HDFS 或者 S3,然后通过 Brokerload 和 S3Load 对数据进行并行导入。Doris 为了加快导入速度,会使用多线程并行的方式从 HDFS/S3 拉取数据,此时会对 HDFS/S3 产生巨大的压力,会导致 HDFS/S3 上运行的别的作业不稳定。 +可以通过 Workload Group 远程 IO 的限制功能来限制导入过程中对 HDFS/S3 的带宽,降低对其他业务的影响。 + + +**测试环境** + +1FE,1BE 部署在同一台机器,配置为 16 核 64G 内存。测试数据为 clickbench 数据集,测试前需要把数据集上传到 S3 上。考虑到上传时间的问题,我们只取其中的 1 千万行数据上传,然后使用 tvf 的功能查询 s3 的数据。 + +上传成功后可以使用命令查看 Schema 信息。 + + ```sql + // 查看schema + DESC FUNCTION s3 ( + "URI" = "https://bucketname/1kw.tsv", + "s3.access_key"= "ak", + "s3.secret_key" = "sk", + "format" = "csv", + "use_path_style"="true" + ); + ``` + +**测试不限制远程读的 IO** +1. 发起单并发测试,全表扫描 clickbench 表。 + + ```sql + // 设置只 scan 数据,不返回结果 + set dry_run_query = true; + + // 使用 tvf 查询 s3 的数据 + SELECT * FROM s3( + "URI" = "https://bucketname/1kw.tsv", + "s3.access_key"= "ak", + "s3.secret_key" = "sk", + "format" = "csv", + "use_path_style"="true" + ); + ``` + +2. 使用系统表查看此时的远程 IO 吞吐。可以看到这个查询的远程 IO 吞吐为 837M 每秒,需要注意的是,这里的实际 IO 吞吐受环境影响较大,如果 BE 所在的机器连接外部存储的带宽比较低,那么可能实际的吞吐会小。 + + ```sql + MySQL [(none)]> select cast(REMOTE_SCAN_BYTES_PER_SECOND/1024/1024 as int) as read_mb from information_schema.workload_group_resource_usage; + +---------+ + | read_mb | + +---------+ + | 837 | + +---------+ + 1 row in set (0.104 sec) + + MySQL [(none)]> select cast(REMOTE_SCAN_BYTES_PER_SECOND/1024/1024 as int) as read_mb from information_schema.workload_group_resource_usage; + +---------+ + | read_mb | + +---------+ + | 867 | + +---------+ + 1 row in set (0.070 sec) + + MySQL [(none)]> select cast(REMOTE_SCAN_BYTES_PER_SECOND/1024/1024 as int) as read_mb from information_schema.workload_group_resource_usage; + +---------+ + | read_mb | + +---------+ + | 867 | + +---------+ + 1 row in set (0.186 sec) + ``` + +3. 使用 sar(sar -n DEV 1 3600) 命令查看机器的网络带宽,可以看到机器级别最大网络带宽为 1033M 每秒。 + 输出的第一列为当前机器某个网卡每秒接收的字节数,单位为 KB 每秒。 + +  + +**测试限制远程读的 IO** +1. 修改 Workload Group 的配置,限制远程读的 IO 吞吐为 100M 每秒。 + + ```sql + alter workload group normal properties('remote_read_bytes_per_second'='104857600'); + ``` + +2. 发起单并发扫全表的查询。 + + ```sql + // 设置只 scan 数据,不返回结果 + set dry_run_query = true; + + // 使用 tvf 查询 s3 的数据 + SELECT * FROM s3( + "URI" = "https://bucketname/1kw.tsv", + "s3.access_key"= "ak", + "s3.secret_key" = "sk", + "format" = "csv", + "use_path_style"="true" + ); + ``` + +3. 使用系统表查看此时的远程读 IO 吞吐,此时的 IO 吞吐在 100M 左右,会有一定的波动,这个波动是受目前算法设计的影响,通常会有一个高峰,但不会持续很长时间,属于正常情况。 + + ```sql + MySQL [(none)]> select cast(REMOTE_SCAN_BYTES_PER_SECOND/1024/1024 as int) as read_mb from information_schema.workload_group_resource_usage; + +---------+ + | read_mb | + +---------+ + | 56 | + +---------+ + 1 row in set (0.010 sec) + + MySQL [(none)]> select cast(REMOTE_SCAN_BYTES_PER_SECOND/1024/1024 as int) as read_mb from information_schema.workload_group_resource_usage; + +---------+ + | read_mb | + +---------+ + | 131 | + +---------+ + 1 row in set (0.009 sec) + + MySQL [(none)]> select cast(REMOTE_SCAN_BYTES_PER_SECOND/1024/1024 as int) as read_mb from information_schema.workload_group_resource_usage; + +---------+ + | read_mb | + +---------+ + | 111 | + +---------+ + 1 row in set (0.009 sec) + ``` -1. 在 Kubernetes 中使用 Workload 管控资源。Workload 的 CPU 管理是基于 CGroup 实现的,如果期望在容器中使用 Workload Group,那么需要以特权模式启动容器,容器内的 Doris 进程才能具备读写宿主机 CGroup 文件的权限。当 Doris 在容器内运行时,Workload Group 的 CPU 资源用量是在容器可用资源的情况下再划分的,例如宿主机整机是 64 核,容器被分配了 8 个核的资源,Workload Group 配置的 CPU 硬限为 50%,那么 Workload Group 实际可用核数为 4 个(8 核 * 50%)。 +4. 使用 sar 命令(sar -n DEV 1 3600)查看目前的网卡接收流量,第一列为每秒接收的数据量,可以看到最大值变成了 207M 每秒,说明读 IO 的限制是生效的,但是由于 sar 命令看到的是机器级别的流量,因此要比 Doris 统计到的会大一些。 -2. WorkloadGroup 的内存管理和 IO 管理功能是 Doris 内部实现,不依赖外部组件,因此在容器和物理机上部署使用并没有区别。如果要在 K8S 上使用 Doris,建议使用 Doris Operator 进行部署,可以屏蔽底层的权限细节问题。 \ No newline at end of file +  diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.0.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.0.json index 4d5bd7afec6..4a9c9a700ca 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.0.json +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.0.json @@ -595,6 +595,10 @@ "message": "负载管理", "description": "The label for category Managing Workload in sidebar docs" }, + "sidebar.docs.category.Resource Isolation": { + "message": "资源隔离", + "description": "The label for category Resource Isolation in sidebar docs" + }, "sidebar.docs.category.Best Practices": { "message": "最佳实践", "description": "The label for category Best Practices in sidebar docs" diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.0/admin-manual/workload-management/concurrency-control-and-queuing.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.0/admin-manual/workload-management/concurrency-control-and-queuing.md index e69de29bb2d..0fb79f00153 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.0/admin-manual/workload-management/concurrency-control-and-queuing.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.0/admin-manual/workload-management/concurrency-control-and-queuing.md @@ -0,0 +1,103 @@ +--- +{ +"title": "并发控制与排队", +"language": "zh-CN" +} +--- + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + +并发控制与排队是一种资源管理机制,当多个查询同时请求资源,达到系统并发能力的上限时,Doris 会根据预设的策略和限制条件对查询进行排队管理,确保系统在高负载情况下仍能平稳运行,避免OOM、系统卡死等问题。 + +Doris 的并发控制与排队机制主要通过 workload group 来实现。workload group 定义了查询的资源使用上限,包括最大并发数、排队队列长度和超时时间等参数。通过合理配置这些参数,可以达到资源管控的目的。 + +## 基本使用 + +``` +create workload group if not exists queue_group +properties ( + "max_concurrency" = "10", + "max_queue_size" = "20", + "queue_timeout" = "3000" +); +``` + +**参数说明** + +* max_concurrency:最大查询并发数,默认值为整型最大值,也就是不做并发的限制。运行中的查询数量达到该值时,新来的查询会进入排队的逻辑。 + +* max_queue_size:查询排队队列的长度,当排队队列已满时,新来的查询会被拒绝。默认值为 0,含义是不排队,当查询数达到最大时查询会直接失败。 + +* queue_timeout:查询在排队队列中的超时时间,单位为毫秒,如果查询在队列中的排队时间超过这个值,那么就会直接抛出异常给客户端。默认值为 0,含义是不排队,查询进入队列后立即返回失败。 + + +如果集群中目前有1台FE,那么这个配置的含义为,集群中同时运行的查询数最大不超过10个,当最大并发已满时,新来的查询会排队,队列的长度不超过20。查询在队列中排队的时间最长为3s,排队超过3s的查询会直接返回失败给客户端。 + +:::tip +目前的排队设计是不感知 FE 的个数的,排队的参数只在单 FE 粒度生效,例如: + +一个 Doris 集群配置了一个 work load group,设置 max_concurrency = 1; +如果集群中有 1FE,那么这个 workload group 在 Doris 集群视角看同时只会运行一个 SQL; +如果有 3 台 FE,那么在 Doris 集群视角看最大可运行的 SQL 个数为 3 。 +::: + +## 查看排队状态 + +**语法** + +``` +show workload groups +``` + +**示例** + +``` +mysql [(none)]>show workload groups\G; +*************************** 1. row *************************** + Id: 1 + Name: normal + cpu_share: 20 + memory_limit: 50% + enable_memory_overcommit: true + max_concurrency: 2147483647 + max_queue_size: 0 + queue_timeout: 0 + cpu_hard_limit: 1% + scan_thread_num: 16 + max_remote_scan_thread_num: -1 + min_remote_scan_thread_num: -1 + memory_low_watermark: 50% + memory_high_watermark: 80% + tag: + read_bytes_per_second: -1 +remote_read_bytes_per_second: -1 + running_query_num: 0 + waiting_query_num: 0 +``` + +```running_query_num```代表运行中的查询数量,```waiting_query_num```代表排队中的查询数量 + +## 绕开排队的逻辑 + +在有些运维情况下,管理员账户需要绕开排队的逻辑执行SQL对系统进行一些管理操作,那么可以通过设置session变量,来绕开排队的逻辑: + +``` +set bypass_workload_group = true; +``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.0/admin-manual/workload-management/sql-blocking.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.0/admin-manual/workload-management/sql-blocking.md index e3bcce313a6..60a619ef6d3 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.0/admin-manual/workload-management/sql-blocking.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.0/admin-manual/workload-management/sql-blocking.md @@ -283,7 +283,7 @@ properties('workload_group'='normal') ### Workload Policy 效果演示 #### 1 session 变量修改测试 -尝试修改 Admin 账户的 Aession 变量中的并发相关的参数 +尝试修改 Admin 账户的 session 变量中的并发相关的参数 ```sql // 登录 admin账户查看并发参数 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.0/admin-manual/workload-management/workload-group.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.0/admin-manual/workload-management/workload-group.md index 8bf5b88299c..015490ed518 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.0/admin-manual/workload-management/workload-group.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.0/admin-manual/workload-management/workload-group.md @@ -24,162 +24,218 @@ specific language governing permissions and limitations under the License. --> -在 Doris 中使用 Workload Group 管理与限制资源。通过资源管控方式可以有效限制查询与导入等负载所用的 CPU、内存与 IO 资源,也可以创建查询队列,控制集群中的查询最大并发量。自 Doris 2.1 版本后,使用基于 CGroup 对 CPU 资源进行限制。在使用 Workload 资源管控功能前,需要先配置 CGroup 环境。在创建 Workload Group 管控资源前,需要根据业务选择对资源进行软限或硬限: +Workload Group 是一种进程内实现的对负载进行逻辑隔离的机制,它通过对BE进程内的资源(CPU,IO,Memory)进行细粒度的划分或者限制,达到资源隔离的目的,它的原理如下图所示: -- 设置资源软限,在没有资源争用时,可以借用其他 Workload Group 资源,超过软限; + -- 设置资源硬限,无论是否存在资源争用,都无法超过硬限设置的资源配额。 - -在使用 Workload 资源管控时,需要执行以下操作: +目前支持的隔离能力包括: -1. 创建 Workload Group; +* 管理CPU资源,支持CPU硬限和CPU软限; +* 管理内存资源,支持内存硬限和内存软限; +* 管理IO资源,包括读本地文件和远程文件产生的IO。 -2. 向 Workload Group 中添加资源限制规则; -3. 为租户绑定 Workload Group。 +## 版本说明 -## 版本升级说明 +- 自 Doris 2.0 版本开始提供 Workload Group 功能。在 Doris 2.0 版本中,Workload Group 功能不依赖于 CGroup,而 Doris 2.1 版本中需要依赖 CGroup。 -自 Doris 2.0 版本开始提供 Workload 资源管控功能。在 Doris 2.0 版本中,Workload 资源管控不依赖于 CGroup,而 Doris 2.1 版本中需要依赖 CGroup。 +- 从 Doris 1.2 升级到 2.0:建议集群升级完成后,再开启 Workload Group功能。只升级部分 follower FE 节点,可能会因为未升级的 FE 节点没有 Workload Group 的元数据信息,导致已升级的 follower FE 节点查询失败。 -- 从 Doris 1.2 升级到 2.0:建议集群升级完成后,再开启 Workload 资源管控功能。只升级部分 follower FE 节点,可能会因为未升级的 FE 节点没有 Workload Group 的元数据信息,导致已升级的 follower FE 节点查询失败。 +- 从 Doris 2.0 升级到 2.1:由于 2.1 版本的 Workload Group 功能依赖于 CGroup,需要先配置 CGroup 环境,再升级到 Doris 2.1 版本。 -- 从 Doris 2.0 升级到 2.1:由于 2.1 版本的 Workload 资源管控功能依赖于 CGroup,需要先配置 CGroup 环境,在升级到 Doris 2.1 版本。 +## 配置workload group -## 配置 CGroup 环境 +### 配置 CGroup 环境 -在 Doris 的 2.0 版本使用基于 Doris 的调度实现 CPU 资源的限制,虽然提供了极大的灵活性,但由于 CPU 的隔离不够精准,无法提供 CPU 的硬隔离限制。从 2.1 版本起,Doris 使用基于 CGroup 对 CPU 资源进行限制,因此建议对资源隔离有强烈需求的用户升级到 2.1 版本,同时在所有 BE 节点上已经安装好 CGroup 的环境。 -用户如果在 2.0 版本使用了 Workload Group 的软限并升级到了 2.1 版本,那么也需要配置 CGroup,否则可能导致软限失效。在不配置 cgroup 的情况下,用户可以使用 Workload Group 除 CPU 限制外的所有功能。 +在使用2.1版本的Workload Group功能之前,需要 BE 所在的节点上已经安装好 CGroup 的环境。 -:::tip -1. Doris BE 节点能够很好的使用机器的 CPU 与内存资源,建议单台机器上只部署一个 BE 实例,目前的 Workload 资源管控不支持一个机器多个 BE 的部署方式; -2. 当机器重启之后,以下的 CGroup 配置就会清空。如果期望配置重启之后可以也可以生效,可以使用 systemd 把操作设置成系统的自定义服务,这样在每次机器重启的时候,自动完成创建和授权操作 -3. 如果是在容器内使用 CGroup,需要容器具备操作宿主机的权限。 -::: +用户如果在 2.0 版本使用了 Workload Group 的软限并升级到了 2.1 版本,那么也需要配置 CGroup,否则可能导致CPU软限失效。 -### 确定 BE 节点安装 CGroup -通过检查 /proc/filesystems 文件可以判断是否安装 CGroup: +目前支持的 CGroup 版本为 CGroup v1 和 CGroup v2。 -``` -cat /proc/filesystems | grep cgroup -nodev cgroup -nodev cgroup2 -nodev cgroupfs -``` +如果是在容器内使用 CGroup,需要容器具备操作宿主机的权限。 -在上述返回结果中,列出了 cgroup,cgroup2 与 cgroupfs,这表明内核支持了 CGroup。还需要进一步查看 CGroup 版本。 +在不配置 CGroup 的情况下,用户可以使用 Workload Group 除 CPU 限制外的所有功能。 -#### 确定 CGroup 版本 -系统使用 CGroup V1,会有多个子系统分别挂在在 /sys/fs/cgroup 目录下。如果包含了 /sys/fs/cgroup/cpu 目录,说明目前生效的是 CGroup V1: +以下为CGroup环境配置流程: +1. 首先确认 BE 所在节点是否已经安装好 GGroup,输出结果中```cgroup``` 代表目前的环境已经安装CGroup V1,```cgroup2``` 代表目前的环境已安装CGroup V2,至于具体是哪个版本生效,可以通过下一步确认。 ```shell -## 包含 /sys/fs/cgroup/cpu 目录,CGroup V1 生效 -ls /sys/fs/cgroup/cpu +cat /proc/filesystems | grep cgroup +nodev cgroup +nodev cgroup2 +nodev cgroupfs ``` -系统使用 CGroup V2,会采用统一的层级结构,所有的控制器都在一个文件系统中管理。如果包含了 /sys/fs/cgroup/cgroup.controllers 目录,则证明目前生效的是 CGroup V2: - +2. 通过路径名称可以确认目前生效的 CGroup 版本。 ```shell -## 包含 /sys/fs/cgroup/cgroup.controllers 目录,CGroup V2 生效 -ls /sys/fs/cgroup/cgroup.controllers +如果存在这个路径说明目前生效的是cgroup v1 +/sys/fs/cgroup/cpu/ + + +如果存在这个路径说明目前生效的是cgroup v2 +/sys/fs/cgroup/cgroup.controllers ``` -在 Doris 中使用 Workload 管控资源,需要针对于 CGroup 的版本分别配置。 -### 使用 CGroup V1 版本 -如果使用 CGroup V1 版本,需要为 Doris 在 /sys/fs/cgroup/cpu 目录下创建 CPU 管控目录。您可以自定义该目录名称,下例中使用 /sys/fs/cgroup/cpu/doris: +3. 在 CGroup 路径下新建一个名为 doris 的目录,这个目录名用户可以自行指定 ```shell -## Create cgroup dir for Doris +如果是cgroup v1就在cpu目录下新建 mkdir /sys/fs/cgroup/cpu/doris -## Modify the Doris cgroup directory permissions -chmod 770 /sys/fs/cgroup/cpu/doris -## Grant user permissions for Doris usage -chown -R doris:doris /sys/fs/cgroup/cpu/doris +如果是cgroup v2就在直接在cgroup目录下新建 +mkdir /sys/fs/cgroup/doris ``` -### 使用 CGroup V2 版本 -因为 CGroup V2 对于权限管控比较严格,需要具备根目录的 cgroup.procs 文件的写权限才能实现进程在 group 之间的移动。 -通过以下命令为 cgroup.procs 目录授权: +4. 需要保证 Doris 的 BE 进程对于这个目录有读/写/执行权限 +```shell +// 如果是CGroup v1,那么命令如下: +// 1. 修改这个目录的权限为可读可写可执行 +chmod 770 /sys/fs/cgroup/cpu/doris +// 2. 把这个目录的归属划分给doris的账户 +chown -R doris:doris /sys/fs/cgroup/cpu/doris + + +// 如果是CGroup v2,那么命令如下: +// 1. 修改这个目录的权限为可读可写可执行 +chmod 770 /sys/fs/cgroup/doris +// 2. 把这个目录的归属划分给doris的账户 +chown -R doris:doris /sys/fs/cgroup/doris +``` +5. 如果目前环境里生效的是CGroup v2版本,那么还需要做以下操作。这是因为CGroup v2对于权限管控比较严格,需要具备根目录的cgroup.procs文件的写权限才能实现进程在group之间的移动。 + 如果是CGroup v1那么不需要这一步。 ```shell chmod a+w /sys/fs/cgroup/cgroup.procs ``` -### 为 BE 节点配置 CGroup 环境 -在使用 Workload 进行资源管控前,需要在 BE 的配置文件 be/conf/be.conf 中配置 CGroup 的路径: -``` +6. 修改 BE 的配置,指定 cgroup 的路径 +```shell +如果是Cgroup v1,那么配置路径如下 doris_cgroup_cpu_path = /sys/fs/cgroup/cpu/doris -``` -在配置 be.conf 文件后,需要重启 BE 节点,在 BE.INFO 日志文件中可以查看到 add thread {pid} to group 提示,表示配置成功。 -## 使用 Workload Group 管理资源 -在创建 Workload Group 后,可以为 Workload Group 添加资源限制规则。Doris 目前支持以下资源的规则限制: +如果是Cgroup v2,那么配置路径如下 +doris_cgroup_cpu_path = /sys/fs/cgroup/doris +``` -- 对 CPU 进行硬限或软限 +7. 重启 BE,在日志(be.INFO)可以看到"add thread xxx to group"的字样代表配置成功 -- 对内存进行硬限或软限 +:::tip +1. 建议单台机器上只部署一个 BE 实例,目前的 Workload Group 功能不支持一个机器上部署多个 BE ; +2. 当机器重启之后,CGroup 路径下的所有配置就会清空。如果期望CGroup配置持久化,可以使用 systemd 把操作设置成系统的自定义服务,这样在每次机器重启的时可以自动完成创建和授权操作 +3. 如果是在容器内使用 CGroup,需要容器具备操作宿主机的权限。 +::: -- 对远程或本地 IO 进行限制 +#### 在容器中使用Workload Group的注意事项 +Workload的CPU管理是基于CGroup实现的,如果期望在容器中使用Workload Group,那么需要以特权模式启动容器,容器内的Doris进程才能具备读写宿主机CGroup文件的权限。 +当Doris在容器内运行时,Workload Group的CPU资源用量是在容器可用资源的情况下再划分的,例如宿主机整机是64核,容器被分配了8个核的资源,Workload Group配置的CPU硬限为50%, +那么Workload Group实际可用核数为4个(8核 * 50%)。 -- 创建查询队列管理查询作业 +WorkloadGroup的内存管理和IO管理功能是Doris内部实现,不依赖外部组件,因此在容器和物理机上部署使用并没有区别。 -### 创建自定义 Workload Group -需要使用具有 ADMIN 权限的用户创建 Workload Group,同时添加资源规则。通过 `CREATE WORKLOAD GROUP` 语句可以创建自定义 Workload Group。自 Doris 2.1 版本起,系统会自动创建名为 Normal 的 Workload Group,用户会默认绑定到 Normal 下。在以下示例中创建了 Workload Group g1,同时添加了 CPU 与内存资源的限制规则: +如果要在K8S上使用Doris,建议使用Doris Operator进行部署,可以屏蔽底层的权限细节问题。 +### 创建Workload Group ``` -CREATE Workload Group IF NOT EXISTS g1 -PROPERTIES( - "cpu_share"="1024", - "memory_limit"="30%" -); +mysql [information_schema]>create workload group if not exists g1 + -> properties ( + -> "cpu_share"="1024" + -> ); +Query OK, 0 rows affected (0.03 sec) + ``` +可以参考 [CREATE-WORKLOAD-GROUP](../../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-WORKLOAD-GROUP)。 -### 修改 Workload Group 的资源规则 +此时配置的 CPU 限制为软限。自 2.1 版本起,系统会自动创建一个名为```normal```的 group,不可删除。 -访问 Doris 系统表 `information_schema.workload_groups` 可以查看创建的 Workload Group 信息。 -删除 Workload Group 可以参考 [DROP WORKLOAD GROUP](../../sql-manual/sql-statements/cluster-management/compute-management/DROP-RESOURCE); -通过 ALTER-WORKLOAD-GROUP 命令可以调整与修改 Workload Group 配置,参考 [ALTER-WORKLOAD-GROUP](../../sql-manual/sql-statements/cluster-management/compute-management/ALTER-WORKLOAD-GROUP.md). +### Workload Group属性 -#### 添加与修改资源项 -在以下示例中,为 g1 资源组修改了内存限制规则: +* cpu_share: 可选,默认值为 -1。有效值的取值范围是正整数。用于设置 workload group 获取 CPU 时间的多少,可以实现 CPU 资源软隔离。cpu_share 是相对值,表示正在运行的 workload group 可获取 CPU 资源的权重。例如,用户创建了 3 个 workload group g-a、g-b 和 g-c,cpu_share 分别为 10、30、40,某一时刻 g-a 和 g-b 正在跑任务,而 g-c 没有任务,此时 g-a 可获得 25% (10 / (10 + 30)) 的 CPU 资源,而 g-b 可获得 75% 的 CPU 资源。如果系统只有一个 workload group 正在运行,则不管其 cpu_share 的值为多少,它都可获取全部的 CPU 资源。 -```sql -ALTER Workload Group g1 PROPERTIES('memory_limit'='10%'); -``` +* memory_limit: 可选,默认值 -1,含义为不限制内存使用。有效值的取值范围 1%~100%,用于设置 workload group 可以使用 be 内存的百分比。Workload Group 可用的最大内存,所有 group 的累加值不可以超过 100%,通常与 enable_memory_overcommit 配合使用。如果一个机器的内存为 64G,mem_limit=50%,那么该 group 的实际物理内存=64G * 90%(be conf mem_limit) * 50%= 28.8G,这里的 90% 是 BE 进程级别的 mem_limit 参数,限制整个 BE 进程的内存用量。一个集群中所有 Workload Group 的 memory_limit 的累加值不能超过 100%。 -通过 information_schema.workload_groups 系统表可以查看到修改后的内存限制: +* enable_memory_overcommit: 可选,用于开启 workload group 内存软隔离,默认为 true。如果设置为 false,则该 workload group 为内存硬隔离,系统检测到 workload group 内存使用超出限制后将立即 cancel 组内内存占用最大的若干个任务,以释放超出的内存;如果设置为 true,则该 workload group 为内存软隔离,如果系统有空闲内存资源则该 workload group 在超出 memory_limit 的限制后可继续使用系统内存,在系统总内存紧张时会 cancel 组内内存占用最大的若干个任务,释放部分超出的内存以缓解系统内存压力。建议在有 workload group 开启该配置时,所有 workload group 的 memory_limit 总和低于 100%,剩余部分用于 workload group 内存超发。 -```sql -SELECT name, memory_limit FROM information_schema.workload_groups; -+--------+--------------+ -| name | memory_limit | -+--------+--------------+ -| normal | 30% | -| g1 | 10% | -+--------+--------------+ +* cpu_hard_limit:可选,默认值 -1,含义为不限制CPU上限。取值范围 1%~100%,CPU 硬限制模式下,Workload Group 最大可用的 CPU 百分比,不管当前机器的 CPU 资源是否被用满,Workload Group 的最大 CPU 用量都不能超过 cpu_hard_limit, + 所有 Workload Group 的 cpu_hard_limit 累加值不能超过 100%。2.1 版本新增属性,2.0版本不支持该功能。 + +* max_concurrency:可选,最大查询并发数,默认值为整型最大值,也就是不做并发的限制。运行中的查询数量达到该值时,新来的查询会进入排队的逻辑。 + +* max_queue_size:可选,查询排队队列的长度,当排队队列已满时,新来的查询会被拒绝。默认值为 0,含义是不排队,当查询数达到最大时查询会直接失败。 + +* queue_timeout:可选,查询在排队队列中的超时时间,单位为毫秒,如果查询在队列中的排队时间超过这个值,那么就会直接抛出异常给客户端。默认值为 0,含义是不排队,查询进入队列后立即返回失败。 + +* scan_thread_num:可选,当前 workload group 用于 scan 的线程个数,默认值为 -1,含义是不生效,此时以 be 配置中的 scan 线程数为准。取值为大于 0 的整数。 + +* max_remote_scan_thread_num:可选,读外部数据源的scan线程池的最大线程数,默认值为-1,当该值为-1时,实际的线程数由BE自行决定,通常和核数相关。 + +* min_remote_scan_thread_num:可选,读外部数据源的scan线程池的最小线程数,默认值为-1,当该值为-1时,实际的线程数由BE自行决定,通常和核数相关。 + +* tag:可选,默认为空,为Workload Group指定标签,相同标签的Workload Group资源累加值不能超过100%,如果期望指定多个值,可以使用英文逗号分隔。 + +* read_bytes_per_second:可选,含义为读Doris内表时的最大IO吞吐,默认值为-1,也就是不限制IO带宽。需要注意的是这个值并不绑定磁盘,而是绑定文件夹。 + 比如为Doris配置了2个文件夹用于存放内表数据,那么每个文件夹的最大读IO不会超过该值,如果这2个文件夹都配置到同一块盘上,最大吞吐控制就会变成2倍的read_bytes_per_second。落盘的文件目录也受该值的约束。 + +* remote_read_bytes_per_second:可选,含义为读Doris外表时的最大IO吞吐,默认值为-1,也就是不限制IO带宽。 + +:::tip + +1. 目前暂不支持 CPU 的软限和硬限的同时使用,一个集群某一时刻只能是软限或者硬限,下文中会描述切换方法。 + +2. 所有属性均为可选,但是在创建 Workload Group 时需要指定至少一个属性。 + +3. 需要注意 CGroup v1 CGroup v2 版本 CPU 软限默认值是有区别的, CGroup v1 的 CPU 软限默认值为1024,取值范围为2到262144。而 CGroup v2 的 CPU 软限默认值为100,取值范围是1到10000。 + 如果软限填了一个超出范围的值,这会导致 CPU 软限在BE修改失败。是在CGroup v1的环境上如果按照CGroup v2的默认值100设置,这可能导致这个workload group的优先级在该机器上是最低的。 + ::: + +## 查看Workload Group +1. 通过show语句查看 +``` +show workload groups; ``` +可以参考[SHOW-WORKLOAD-GROUPS](../../sql-manual/sql-statements/Show-Statements/SHOW-WORKLOAD-GROUPS)。 -#### 配置资源软限与硬限 +2. 通过系统表查看 +``` +mysql [information_schema]>select * from information_schema.workload_groups where name='g1'; ++-------+------+-----------+--------------+--------------------------+-----------------+----------------+---------------+----------------+-----------------+----------------------------+----------------------------+----------------------+-----------------------+------+-----------------------+------------------------------+ +| ID | NAME | CPU_SHARE | MEMORY_LIMIT | ENABLE_MEMORY_OVERCOMMIT | MAX_CONCURRENCY | MAX_QUEUE_SIZE | QUEUE_TIMEOUT | CPU_HARD_LIMIT | SCAN_THREAD_NUM | MAX_REMOTE_SCAN_THREAD_NUM | MIN_REMOTE_SCAN_THREAD_NUM | MEMORY_LOW_WATERMARK | MEMORY_HIGH_WATERMARK | TAG | READ_BYTES_PER_SECOND | REMOTE_READ_BYTES_PER_SECOND | ++-------+------+-----------+--------------+--------------------------+-----------------+----------------+---------------+----------------+-----------------+----------------------------+----------------------------+----------------------+-----------------------+------+-----------------------+------------------------------+ +| 14009 | g1 | 1024 | -1 | true | 2147483647 | 0 | 0 | -1 | -1 | -1 | -1 | 50% | 80% | | -1 | -1 | ++-------+------+-----------+--------------+--------------------------+-----------------+----------------+---------------+----------------+-----------------+----------------------------+----------------------------+----------------------+-----------------------+------+-----------------------+------------------------------+ +1 row in set (0.05 sec) +``` -使用 Workload Group 功能,可以为 CPU 以及内存资源设置软限与硬限,对于远程与本地 IO,只提供硬限能力: +## 修改Workload Group +``` +mysql [information_schema]>alter workload group g1 properties('cpu_share'='2048'); +Query OK, 0 rows affected (0.00 sec -- 软限:软限作为资源的警戒线,用户正常操作中不会超过这个限度。当其他 Workload Group 负载较低时,可以借用其他 Workload Group 资源,超过软限设置; +mysql [information_schema]>select cpu_share from information_schema.workload_groups where name='g1'; ++-----------+ +| cpu_share | ++-----------+ +| 2048 | ++-----------+ +1 row in set (0.02 sec) -- 硬限:硬限作为资源的绝对使用上限,无论其他 Workload Group 是否有负载,都不能超过硬限上限。硬限通常用来防止系统资源被滥用。 +``` -| | 软限开关与参数 | 硬限开关与参数 | 说明 | -| ----------- |----------------------------------------------------------------------|------------------------------------------------------------------------------------|-----| -| CPU | 开关:FE Config - enable_cpu_hard_limit = false 参数:Property - cpu_share | 开关:FE Config - enable_cpu_hard_limit = true <br /> 参数:property - cpu_hard_limit 修改 CPU 硬限 |不同 Workload Group 只能同时设置软限或硬限,无法设置部分组硬限及部分组软限 | -| Memory | 开关:property - enable_memory_overcommit = true <br /> 参数:property - memory_limit | 开关:property - enable_memory_overcommit = false <br /> 参数:property - memory_limit | 不同 Workload Group 可以任意设置软限或硬限,部分组可以设置硬限,部分组可以设置软限 | -| 本地 IO | 无 | 参数:read_bytes_per_second | 暂时只提供本地 IO 硬限 | -| 远程 IO | 无 | 参数:remote_read_bytes_per_second | 暂时只提供远程 IO 硬限 | +可以参考:[ALTER-WORKLOAD-GROUP](../../sql-manual/sql-statements/Data-Definition-Statements/Alter/ALTER-WORKLOAD-GROUP)。 +## 删除Workload Group +``` +mysql [information_schema]>drop workload group g1; +Query OK, 0 rows affected (0.01 sec) +``` -### 为租户绑定 Workload Group +可以参考:[DROP-WORKLOAD-GROUP](../../sql-manual/sql-statements/Data-Definition-Statements/Drop/DROP-WORKLOAD-GROUP)。 -使用非 ADMIN 用户,需要先确定是否具有该 Workload Group 的权限。通过查看 information_schema.workload_groups 系统表判断是否具有使用 Workload Group 的权限。当可以查询到 Workload Group 时,代表具有使用该 Workload Group 的权限。下例中代表可以使用 g1 与 normal Workload Group: +## 为用户设置Workload Group +在把用户绑定到某个Workload Group之前,需要先确定该用户是否具有某个 Workload Group 的权限。 +可以使用这个用户查看 information_schema.workload_groups 系统表,返回的结果就是当前用户有权限使用的Workload Group。 +下面的查询结果代表当前用户可以使用 g1 与 normal Workload Group: ```sql SELECT name FROM information_schema.workload_groups; @@ -191,56 +247,465 @@ SELECT name FROM information_schema.workload_groups; +--------+ ``` -如果无法看到 g1 Workload Group,可以使用 GRANT 语句为用户授权。 -在为租户绑定 Workload Group 时,可以通过设置 user property 或指定 session 变量两种方式。当同时使用了两种方式时,session 变量的优先级要高于 user property: +如果无法看到 g1 Workload Group,可以使用ADMIN账户执行 GRANT 语句为用户授权。例如: +``` +"GRANT USAGE_PRIV ON WORKLOAD GROUP 'g1' TO 'user_1'@'%';" +``` +这个语句的含义是把名为 g1 的 Workload Group的使用权限授予给名为 user_1 的账户。 +更多授权操作可以参考[grant 语句](../../sql-manual/sql-statements/Account-Management-Statements/GRANT)。 + +**两种绑定方式** +1. 通过设置 user property 将 user 默认绑定到 workload group,默认为`normal`,需要注意的这里的value不能填空,否则语句会执行失败,如果不知道要设置哪些group,可以设置为`normal`,`normal`为全局默认的group。 +``` +set property 'default_workload_group' = 'g1'; +``` +执行完该语句后,当前用户的查询将默认使用'g1'。 + + +2. 通过 session 变量指定 workload group, 默认为空: +``` +set workload_group = 'g1'; +``` +当同时使用了两种方式时为用户指定了Workload Group,session 变量的优先级要高于 user property 。 + +## CPU 软硬限模式切换的说明 +目前 Doris 暂不支持同时运行 CPU 的软限和硬限,一个 Doris 集群在任意时刻只能是 CPU 软限或者 CPU 硬限。 +用户可以在两种模式之间进行切换,切换方法如下: + +1 假如当前的集群配置是默认的 CPU 软限,期望改成 CPU 的硬限,需要把 Workload Group 的 cpu_hard_limit 参数修改成一个有效的值 +``` +alter workload group test_group properties ( 'cpu_hard_limit'='20%' ); +``` +集群中所有的Workload Group都需要修改,所有 Workload Group 的 cpu_hard_limit 的累加值不能超过 100% 。 + +由于 CPU 的硬限无法给出一个有效的默认值,因此如果只打开开关但是不修改属性,那么 CPU 的硬限也无法生效。 + +2 在所有 FE 中打开 CPU 硬限的开关 +``` +1 修改磁盘上fe.conf的配置 +experimental_enable_cpu_hard_limit = true +2 修改内存中的配置 +ADMIN SET FRONTEND CONFIG ("enable_cpu_hard_limit" = "true"); +``` + +如果用户期望从 CPU 的硬限切换回 CPU 的软限,需要在所有 FE 修改 enable_cpu_hard_limit 的值为 false 即可。 +CPU 软限的属性 cpu_share 默认会填充一个有效值 1024(如果之前未指定 cpu_share 的值),用户可以根据 group 的优先级对 cpu_share 的值进行重新调整。 + +## 效果测试 +### 内存硬限 +Adhoc 类查询通常输入的 SQL 不确定,使用的内存资源也不确定,因此存在少数查询占用很大内存的风险。 +可以对这类负载可以划分到独立的分组,通过 Workload Group 对内存的硬限的功能,避免突发性的大查询占满所有内存,导致其他查询没有可用内存或者 OOM。 +当这个 Workload Group 的内存使用超过配置的硬限值时,会通过杀死查询的方式释放内存,避免进程内存被打满。 + +**测试环境** + +1FE,1BE,BE 配置为 96 核,内存大小为 375G。 + +测试数据集为 clickbench,测试方法为使用 jmeter 起三并发执行 q29。 + +**测试不开启 Workload Group 的内存硬限** + +1. 查看进程使用内存。ps 命令输出第四列代表进程使用的物理内存的用量,单位为 kb,可以看到当前测试负载下,进程的内存使用为 7.7G 左右。 + + ```sql + [ ~]$ ps -eo pid,comm,%mem,rss | grep 1407481 + 1407481 doris_be 2.0 7896792 + [ ~]$ ps -eo pid,comm,%mem,rss | grep 1407481 + 1407481 doris_be 2.0 7929692 + [ ~]$ ps -eo pid,comm,%mem,rss | grep 1407481 + 1407481 doris_be 2.0 8101232 + ``` + +2. 使用 Doris 系统表查看当前 Workload Group 的内存用量,Workload Group 的内存用量为 5.8G 左右。 + + ```sql + mysql [information_schema]>select MEMORY_USAGE_BYTES / 1024/ 1024 as wg_mem_used_mb from workload_group_resource_usage where workload_group_id=11201; + +-------------------+ + | wg_mem_used_mb | + +-------------------+ + | 5797.524360656738 | + +-------------------+ + 1 row in set (0.01 sec) + + mysql [information_schema]>select MEMORY_USAGE_BYTES / 1024/ 1024 as wg_mem_used_mb from workload_group_resource_usage where workload_group_id=11201; + +-------------------+ + | wg_mem_used_mb | + +-------------------+ + | 5840.246627807617 | + +-------------------+ + 1 row in set (0.02 sec) + + mysql [information_schema]>select MEMORY_USAGE_BYTES / 1024/ 1024 as wg_mem_used_mb from workload_group_resource_usage where workload_group_id=11201; + +-------------------+ + | wg_mem_used_mb | + +-------------------+ + | 5878.394917488098 | + +-------------------+ + 1 row in set (0.02 sec) + ``` + +这里可以看到进程的内存使用通常要远大于一个 Workload Group 的内存用量,即使进程内只有一个 Workload Group 在跑,这是因为 Workload Group 只统计了查询和部分导入的内存,进程内的其他组件比如元数据,各种 Cache 的内存是不计算 Workload Group 内的,也不由 Workload Group 管理。 + +**测试开启 Workload Group 的内存硬限** +1. 执行 SQL 命令修改内存配置。 + + ```sql + alter workload group g2 properties('memory_limit'='0.5%'); + alter workload group g2 properties('enable_memory_overcommit'='false'); + ``` + +2. 执行同样的测试,查看系统表的内存用量,内存用量为 1.5G 左右。 + + ```sql + mysql [information_schema]>select MEMORY_USAGE_BYTES / 1024/ 1024 as wg_mem_used_mb from workload_group_resource_usage where workload_group_id=11201; + +--------------------+ + | wg_mem_used_mb | + +--------------------+ + | 1575.3877239227295 | + +--------------------+ + 1 row in set (0.02 sec) + + mysql [information_schema]>select MEMORY_USAGE_BYTES / 1024/ 1024 as wg_mem_used_mb from workload_group_resource_usage where workload_group_id=11201; + +------------------+ + | wg_mem_used_mb | + +------------------+ + | 1668.77405834198 | + +------------------+ + 1 row in set (0.01 sec) + + mysql [information_schema]>select MEMORY_USAGE_BYTES / 1024/ 1024 as wg_mem_used_mb from workload_group_resource_usage where workload_group_id=11201; + +--------------------+ + | wg_mem_used_mb | + +--------------------+ + | 499.96760272979736 | + +--------------------+ + 1 row in set (0.01 sec) + ``` + +3. 使用 ps 命令查看进程的内存用量,内存用量为 3.8G 左右。 + + ```sql + [ ~]$ ps -eo pid,comm,%mem,rss | grep 1407481 + 1407481 doris_be 1.0 4071364 + [ ~]$ ps -eo pid,comm,%mem,rss | grep 1407481 + 1407481 doris_be 1.0 4059012 + [ ~]$ ps -eo pid,comm,%mem,rss | grep 1407481 + 1407481 doris_be 1.0 4057068 + ``` + +4. 同时客户端会观察到大量由于内存不足导致的查询失败。 + + ```sql + 1724074250162,14126,1c_sql,HY000 1105,"java.sql.SQLException: errCode = 2, detailMessage = (127.0.0.1)[MEM_LIMIT_EXCEEDED]GC wg for hard limit, wg id:11201, name:g2, used:1.71 GB, limit:1.69 GB, backend:10.16.10.8. cancel top memory used tracker <Query#Id=4a0689936c444ac8-a0d01a50b944f6e7> consumption 1.71 GB. details:process memory used 3.01 GB exceed soft limit 304.41 GB or sys available memory 101.16 GB less than warning water mark 12.80 GB., Execute again after enough memory, det [...] + ``` + +这个报错信息中可以看到,Workload Group 使用了 1.7G 的内存,但是 Workload Group 的限制是 1.69G,这里的计算方式是这样的 1.69G = 物理机内存 (375) * mem_limit(be.conf 中的值,默认为 0.9) * 0.5%(Workload Group 的配置) +也就是说,Workload Group 中配置的内存百分比是基于 Doris 进程可用内存再次进行计算的。 + + +**使用建议** + +如上文测试,硬限可以控制 Workload Group 的内存使用,但却是通过杀死查询的方式释放内存,这对用户来说体验会非常不友好,极端情况下可能会导致所有查询都失败。 +因此在生产环境中推荐内存硬限配合查询排队的功能一起使用,可以在限制内存使用的同时保证查询的成功率。 + + + +### CPU 硬限 +Doris 的负载大体可以分为三类: +1. 核心报表查询,通常给公司高层查看报表使用,负载不一定很高,但是对可用性要求较高,这类查询可以划分到一个分组,配置较高优先级的软限,保证 CPU 资源不够时可以获得更多的 CPU 资源。 +2. Adhoc 类查询,这类查询通常偏探索分析,SQL 比较随机,具体的资源用量也比较未知,优先级通常不高。因此可以使用 CPU 硬限进行管理,并配置较低的值,避免占用过多 CPU 资源降低集群可用性。 +3. ETL 类查询,这类查询的 SQL 比较固定,资源用量通常也比较稳定,偶尔会出现上游数据量增长导致资源用量暴涨的情况,因此可以使用 CPU 硬限进行配置。 + +不同的负载对 CPU 的消耗不一样,用户对响应延时的需求也不一样。当 BE 的 CPU 被用的很满时,可用性会变差,响应延时会变高。比如可能一个 Adhoc 的分析类查询把整个集群的 CPU 打满,导致核心报表的延时变大,影响到了 SLA。所以需要 CPU 隔离机制来对不同的业务进行隔离,保障集群的可用性和 SLA。 +Workload Group 支持 CPU 的软限和硬限,目前比较推荐在线上环境把 Workload Group 配置成硬限。原因是 CPU 的软限通常在 CPU 被打满时才能体现出优先级的作用,但是在 CPU 被用满时,Doris 的内部组件(例如 rpc 组件)以及操作系统可用的 CPU 会减少,此时集群整体的可用性是下降比较严重的,因此生产环境通常需要避免 CPU 资源被打满的情况,当然其他资源也一样,内存资源同理。 + + +**测试环境** + +1FE,1BE,96 核机器。 +数据集为 clickbench,测试 sql 为 q29。 + +**发起测试** +1. 使用 jmeter 发起 3 并发查询,把 BE 进程的 CPU 使用压到比较高的使用率,这里测试的机器是 96 核,使用 top 命令看到 BE 进程 CPU 使用率为 7600% 的含义是该进程目前使用中的核数是 76 个。 + +  + +2. 修改使用中的 Workload Group 的 CPU 硬限为 10%。 + + ```sql + alter workload group g2 properties('cpu_hard_limit'='10%'); + ``` + +3. 集群开启硬限模式,此时集群中所有 Group 都会切换为硬限。 + + ```sql + ADMIN SET FRONTEND CONFIG ("enable_cpu_hard_limit" = "true"); + ``` + +4. 重新压测查询负载,可以看到当前进程只能使用 9 到 10 个核,占总核数的 10% 左右。 + +  + +需要注意的是,这里的测试最好使用查询负载会比较能体现出效果,因为如果是高吞吐导入的话,可能会触发 Compaction,使得实际观测的值要比 Workload Group 配置的值大。而 Compaction 的负载目前是没有归入 Workload Group 的管理的。 + +5. 除了使用 Linux 的系统命令外,还可以通过使用 Doris 的系统表观察 Group 目前的 CPU 使用为 10% 左右。 + + ```sql + mysql [information_schema]>select CPU_USAGE_PERCENT from workload_group_resource_usage where WORKLOAD_GROUP_ID=11201; + +-------------------+ + | CPU_USAGE_PERCENT | + +-------------------+ + | 9.57 | + +-------------------+ + 1 row in set (0.02 sec) + ``` + +**注意事项** + +1. 在实际配置的时候,所有 Group 的 CPU 累加值最好不要正好等于 100%,这主要是为了保证低延迟场景的可用性。因为需要让出一部分资源给其他组件使用。当然如果对延迟不是很敏感的场景,期望最高的资源利用率,那么可以考虑所有 Group 的 CPU 累加值配置等于 100%。 +2. 目前 FE 向 BE 同步 Workload Group 元数据的时间间隔为 30 秒,因此对于 Workload Group 的变更最大需要等待 30 秒才能生效。 + + +### 本地IO 硬限 +OLAP 系统在做 ETL 或者大的 Adhoc 查询时,需要读取大量的数据,Doris 为了加速数据分析过程,内部会使用多线程并行的方式对多个磁盘文件扫描,会产生巨大的磁盘 IO,就会对其他的查询(比如报表分析)产生影响。 +可以通过 Workload Group 对离线的 ETL 数据处理和在线的报表查询做分组,限制离线数据处理 IO 带宽的方式,降低它对在线报表分析的影响。 + +**测试环境** + +1FE,1BE, 配置为 96 核。 + +测试数据集为 clickbench。 + +**不开启 IO 硬限测试** +1. 关闭缓存。 -- 使用 user property 绑定 Workload Group:一般由管理员使用 SET-PROPERTY 命令为租户绑定默认的 Workload Group。在以下示例中,为 test_wlg 租户绑定了默认 Workload Group g1: + ```sql + // 清空操作系统缓存 + sync; echo 3 > /proc/sys/vm/drop_caches + + // 禁用 BE 的 page cache + disable_storage_page_cache = true + ``` - ```sql - set property for 'test_wlg' 'default_workload_group' = 'g1'; - ``` +2. 对 clickbench 的表执行全表扫描,执行单并发查询即可。 + + ```sql + set dry_run_query = true; + select * from hits.hits; + ``` -- 使用 session 变量绑定 Workload Group:在业务开发的过程中,即便管理员配置了默认的 Workload Group,也可以在 session 中通过 workload_group 变量修改。在以下示例中,为当前 session 配置了绑定 Workload Group g1: +3. 通过 Doris 的内表查看当前 Group 的最大吞吐为 3GB 每秒。 - ```sql - SET workload_group = 'g1'; - ``` + ```sql + mysql [information_schema]>select LOCAL_SCAN_BYTES_PER_SECOND / 1024 / 1024 as mb_per_sec from workload_group_resource_usage where WORKLOAD_GROUP_ID=11201; + +--------------------+ + | mb_per_sec | + +--------------------+ + | 1146.6208400726318 | + +--------------------+ + 1 row in set (0.03 sec) + + mysql [information_schema]>select LOCAL_SCAN_BYTES_PER_SECOND / 1024 / 1024 as mb_per_sec from workload_group_resource_usage where WORKLOAD_GROUP_ID=11201; + +--------------------+ + | mb_per_sec | + +--------------------+ + | 3496.2762966156006 | + +--------------------+ + 1 row in set (0.04 sec) + + mysql [information_schema]>select LOCAL_SCAN_BYTES_PER_SECOND / 1024 / 1024 as mb_per_sec from workload_group_resource_usage where WORKLOAD_GROUP_ID=11201; + +--------------------+ + | mb_per_sec | + +--------------------+ + | 2192.7690029144287 | + +--------------------+ + 1 row in set (0.02 sec) + ``` -## 为 Workload Group 设置分组 +4. 使用 pidstat 命令查看进程 IO,图中第一列是进程 id,第二列是读 IO 的吞吐(单位是 kb/s)。可以看到不限制 IO 时,最大吞吐为 2G 每秒。 -在多负载或多租户环境中,一个 Doris 集群可能被拆分成多个子集群使用,如部分节点用于外部存储的联邦查询,部分节点用于内表实时查询。Workload Group 可以为 BE 节点打标签(tag),标签相同的 BE 节点组成子集群。每个子集群的资源独立计算,子集群内累加值不能超过 100%。在下例中,将七台机器分成 sub_a 与 sub_b 两个子集群,两个子集群中分别创建了两个 Workload Group。 -在多负载或多租户的环境中,一个 Doris 集群可能被拆分成多个子集群使用,如部分节点用于外部存储的联邦查询,部分节点用于内部表的事实查询,两个自己群在数据分布与资源使用上完全隔离。在同一个子集群群内,需要创建多个租户并创建租户之间的资源使用隔离规则。针对于这类复杂的资源隔离要求,可以结合 Resource Group 与 Workload Group 功能,使用 Resource Group 实现多个子集群的节点粒度隔离,在自己群内使用 Workload Group 进行租户间的资源隔离。如下图中划分成 A、B 两个子集群,每个子集群中有各自的 Workload Group 进行资源管控: +  - -1. 创建 A 与 B 两个 Resource Group,将 7 台机器划分成两个子集群 +**开启 IO 硬限后测试** +1. 关闭缓存。 ```sql - -- create resource group sub_cluster_a - ALTER SYSTEM MODIFY BACKEND "192.168.88.31:9050" SET("tag.location" = "sub_cluster_a"); - ALTER SYSTEM MODIFY BACKEND "192.168.88.32:9050" SET("tag.location" = "sub_cluster_a"); - ALTER SYSTEM MODIFY BACKEND "192.168.88.33:9050" SET("tag.location" = "sub_cluster_a"); + // 清空操作系统缓存 + sync; echo 3 > /proc/sys/vm/drop_caches - -- create resource group sub_cluster_b - ALTER SYSTEM MODIFY BACKEND "192.168.88.34:9050" SET("tag.location" = "sub_cluster_b"); - ALTER SYSTEM MODIFY BACKEND "192.168.88.35:9050" SET("tag.location" = "sub_cluster_b"); + // 禁用 BE 的 page cache + disable_storage_page_cache = true ``` -2. 为子集群创建 Workload Group 进行内存资源隔离 +2. 修改 Workload Group 的配置,限制每秒最大吞吐为 100M。 ```sql - -- create Workload Groups for sub cluster A - CREATE Workload Group a_wlg_1 PROPERTIES('tag' = "sub_cluster_a", "memory_limit" = "30"); - CREATE Workload Group a_wlg_2 PROPERTIES('tag' = "sub_cluster_a", "memory_limit" = "30"); - CREATE Workload Group a_wlg_3 PROPERTIES('tag' = "sub_cluster_a", "memory_limit" = "30"); + // 限制当前 Group 的读吞吐为每秒 100M + alter workload group g2 properties('read_bytes_per_second'='104857600'); + ``` - -- create Workload Groups for sub cluster B - CREATE Workload Group b_wlg_1 PROPERTIES('tag' = "sub_cluster_b", "memory_limit" = "30"); - CREATE Workload Group b_wlg_2 PROPERTIES('tag' = "sub_cluster_b", "memory_limit" = "30"); +3. 使用 Doris 系统表查看 Workload Group 的最大 IO 吞吐为每秒 98M。 + + ```sql + mysql [information_schema]>select LOCAL_SCAN_BYTES_PER_SECOND / 1024 / 1024 as mb_per_sec from workload_group_resource_usage where WORKLOAD_GROUP_ID=11201; + +--------------------+ + | mb_per_sec | + +--------------------+ + | 97.94296646118164 | + +--------------------+ + 1 row in set (0.03 sec) + + mysql [information_schema]>select LOCAL_SCAN_BYTES_PER_SECOND / 1024 / 1024 as mb_per_sec from workload_group_resource_usage where WORKLOAD_GROUP_ID=11201; + +--------------------+ + | mb_per_sec | + +--------------------+ + | 98.37584781646729 | + +--------------------+ + 1 row in set (0.04 sec) + + mysql [information_schema]>select LOCAL_SCAN_BYTES_PER_SECOND / 1024 / 1024 as mb_per_sec from workload_group_resource_usage where WORKLOAD_GROUP_ID=11201; + +--------------------+ + | mb_per_sec | + +--------------------+ + | 98.06641292572021 | + +--------------------+ + 1 row in set (0.02 sec) ``` -## 注意事项 +4. 使用 pid 工具查看进程最大 IO 吞吐为每秒 131M。 + +  + +**注意事项** +1. 系统表中的 LOCAL_SCAN_BYTES_PER_SECOND 字段代表的是当前 Workload Group 在进程粒度的统计汇总值,比如配置了 12 个文件路径,那么 LOCAL_SCAN_BYTES_PER_SECOND 就是这 12 个文件路径 IO 的最大值,如果期望查看每个文件路径分别的 IO 吞吐,可以在 grafana 上或者 BE 的 bvar 监控查看明细的值。 + +2. 由于操作系统和 Doris 的 Page Cache 的存在,通过 linux 的 IO 监控脚本看到的 IO 通常要比系统表看到的要小。 + + +### 远程 IO 硬限 +BrokerLoad 和 S3Load 是常用的大批量数据导入方式,用户可以把数据先上传到 HDFS 或者 S3,然后通过 Brokerload 和 S3Load 对数据进行并行导入。Doris 为了加快导入速度,会使用多线程并行的方式从 HDFS/S3 拉取数据,此时会对 HDFS/S3 产生巨大的压力,会导致 HDFS/S3 上运行的别的作业不稳定。 +可以通过 Workload Group 远程 IO 的限制功能来限制导入过程中对 HDFS/S3 的带宽,降低对其他业务的影响。 + + +**测试环境** + +1FE,1BE 部署在同一台机器,配置为 16 核 64G 内存。测试数据为 clickbench 数据集,测试前需要把数据集上传到 S3 上。考虑到上传时间的问题,我们只取其中的 1 千万行数据上传,然后使用 tvf 的功能查询 s3 的数据。 + +上传成功后可以使用命令查看 Schema 信息。 + + ```sql + // 查看schema + DESC FUNCTION s3 ( + "URI" = "https://bucketname/1kw.tsv", + "s3.access_key"= "ak", + "s3.secret_key" = "sk", + "format" = "csv", + "use_path_style"="true" + ); + ``` + +**测试不限制远程读的 IO** +1. 发起单并发测试,全表扫描 clickbench 表。 + + ```sql + // 设置只 scan 数据,不返回结果 + set dry_run_query = true; + + // 使用 tvf 查询 s3 的数据 + SELECT * FROM s3( + "URI" = "https://bucketname/1kw.tsv", + "s3.access_key"= "ak", + "s3.secret_key" = "sk", + "format" = "csv", + "use_path_style"="true" + ); + ``` + +2. 使用系统表查看此时的远程 IO 吞吐。可以看到这个查询的远程 IO 吞吐为 837M 每秒,需要注意的是,这里的实际 IO 吞吐受环境影响较大,如果 BE 所在的机器连接外部存储的带宽比较低,那么可能实际的吞吐会小。 + + ```sql + MySQL [(none)]> select cast(REMOTE_SCAN_BYTES_PER_SECOND/1024/1024 as int) as read_mb from information_schema.workload_group_resource_usage; + +---------+ + | read_mb | + +---------+ + | 837 | + +---------+ + 1 row in set (0.104 sec) + + MySQL [(none)]> select cast(REMOTE_SCAN_BYTES_PER_SECOND/1024/1024 as int) as read_mb from information_schema.workload_group_resource_usage; + +---------+ + | read_mb | + +---------+ + | 867 | + +---------+ + 1 row in set (0.070 sec) + + MySQL [(none)]> select cast(REMOTE_SCAN_BYTES_PER_SECOND/1024/1024 as int) as read_mb from information_schema.workload_group_resource_usage; + +---------+ + | read_mb | + +---------+ + | 867 | + +---------+ + 1 row in set (0.186 sec) + ``` + +3. 使用 sar(sar -n DEV 1 3600) 命令查看机器的网络带宽,可以看到机器级别最大网络带宽为 1033M 每秒。 + 输出的第一列为当前机器某个网卡每秒接收的字节数,单位为 KB 每秒。 + +  + +**测试限制远程读的 IO** +1. 修改 Workload Group 的配置,限制远程读的 IO 吞吐为 100M 每秒。 + + ```sql + alter workload group normal properties('remote_read_bytes_per_second'='104857600'); + ``` + +2. 发起单并发扫全表的查询。 + + ```sql + // 设置只 scan 数据,不返回结果 + set dry_run_query = true; + + // 使用 tvf 查询 s3 的数据 + SELECT * FROM s3( + "URI" = "https://bucketname/1kw.tsv", + "s3.access_key"= "ak", + "s3.secret_key" = "sk", + "format" = "csv", + "use_path_style"="true" + ); + ``` + +3. 使用系统表查看此时的远程读 IO 吞吐,此时的 IO 吞吐在 100M 左右,会有一定的波动,这个波动是受目前算法设计的影响,通常会有一个高峰,但不会持续很长时间,属于正常情况。 + + ```sql + MySQL [(none)]> select cast(REMOTE_SCAN_BYTES_PER_SECOND/1024/1024 as int) as read_mb from information_schema.workload_group_resource_usage; + +---------+ + | read_mb | + +---------+ + | 56 | + +---------+ + 1 row in set (0.010 sec) + + MySQL [(none)]> select cast(REMOTE_SCAN_BYTES_PER_SECOND/1024/1024 as int) as read_mb from information_schema.workload_group_resource_usage; + +---------+ + | read_mb | + +---------+ + | 131 | + +---------+ + 1 row in set (0.009 sec) + + MySQL [(none)]> select cast(REMOTE_SCAN_BYTES_PER_SECOND/1024/1024 as int) as read_mb from information_schema.workload_group_resource_usage; + +---------+ + | read_mb | + +---------+ + | 111 | + +---------+ + 1 row in set (0.009 sec) + ``` -1. 在 Kubernetes 中使用 Workload 管控资源。Workload 的 CPU 管理是基于 CGroup 实现的,如果期望在容器中使用 Workload Group,那么需要以特权模式启动容器,容器内的 Doris 进程才能具备读写宿主机 CGroup 文件的权限。当 Doris 在容器内运行时,Workload Group 的 CPU 资源用量是在容器可用资源的情况下再划分的,例如宿主机整机是 64 核,容器被分配了 8 个核的资源,Workload Group 配置的 CPU 硬限为 50%,那么 Workload Group 实际可用核数为 4 个(8 核 * 50%)。 +4. 使用 sar 命令(sar -n DEV 1 3600)查看目前的网卡接收流量,第一列为每秒接收的数据量,可以看到最大值变成了 207M 每秒,说明读 IO 的限制是生效的,但是由于 sar 命令看到的是机器级别的流量,因此要比 Doris 统计到的会大一些。 -2. WorkloadGroup 的内存管理和 IO 管理功能是 Doris 内部实现,不依赖外部组件,因此在容器和物理机上部署使用并没有区别。如果要在 K8S 上使用 Doris,建议使用 Doris Operator 进行部署,可以屏蔽底层的权限细节问题。 \ No newline at end of file +  diff --git a/sidebars.json b/sidebars.json index eaa6968dffe..37976d74aef 100644 --- a/sidebars.json +++ b/sidebars.json @@ -469,9 +469,15 @@ "label": "Managing Workload", "items": [ "admin-manual/workload-management/workload-management-summary", - "admin-manual/workload-management/resource-group", - "admin-manual/workload-management/compute-group", - "admin-manual/workload-management/workload-group", + { + "type": "category", + "label": "Resource Isolation", + "items": [ + "admin-manual/workload-management/resource-group", + "admin-manual/workload-management/compute-group", + "admin-manual/workload-management/workload-group" + ] + }, "admin-manual/workload-management/concurrency-control-and-queuing", "admin-manual/workload-management/sql-blocking", "admin-manual/workload-management/kill-query", diff --git a/versioned_sidebars/version-2.1-sidebars.json b/versioned_sidebars/version-2.1-sidebars.json index 8c1d4fcc549..482625409e6 100644 --- a/versioned_sidebars/version-2.1-sidebars.json +++ b/versioned_sidebars/version-2.1-sidebars.json @@ -416,8 +416,14 @@ "label": "Managing Workload", "items": [ "admin-manual/workload-management/workload-management-summary", - "admin-manual/workload-management/resource-group", - "admin-manual/workload-management/workload-group", + { + "type": "category", + "label": "Resource Isolation", + "items": [ + "admin-manual/workload-management/resource-group", + "admin-manual/workload-management/workload-group" + ] + }, "admin-manual/workload-management/concurrency-control-and-queuing", "admin-manual/workload-management/sql-blocking", "admin-manual/workload-management/kill-query", diff --git a/versioned_sidebars/version-3.0-sidebars.json b/versioned_sidebars/version-3.0-sidebars.json index 7922caa04e9..7d0b24a5735 100644 --- a/versioned_sidebars/version-3.0-sidebars.json +++ b/versioned_sidebars/version-3.0-sidebars.json @@ -455,9 +455,15 @@ "label": "Managing Workload", "items": [ "admin-manual/workload-management/workload-management-summary", - "admin-manual/workload-management/resource-group", - "admin-manual/workload-management/compute-group", - "admin-manual/workload-management/workload-group", + { + "type": "category", + "label": "Resource Isolation", + "items": [ + "admin-manual/workload-management/resource-group", + "admin-manual/workload-management/compute-group", + "admin-manual/workload-management/workload-group" + ] + }, "admin-manual/workload-management/concurrency-control-and-queuing", "admin-manual/workload-management/sql-blocking", "admin-manual/workload-management/kill-query", --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org