1 - 可扩展性和并发优化的基本原则

Vertica 数据库在一组商用硬件上运行。对数据库运行的所有加载和查询均需占用 CPU、内存、磁盘 I/O 带宽、文件句柄等系统资源。给定查询的性能(运行时间)取决于为其分配的资源量。

在系统中同时运行多个查询时,这些查询会共享资源;因此,每个查询的运行时间可能比其单独运行时要长。在可扩展的高效系统中,如果某个查询占用计算机的所有资源且运行时间为 X,则运行两个此类查询可能会使每个查询的运行时间增加一倍。如果查询的运行时间超过 2X,则说明系统并非可线性扩展;如果查询的运行时间小于 2X,则说明单个查询在资源使用方面存在浪费情况。请注意,只要查询获得其运行所需的最少资源且受 CPU 周期限制,就会发生上述情况。相反,如果因系统瓶颈导致查询无法获得运行所需的足够特定资源,则说明系统已达到极限。在这种情况下,为了提高并发性,必须通过另外添加此资源来扩展系统。

实际上,Vertica 应在达到系统资源限制之前,通过提高并发性而在运行时间方面实现近乎线性的可扩展性。如果达到足够的并发性且未引发任何瓶颈,便可认为系统大小非常适合工作负载。

2 - 为查询设置运行时限制

可以为允许查询运行的时间长度设置限制。您可以将此限制设置为三个级别,按优先级降序排列:

  1. 要将用户分配到的资源池。

  2. 具有 RUNTIMECAP(由 CREATE USER/ALTER USER 配置)的用户配置文件 ALTER USER

  3. 会话查询(由 SET SESSION RUNTIMECAP 设置) SET SESSION RUNTIMECAP

在所有情况下,您都可以使用不超过一年的 interval 值设置运行时限制。在多个级别设置运行时限制时,Vertica 始终使用最短的值。如果为非超级用户设置了运行时限制,则该用户无法将任何会话设置为更长的运行时限制。超级用户可以将其他用户和他们自己的会话的运行时限制设置为不超过一年(包含)的任意值。

示例

user1 被分配至 ad_hoc_queries 资源库:

=> CREATE USER user1 RESOURCE POOL ad_hoc_queries;

user1RUNTIMECAP 设置为 1 小时。

=> ALTER USER user1 RUNTIMECAP '60 minutes';

ad_hoc_queries 资源池的 RUNTIMECAP 设置为 30 分钟。

=> ALTER RESOURCE POOL ad_hoc_queries RUNTIMECAP '30 minutes';

在本例中,如果 user1 的查询超过 30 分钟,Vertica 会终止这些查询。尽管 user1 的运行时间限制设置为一小时,但运行查询的池(具有 30 分钟的运行时间限制)具有优先权。

另请参阅

3 - 处理会话套接字阻止

针对给定查询等待客户端输入或输出时,会话套接字可能会被阻止。会话套接字通常因多种原因而被阻止 — 例如,当 Vertica 执行引擎将数据传输到客户端时,或 COPY LOCAL 操作等待从客户端加载数据时。

在极少数情况下,会话套接字可能会无限期地保持被阻止状态。例如,客户端上的查询超时,这会尝试强制取消查询或者依赖会话 RUNTIMECAP 设置来终止查询。在任何一种情况下,如果查询在等待消息或数据时结束,则套接字可能会保持阻止状态,会话将挂起,直到它被强制关闭。

配置宽限期

您可以为系统配置一个宽限期,在此期间滞后的客户端或服务器可以跟上并传递待定的响应。如果套接字保持被阻止状态的连续期间超过宽限期设置,服务器将关闭套接字并引发致命错误。随后,会话终止。如果没有设置宽限期,查询会使套接字无限期地保持被阻止状态。

您应该将会话宽限期设置为高到足以覆盖可接受的延迟范围并避免会话过早关闭 — 例如,为了对服务器进行响应而设置正常的客户端延迟。超大负载操作可能会要求您根据需要调整会话宽限期。

您可以将宽限期设置为四个级别,按优先级降序排列:

  1. 会话(最高)

  2. 用户

  3. 节点

  4. 数据库

为数据库和节点设置宽限期

在数据库和节点级别,可以通过 BlockedSocketGracePeriod 配置参数将宽限期设置为不超过 20 天的任意间隔

  • ALTER DATABASE db-name SET BlockedSocketGracePeriod = 'interval';
  • ALTER NODE node-name SET BlockedSocketGracePeriod = 'interval';

默认情况下,这两个级别的宽限期都设置为空字符串,允许无限期阻止。

为用户和会话设置宽限期

您可以为单个用户和给定会话设置宽限期,如下所示:

用户可以将会话设置为等于或小于为该用户设置的宽限期的任意间隔。超级用户可以将其他用户和他们自己的会话的宽限期设置为不超过 20 天(包含)的任意值。

示例

超级用户 dbadmin 将数据库宽限期设置为 6 小时。此限制仅适用于非超级用户。 dbadmin 可以将自己的会话宽限期设置为不超过 20 天的任意值 — 在本例中为 10 小时:

=> ALTER DATABASE VMart SET BlockedSocketGracePeriod = '6 hours';
ALTER DATABASE
=> SHOW CURRENT BlockedSocketGracePeriod;
  level   |           name           | setting
----------+--------------------------+---------
 DATABASE | BlockedSocketGracePeriod | 6 hours
(1 row)

=> SET SESSION GRACEPERIOD '10 hours';
SET
=> SHOW GRACEPERIOD;
    name     | setting
-------------+---------
 graceperiod | 10:00
(1 row)

dbadmin 创建未设置宽限期的用户 user777。因此,user777 的有效宽限期派生自数据库的 BlockedSocketGracePeriod 设置,即 6 小时。user777 将会话宽限期设置为大于 6 小时的任何尝试都会返回错误:


=> CREATE USER user777;
=> \c - user777
You are now connected as user "user777".
=> SHOW GRACEPERIOD;
    name     | setting
-------------+---------
 graceperiod | 06:00
(1 row)

=> SET SESSION GRACEPERIOD '7 hours';
ERROR 8175:  The new period 07:00 would exceed the database limit of 06:00

dbadminuser777 设置 5 分钟的宽限期。现在,user777 可以将会话宽限期设置为等于或小于用户级别设置的任何值:


=> \c
You are now connected as user "dbadmin".
=> ALTER USER user777 GRACEPERIOD '5 minutes';
ALTER USER
=> \c - user777
You are now connected as user "user777".
=> SET SESSION GRACEPERIOD '6 minutes';
ERROR 8175:  The new period 00:06 would exceed the user limit of 00:05
=> SET SESSION GRACEPERIOD '4 minutes';
SET

4 - 将用户定义的池和用户配置文件用于工作负载管理

本部分中的场景介绍常见的工作负载管理问题,并提供带示例的解决方案。

4.1 - 周期性批量加载

场景

您每天晚上都执行批量加载,偶尔(很少)在白天执行批量加载。当加载正在运行时,减少查询的资源使用量是可接受的,但在其他所有时间,您希望所有资源都可用于查询。

解决方案

为加载创建一个单独的资源池,使其优先级高于内置 GENERAL 池上的预配置设置。

在此场景中,在从 GENERAL 池中借用内存时,每天晚上的加载具有优先权。在没有运行加载时,所有内存将可自动用于查询。

示例

创建一个优先级高于 GENERAL 池的资源池:

  1. 创建 PRIORITY 设置为 10 的资源池 load_pool

    => CREATE RESOURCE POOL load_pool PRIORITY 10;
    
  2. 修改用户 load_user 以使用新的资源池:

    => ALTER USER load_user RESOURCE POOL load_pool;
    

4.2 - CEO 查询

场景

CEO 在每周一的上午 9 点运行报告,您想要确保该报告始终运行。

解决方案

若要确保某个查询或某类查询始终获得资源,可以为其创建专用池,如下所示:

  1. 使用 PROFILE 命令,运行 CEO 每周运行的查询,确定应当分配的内存量:

    => PROFILE SELECT DISTINCT s.product_key, p.product_description
    -> FROM store.store_sales_fact s, public.product_dimension p
    -> WHERE s.product_key = p.product_key AND s.product_version = p.product_version
    -> AND s.store_key IN (
    ->  SELECT store_key FROM store.store_dimension
    ->  WHERE store_state = 'MA')
    -> ORDER BY s.product_key;
    
  2. 在查询结束时,系统返回一条含有资源使用量的通知:

    NOTICE:  Statement is being profiled.HINT:  select * from v_monitor.execution_engine_profiles where
    transaction_id=45035996273751349 and statement_id=6;
    NOTICE:  Initiator memory estimate for query: [on pool general: 1723648 KB,
    minimum: 355920 KB]
    
  3. 创建具有上述提示所报告的 MEMORYSIZE 的资源池,确保至少为 CEO 查询保留此内存大小:

    => CREATE RESOURCE POOL ceo_pool MEMORYSIZE '1800M' PRIORITY 10;
    CREATE RESOURCE POOL
    => \x
    Expanded display is on.
    => SELECT * FROM resource_pools WHERE name = 'ceo_pool';
    -[ RECORD 1 ]-------+-------------
    name                | ceo_pool
    is_internal         | f
    memorysize          | 1800M
    maxmemorysize       |
    priority            | 10
    queuetimeout        | 300
    plannedconcurrency  | 4
    maxconcurrency      |
    singleinitiator     | f
    
  4. 假设 CEO 报告用户已存在,使用 ALTER USER 语句将此用户与上述资源池相关联。

    => ALTER USER ceo_user RESOURCE POOL ceo_pool;
    
  5. 发出以下命令确认 ceo_user 与 ceo_pool 相关联:

    => SELECT * FROM users WHERE user_name ='ceo_user';
    -[ RECORD 1 ]-+------------------
    user_id       | 45035996273713548
    user_name     | ceo_user
    is_super_user | f
    resource_pool | ceo_pool
    memory_cap_kb | unlimited
    

如果 CEO 查询内存使用量过大,可以让资源管理器将其降至符合特定预算的水平。请参阅查询预算

4.3 - 防止失控查询

场景

Joe 是一位经常在中午运行大型报告的业务分析员,这些报告占用了整个机器的资源。您想要防止 Joe 使用超过 100MB 的内存,并且想要将 Joe 的查询运行时间限制在 2 小时以内。

解决方案

用户配置文件 为此场景提供了一个解决方案。若要限制 Joe 一次可以使用的内存量,使用 ALTER USER 命令将 Joe 的 MEMORYCAP 设置为 100MB。若要限制 Joe 的查询可以运行的时间长度,使用相同的命令将 RUNTIMECAP 设置为 2 小时。如果 Joe 运行的查询超过其最高限值,Vertica 会拒绝该查询。

如果您有一批需要限制查询的用户,也可以为他们创建一个资源池并为该资源池设置 RUNTIMECAP。将这些用户移至此资源池后,Vertica 会将这些用户的所有查询限制为您为该资源池指定的 RUNTIMECAP。

示例

=> ALTER USER analyst_user MEMORYCAP '100M' RUNTIMECAP '2 hours';

如果 Joe 尝试运行超过 100MB 的查询,系统会返回一个错误,说明请求超出内存会话限制,如以下示例所示:

\i vmart_query_04.sqlvsql:vmart_query_04.sql:12: ERROR:  Insufficient resources to initiate plan
on pool general [Request exceeds memory session limit: 137669KB > 102400KB]

只有系统数据库管理员 (dbadmin) 可以提高 MEMORYCAP 设置。用户不能提高自己的 MEMORYCAP 设置,如果他们尝试编辑其 MEMORYCAP 或 RUNTIMECAP 设置,则将看到类似于以下内容的错误:

ALTER USER analyst_user MEMORYCAP '135M';
ROLLBACK:  permission denied

4.4 - 限制临时查询应用程序的资源使用率

场景

您最近将数据仓库提供给一大群用户,而他们并不熟悉 SQL。一些用户对大量的行运行报告,耗尽了系统资源。您想要制约这些用户的系统使用量。

解决方案

  1. 为 MAXMEMORYSIZE 等于 MEMORYSIZE 的临时应用程序创建资源池。这可以防止该资源池中的查询从 GENERAL 池中借用资源。另外,设置 RUNTIMECAP 以限制临时查询的最大持续时间。

    => CREATE RESOURCE POOL adhoc_pool
        MEMORYSIZE '200M'
           MAXMEMORYSIZE '200M'
        RUNTIMECAP '20 seconds'
        PRIORITY 0
        QUEUETIMEOUT 300
        PLANNEDCONCURRENCY 4;
    => SELECT pool_name, memory_size_kb, queueing_threshold_kb
        FROM V_MONITOR.RESOURCE_POOL_STATUS WHERE pool_name='adhoc_pool';
     pool_name  | memory_size_kb | queueing_threshold_kb
    ------------+----------------+-----------------------
     adhoc_pool |         204800 |                153600
    (1 row)
    
  2. 将此资源池与应用程序用于连接到数据库的数据库用户相关联。

    => ALTER USER app1_user RESOURCE POOL adhoc_pool;
    

4.5 - 为应用程序设置硬性并发限制

场景

为了便于开票,分析员 Jane 希望对此应用程序的并发性实施硬性限制。如何做到这一点?

解决方案

最简单的解决方案是为该应用程序的用户创建一个单独的资源池,并将其 MAXCONCURRENCY 设置为所需的并发级别。任何超过 MAXCONCURRENCY 的查询都会进入队列。

示例

在本示例中,存在四位与开票池相关联的开票用户。目的是对资源池设置硬性限制,使一次最多可以执行三个并发查询。所有其他查询将排队并在资源释放后完成。

=> CREATE RESOURCE POOL billing_pool MAXCONCURRENCY 3 QUEUETIMEOUT 2;
=> CREATE USER bill1_user RESOURCE POOL billing_pool;
=> CREATE USER bill2_user RESOURCE POOL billing_pool;
=> CREATE USER bill3_user RESOURCE POOL billing_pool;
=> CREATE USER bill4_user RESOURCE POOL billing_pool;
=> \x
Expanded display is on.

=> select maxconcurrency,queuetimeout from resource_pools where name = 'billing_pool';
maxconcurrency | queuetimeout
----------------+--------------
             3 |            2
(1 row)
> SELECT reason, resource_type, rejection_count  FROM RESOURCE_REJECTIONS
WHERE pool_name = 'billing_pool' AND node_name ilike '%node0001';
reason                                | resource_type | rejection_count
---------------------------------------+---------------+-----------------
Timedout waiting for resource request | Queries       |              16
(1 row)

如果查询正在运行并且没有在规定时间内完成(默认超时设置为 5 分钟),请求的下一查询将收到一条类似于以下内容的错误:

ERROR:  Insufficient resources to initiate plan on pool billing_pool [Timedout waiting for resource request: Request exceeds limits:
Queries Exceeded: Requested = 1, Free = 0 (Limit = 3, Used = 3)]

下表显示在开票池中存在三个活动查询。

=> SELECT pool_name, thread_count, open_file_handle_count, memory_inuse_kb FROM RESOURCE_ACQUISITIONS
WHERE pool_name = 'billing_pool';
pool_name    | thread_count | open_file_handle_count | memory_inuse_kb
--------------+--------------+------------------------+-----------------
billing_pool |            4 |                      5 |          132870
billing_pool |            4 |                      5 |          132870
billing_pool |            4 |                      5 |          132870
(3 rows)

4.6 - 处理混合工作负载:批处理与交互式处理

场景

您具有一个带交互门户的 Web 应用程序。有时,当 IT 人员运行批处理报告时,Web 页面需要很长时间才能刷新,引起用户抱怨,因此您想要为网站用户提供更好的体验。

解决方案

可以应用先前场景中学习到的原则解决此问题。基本思想是将查询分离成与不同资源池相关联的两组。先决条件是存在两个不同的数据库用户,他们发出不同类型的查询。如果情况与此不同,请将此视为应用程序设计的最佳方法。

方法 1
创建专门用于 Web 页面刷新查询的资源池,同时:

  • 根据查询的平均资源需求以及门户中发出的并发查询的预期数量来设定资源池大小。

  • 将此资源池与运行网站查询的数据库用户相关联。有关创建专用池的信息,请参阅CEO 查询

这可确保网站查询始终运行并且从不排列在大型批处理作业之后。让处理作业不在 GENERAL 池上运行。

例如,以下池是根据从 Web 运行的查询所需的平均资源量以及并发查询的预期数量来确定的。另外,它给予 Web 查询的优先级要高于任何正在运行的批处理作业,并假定将查询调整为每个查询占用 250M:

=> CREATE RESOURCE POOL web_pool
     MEMORYSIZE '250M'
     MAXMEMORYSIZE NONE
     PRIORITY 10
     MAXCONCURRENCY 5
     PLANNEDCONCURRENCY 1;

方法 2
创建具有固定内存大小的资源池。这将限制批处理报告可用的内存量,使内存始终留作其他用途。有关详细信息,请参阅限制临时查询应用程序的资源使用率

例如:

=> CREATE RESOURCE POOL batch_pool
     MEMORYSIZE '4G'
     MAXMEMORYSIZE '4G'
     MAXCONCURRENCY 10;

如果您有三个或更多不同类别的工作负载,此原则同样适用。

4.7 - 对不同用户发出的查询设置优先级

场景

您希望一个部门的用户查询比另一个部门的查询具有更高的优先级。

解决方案

解决方案类似于混合工作负载场景。在此场景中,您没有限制资源使用量;您设置了不同的优先级。若要这样做,可创建两个不同的池,每个池都具有 MEMORYSIZE=0% 以及一个不同的 PRIORITY 参数。这两个池都从 GENERAL 池中借用资源,但在争夺资源时,优先级决定了每个池的请求获得批准的顺序。例如:

=> CREATE RESOURCE POOL dept1_pool PRIORITY 5;
=> CREATE RESOURCE POOL dept2_pool PRIORITY 8;

如果您发现此解决方案不足以满足需要,或者一个部门的查询一直使另一个部门的用户难以执行查询,则可以通过设置 MEMORYSIZE 为每个池添加预留,这样会保证每个部门都可以使用一些内存。

例如,两个资源都使用 GENERAL 池获取内存,所以您可以通过使用 ALTER RESOURCE POOL 更改每个池的 MEMORYSIZE,为每个资源池分配一些内存。

=> ALTER RESOURCE POOL dept1_pool MEMORYSIZE '100M';
=> ALTER RESOURCE POOL dept2_pool MEMORYSIZE '150M';

4.8 - 持续加载和查询

场景

您希望应用程序运行连续加载流,但许多应用程序运行的是并行查询流。您希望确保性能是可预计的。

解决方案

此场景的解决方案取决于您的查询组合。在所有情况下,以下方法均适用:

  1. 确定所需的连续加载流数量。如果单个流没有提供足够的吐吞量,则这可能与所需加载速率有关,或者与要加载的数据源数量有更直接的关系。为加载创建一个专用资源池,并将其与要执行加载的数据库用户相关联。有关详细信息,请参阅CREATE RESOURCE POOL

    通常,加载池的并行设置应少于每个节点的内核数。除非源进程较慢,否则会更高效地为每个加载贡献更多内存,并且具有更多的加载队列。如果预计有队列,请调整加载池的 QUEUETIMEOUT 设置。

  2. 运行加载工作负载一会儿,观察加载性能是否符合预期。如果 Tuple Mover 没有经过充分优化以涵盖加载行为,请参阅管理 Tuple Mover

  3. 如果系统中有多种类型的查询(例如,对于某些查询,必须为交互用户快速提供答复,而其他查询属于批量报告处理的一部分),请遵循处理混合工作负载:批处理与交互式处理中的准则。

  4. 运行查询并观察性能。如果某些类别的查询没有按预期执行,那么您可能需要按照限制临时查询应用程序的资源使用率中所述调整 GENERAL 池,或者为这些查询创建更多专用资源池。有关详细信息,请参阅CEO 查询处理混合工作负载:批处理与交互式处理

有关在混合工作负载环境中获得可预测结果的信息,请参阅关于管理工作负载CREATE RESOURCE POOL的部分。

4.9 - 确定运行时短查询的优先级

场景

您最近为没有 SQL 方面经验并且经常运行临时报表的用户创建了一个资源池。到目前为止,您通过创建 MEMORYSIZE 和 MAXMEMORYSIZE 相等的资源池来管理资源分配。这可以防止该资源池中的查询从 GENERAL 池中借用资源。现在,您希望在运行时管理资源并优先考虑短查询,使其不会因为运行时资源有限而排队。

解决方案

  • 将资源池的 RUNTIMEPRIORITY设置为 MEDIUM 或 LOW。

  • 将资源池的 RUNTIMEPRIORITYTHRESHOLD设置为您希望确保始终以较高优先级运行的查询的持续时间。

例如:

=> ALTER RESOURCE POOL ad_hoc_pool RUNTIMEPRIORITY medium RUNTIMEPRIORITYTHRESHOLD 5;

由于 RUNTIMEPRIORITYTHRESHOLD 设置为 5,因此资源池 ad_hoc_pool 中在 5 秒内完成的所有查询都以高优先级运行。超过 5 秒的查询将下降到分配给该资源池的 RUNTIMEPRIORITYMEDIUM。

4.10 - 删除运行时较长查询的优先级

场景

您希望资源池中的大部分查询以 HIGH 运行时优先级运行,但能够将长于 1 小时的作业调整为更低的优先级。

解决方案

将资源池的 RUNTIMEPRIORITY 设置为 LOW,将 RUNTIMEPRIORITYTHRESHOLD 设置为一个仅截断最长作业的数值。

示例

要确保向所有持续时间长于 3600 秒(1 小时)的查询分配低运行时优先级,请按如下所示修改资源池:

  • 将 RUNTIMEPRIORITY 设置为 LOW。

  • 将 RUNTIMETHRESHOLD 设置为 3600

=> ALTER RESOURCE POOL ad_hoc_pool RUNTIMEPRIORITY low RUNTIMEPRIORITYTHRESHOLD 3600;

5.1 - 将 Vertica 限制为仅占用 60% 的内存

场景

您有一个嵌入 Vertica 的单节点应用程序,部分 RAM 需要专用于该应用程序进程。在此场景中,您想要将 Vertica 限制为仅使用可用 RAM 的 60%。

解决方案

将 GENERAL 池的 MAXMEMORYSIZE 参数设置为所需的内存大小。有关资源限制的讨论,请参阅资源池架构

5.2 - 为恢复进行调整

场景

您有一个大型数据库,其中包含一个具有两个投影以及默认设置的大型表,恢复操作所需的时间过长。您想要为恢复操作提供更多内存以提高速度。

解决方案

将 RECOVERY 池的 PLANNEDCONCURRENCY 和 MAXCONCURRENCY 设为 1,使恢复操作可以从 GENERAL 池中获得尽可能多的内存并且每次仅运行一个线程。

5.3 - 调整刷新

场景

刷新操作正在运行时,系统性能会受到影响,用户查询会被拒绝。您想要降低刷新作业的内存用量。

解决方案

将刷新池的 MEMORYSIZE 设置为固定值。然后,资源管理器调整刷新查询,使其仅使用此数量的内存。

5.4 - 调整 Tuple Mover 池设置

场景 1

在重负载操作期间,您偶尔会注意到 ROS 容器的数量激增。您希望 Tuple Mover 更主动地执行合并以合并 ROS 容器,并避免 ROS 推回。

解决方案

使用 ALTER RESOURCE POOL 增加 TM 资源池 中 MAXCONCURRENCY 的设置。此设置确定有多少线程可用于合并。默认情况下,此参数设置为 7。Vertica 将一半线程分配给处于活动状态的分区,其余一半根据需要分配给处于活动状态和非活动状态的分区。如果 MAXCONCURRENCY 设置为奇整数,Vertica 会向上舍入以支持处于活动状态的分区。

例如,如果您将 MAXCONCURRENCY 增加到 9,则 Vertica 会将五个线程专门分配给处于活动状态的分区,并将剩余的四个线程分配给处于活动状态和非活动状态的分区。

场景 2

您有一个专用于时间敏感型分析查询的辅助子群集。您希望限制此子群集上可能干扰其处理查询的任何其他工作负载,并同时释放内存以执行查询。

默认情况下,每个子群集都有一个用于 Tuple Mover 操作的内置 TM 资源池,该资源池可用于执行 Tuple Mover 合并操作。TM 池消耗可用于查询的内存。此外,合并操作可能会给子群集的处理稍微增加一点开销。您希望重新分配由 TM 池消耗的内存,并阻止子群集运行合并操作。

解决方案

使用 ALTER RESOURCE POOL 覆盖辅助子群集的全局 TM 资源池,并将其 MAXMEMORYSIZE 和 MEMORYSIZE 都设置为 0。这允许您使用由全局 TM 池消耗的内存来运行分析查询,并防止为子群集分配要执行的 TM 合并操作。

5.5 - 为机器学习进行调整

场景

大量机器学习功能正在运行,您希望为它们提供更多内存以提高性能。

解决方案

Vertica 在 BLOBDATA 资源池中执行机器学习功能。为了提高机器学习功能的性能并避免将查询溢出到磁盘,请使用 ALTER RESOURCE POOL 增加池的 MAXMEMORYSIZE 设置。

有关调整查询预算的更多信息,请参阅查询预算

另请参阅

6 - 缩短查询运行时间

查询的运行时间取决于查询的复杂性、计划中的运算符数、数据量和投影设计。I/O 或 CPU 瓶颈可能导致查询运行速度低于预期。您通常可以使用更好的投影设计来纠正 CPU 使用率过高的问题。高 I/O 通常可以追溯到由溢出到磁盘的联接和排序引起的争用。但是,没有单一的解决方案可以解决所有导致高 CPU 或 I/O 使用率的查询。您必须单独分析和优化每个查询。

可通过两种方式评估运行缓慢的查询:

检查查询计划会揭露以下一个或多个问题:

  • 投影排序顺序不理想

  • 对未排序或未编码的列进行谓词评估

  • 使用 GROUPBY HASH 而非 GROUPBY PIPE

分析

Vertica 提供的分析机制可帮助您评估不同级别的数据库性能。例如,可为单个语句、单个会话或所有节点上的所有会话收集分析数据。有关详细信息,请参阅对数据库性能执行分析

7 - 管理 Eon 模式数据库中的工作负载资源

您主要使用子群集来控制 Eon 模式数据库中的工作负载。例如,您可以为特定用例(如 ETL 或查询工作负载)创建子群集,也可以为不同的用户组创建子群集以隔离工作负载。在每个子群集中,您可以创建单独的资源池以根据工作负载优化资源分配。有关 Vertica 如何使用子群集的详细信息,请参阅管理子群集

全局资源池和特定于子群集的资源池

您可以定义影响数据库中所有节点的全局资源池分配。您还可以在子群集级别创建资源池分配。如果您同时创建这两种分配,则子群集级别的设置会覆盖全局设置。

您可以使用此功能移除子群集不需要的全局资源池。此外,您可以使用适合大多数子群集的设置创建资源池,然后根据需要为特定子群集定制设置。

优化 ETL 和查询子群集

覆盖子群集级别的资源池设置将允许您隔离内置和用户定义的资源池并按工作负载优化它们。您通常为不同的子群集分配特定的角色:

  • 专用于 ETL 工作负载和 DDL 语句(这些语句用来更改数据库)的子群集。

  • 专用于运行长时间运行的深入分析查询的子群集。为了获得最佳性能,需要为这些查询分配更多的资源。

  • 用于运行许多短时间运行的“仪表板”查询(您希望快速完成且并行运行这些查询)的子群集。

定义由每个子群集执行的查询类型后,您可以创建一个特定于子群集的资源池,并对该资源池进行优化以提高此工作负载的效率。

以下方案按工作负载优化 3 个子群集:

  • ETL:用于执行 ETL 的子群集,您希望针对 Tuple Mover 操作优化该 ETL。

  • 仪表板:您要为短时间运行的查询指定的子群集,这些查询由大量用户执行,可用于刷新网页。

  • 分析:要为长时间运行的查询指定的子群集。

有关资源池调整的其他方案,请参阅工作负载资源管理最佳实践

配置 ETL 子群集以提高 TM 性能

Vertica 选择在存储库中的合并操作中涉及 ROS 容器最多的子群集来执行合并(请参阅 Eon 模式数据库中的 Tuple Mover)。通常,执行 ETL 的子群集将是执行合并的最佳候选者,因为该子群集加载的数据参与合并。您可以选择通过更改 TM 池的 MAXCONCURRENCY 设置来提高子群集上合并操作的性能,以增加可用于合并操作的线程数。您无法在子群集级别更改此设置,因此您必须在全局设置它:

=> ALTER RESOURCE POOL TM MAXCONCURRENCY 10;

有关 Tuple Mover 资源的更多信息,请参阅调整 Tuple Mover 池设置

配置仪表板查询子群集

默认情况下,辅助子群集将内存分配给 Tuple Mover 资源池。此池设置允许 Vertica 将合并操作分配给辅助子群集,这会增加少量开销。如果您将辅助子群集主要用于查询,则最佳做法是回收 TM 池使用的内存并防止将合并操作分配给辅助子群集。

要优化仪表板查询辅助子群集,请设置其 TM 池的 MEMORYSIZEMAXMEMORYSIZE 设置为 0:

=> ALTER RESOURCE POOL TM FOR SUBCLUSTER dashboard MEMORYSIZE '0%'
   MAXMEMORYSIZE '0%';

若要确认覆盖,请查询 SUBCLUSTER_RESOURCE_POOL_OVERRIDES 表:

=> SELECT pool_oid, name, subcluster_name, memorysize, maxmemorysize
          FROM SUBCLUSTER_RESOURCE_POOL_OVERRIDES;

     pool_oid      | name | subcluster_name | memorysize | maxmemorysize
-------------------+------+-----------------+------------+---------------
 45035996273705046 | tm   | dashboard       | 0%         | 0%
(1 row)

若要针对网页上短时间运行的查询优化仪表板子群集,请创建一个名为 dash_pool 的子群集级资源池,该池使用子群集 70% 的内存。此外,增加 PLANNEDCONCURRENCY 以使用机器的所有逻辑核心,并将 EXECUTIONPARALLELISM 限制为不超过机器可用核心的一半:

=> CREATE RESOURCE POOL dash_pool FOR SUBCLUSTER dashboard
     MEMORYSIZE '70%'
     PLANNEDCONCURRENCY 16
     EXECUTIONPARALLELISM 8;

配置分析查询子群集

若要针对网页上长时间运行的查询优化分析子群集,请创建一个名为 analytics_pool 的子群集级资源池,该池使用子群集 60% 的内存。在这种情况下,您无法为该池分配更多内存,因为该子群集中的节点仍将内存分配给其 TM 池。此外,将 EXECUTIONPARALLELISM 设置为 AUTO 以使用节点上的所有可用核心来处理查询,并将 PLANNEDCONCURRENCY 限制为不超过 8 个并发查询:

=> CREATE RESOURCE POOL analytics_pool FOR SUBCLUSTER analytics
      MEMORYSIZE '60%'
      EXECUTIONPARALLELISM AUTO
      PLANNEDCONCURRENCY 8;