如何使用和管理 Amazon Redshift WLM 内存分配?

上次更新日期:2020 年 10 月 6 日

我正在尝试检查并发性和 Amazon Redshift 工作负载管理 (WLM) 的队列分配。WLM 分配如何工作,我应在何时使用它?

简短描述

Amazon Redshift 工作负载管理 (WLM) 允许您管理和定义多个查询队列。它会将查询路由到相应的队列,并在运行时为查询分配内存。某些查询可能会消耗更多的集群资源,从而影响其他查询的性能。

您可以通过以下任一方式配置工作负载管理,以便有效地管理资源:

  • 自动 WLM:允许 Amazon Redshift 管理队列的并发级别和每个已分派查询的内存分配。已分派的查询允许用户定义工作负载或用户对每个查询队列的查询优先级
  • 手动 WLM:允许您更好地控制并发级别和队列的内存分配。因此,消耗更多资源的查询可以在分配更多资源的队列中运行。

注意:要定义基于指标的性能边界,请在工作负载管理配置中使用查询监控规则 (QMR)

要检查并发级别和 WLM 的队列分配,请执行以下步骤:

1.    检查 Amazon Redshift 集群的当前 WLM 配置。

2.    创建测试工作负载管理配置,指定查询队列的分布和并发级别。

3.    (可选)如果您使用的是手动 WLM,请确定内存在槽计数之间的分配方式。

解决方法

检查您的 WLM 配置和内存使用情况

使用 STV_WLM_SERVICE_CLASS_CONFIG 表检查 Amazon Redshift 集群的当前 WLM 配置:

[
  {
    "query_concurrency": 2,
    "memory_percent_to_use": 30,
    "query_group": [],
    "query_group_wild_card": 0,
    "user_group": [
      "user_group1"
    ],
    "user_group_wild_card": 0,
    "rules": [
      {
        "rule_name": "BlockstoDiskSpill",
        "predicate": [
          {
            "metric_name": "query_temp_blocks_to_disk",
            "operator": ">",
            "value": 50
          }
        ],
        "action": "abort"
      }
    ]
  },
  {
    "query_concurrency": 5,
    "memory_percent_to_use": 40,
    "query_group": [],
    "query_group_wild_card": 0,
    "user_group": [
      "user_group2"
    ],
    "user_group_wild_card": 0
  },
  {
    "query_concurrency": 5,
    "memory_percent_to_use": 10,
    "query_group": [],
    "query_group_wild_card": 0,
    "user_group": [],
    "user_group_wild_card": 0,
    "rules": [
      {
        "rule_name": "abort_query",
        "predicate": [
          {
            "metric_name": "scan_row_count",
            "operator": ">",
            "value": 1000
          }
        ],
        "action": "abort"
      }
    ]
  },
  {
    "query_group": [],
    "query_group_wild_card": 0,
    "user_group": [],
    "user_group_wild_card": 0,
    "auto_wlm": false
  },
  {
    "short_query_queue": false
  }
]

注意:在此示例中,WLM 配置采用 JSON 格式,并使用查询监控规则 (Queue1)。

在 WLM 配置中,“memory_percent_to_use”表示分配给 服务类的实际工作内存量。请注意,Amazon Redshift 会从集群中的共享资源池分配内存。因此,Queue1 具有 30% 的内存分配,它进一步分成 2 个相等的槽。然后,每个槽都将获得相等的 15% 的当前内存分配份额。同时,Queue2 具有 40% 的内存分配,它进一步分成 5 个相等的槽。然后,每个槽都将获得相等的 8% 内存分配。默认队列使用 10% 的内存分配,并且队列并发级别为 5。

使用以下查询检查 Amazon Redshift WLM 的服务类配置:

select rtrim(name) as name,
num_query_tasks as slots,
query_working_mem as mem,
max_execution_time as max_time,
user_group_wild_card as user_wildcard,
query_group_wild_card as query_wildcard
from stv_wlm_service_class_config
where service_class > 4;

以下是示例输出:

                        name                        | slots | mem | max_time | user_wildcard | query_wildcard
----------------------------------------------------+-------+-----+----------+---------------+----------------
 Service class for super user                       |     1 | 297 |        0 | false         | false
 Queue 1                                            |     2 | 522 |        0 | false         | false
 Queue 2                                            |     5 | 278 |        0 | false         | false
 Default queue                                      |     5 |  69 |        0 | false         | false
 Service class for vacuum/analyze                   |     0 |   0 |        0 | false         | false

队列 1 的槽计数为 2,为每个槽(或节点)分配的内存为 522MB。内存分配表示分配给服务类的各个节点的每个槽当前实际工作内存量(以 MB 为单位)。

注意:如果已使用所有查询槽,则队列中未分配的内存将分配给其他槽。例如,如果查询并发级别设置为“5”,但是当前队列仅使用一个槽,则会保留未分配的内存。然后,未分配的内存将供当前槽中的查询使用。

识别高级调优参数

以下是查询的示例查询执行计划:

  • 使用 SVL_QUERY_METRICS_SUMMARY 表检查详细的执行,并使用“query_queue_time”列查看已加入队列的查询。“query_queue_time”列表示查询正在队列中等待 WLM 槽执行。
  • 使用 SVL_QUERY_SUMMARY 表检查查询的内存消耗,即使查询在内存中运行也是如此。
dev=# select userid, query, service_class, query_cpu_time, query_blocks_read, query_execution_time, query_cpu_usage_percent, query_temp_blocks_to_disk, query_queue_time  from SVL_QUERY_METRICS_SUMMARY where query=29608;

 userid | query | service_class | query_cpu_time | query_blocks_read | query_execution_time | query_cpu_usage_percent | query_temp_blocks_to_disk | query_queue_time
--------+-------+---------------+----------------+-------------------+----------------------+-------------------------+---------------------------+------------------
    100 | 29608 |                    8 |                       18 |                          942 |                                64 |                                   10.05 |                                               |
(1 row)


ev=# select query, step, rows, workmem, label, is_diskbased
from svl_query_summary
where query = 29608
order by workmem desc;

 query | step |   rows   | workmem  |                  label                  | is_diskbased
-------+------+----------+----------+-----------------------------------------+--------------
 29608 |    3 |    49999 | 54263808 | hash   tbl=714                          | f
 29608 |    2 |    49999 |        0 | project                                 | f
 29608 |    0 |    49999 |        0 | scan   tbl=255079 name=part             | f
 29608 |    1 |    49999 |        0 | project                                 | f
 29608 |    6 |  1561938 |        0 | return                                  | f
 29608 |    4 |  1561938 |        0 | project                                 | f
 29608 |    5 |  1561938 |        0 | project                                 | f
 29608 |    2 | 29995220 |        0 | project                                 | f
 29608 |    1 |  1561938 |        0 | return                                  | f
 29608 |    1 | 29995220 |        0 | project                                 | f
 29608 |    0 |  1561938 |        0 | scan   tbl=4893 name=Internal Worktable | f
 29608 |    3 |  1561938 |        0 | hjoin  tbl=714                          | f
 29608 |    0 | 29995220 |        0 | scan   tbl=255087 name=lineorder        | f
(13 rows)
使用 SVL_QUERY_SUMMARY 表在查询的每个步骤期间获取资源分配的详细视图。检查 is_diskbasedworkmem 列以查看资源消耗。有关更多信息,请参阅 分析查询摘要

更新为 WLM 动态配置属性

您还可以使用 WLM 动态配置属性来适应不断变化的工作负载。您可以在不重启集群的情况下将动态属性应用到数据库。但是,WLM 静态配置属性要求重启集群以使更改生效。

以下是配置了两个队列的集群示例:

Queue    Concurrency    % Memory to Use            
1        5              60%
2        5              40%

如果集群具有 200GB 的可用内存,则每个队列槽的当前内存分配可能如下所示:

Queue 1: (200 GB * 60% ) / 5 slots  = 24 GB
Queue 2: (200 GB * 40% ) / 5 slots  = 16 GB

要将 WLM 配置属性更新为动态属性,请按如下所示修改设置:

Queue    Concurrency    % Memory to Use
1        3              75%
2        4              25%

因此,内存分配已更新以适应变化的工作负载:

Queue 1: (200 GB * 75% ) / 3 slots = 50 GB
Queue 2: (200 GB * 25% ) / 4 slots = 12.5 GB
注意:如果在动态配置更新期间有任何查询正在 WLM 队列中运行,则 Amazon Redshift 将等待这些查询完成。查询完成后,Amazon Redshift 会使用更新的设置更新集群。

当正在过渡到动态 WLM 配置属性时,请使用 STV_WLM_SERVICE_CLASS_CONFIG 表。当 num_query_tasks(并发性)和 query_working_mem(动态内存百分比)列的目标值相等时,表示过渡完成。

识别分配给查询的内存不足

如果 SVL_QUERY_SUMMARY 中的查询执行计划的 is_diskbased 值为“true”,则考虑为查询分配更多内存。您可以通过增加使用的查询槽数来分配更多内存。有关更多信息,请参阅步骤 1:使用 wlm_query_slot_count 覆盖并发级别

注意:最佳做法是首先确定导致磁盘溢出的步骤。然后,确定为队列分配更多内存是否可以解决此问题。或者,您也可以优化查询。


这篇文章对您有帮助吗?


您是否需要账单或技术支持?